Почему нет << в стандартной библиотеке Haskell?

Класс Monad определяет метод >>, который последовательно выполняет два монадических действия:

>> :: Monad m => m a -> m b -> m b

Оператор привязки >>= имеет эквивалент с переворотом аргумента, =<<; как и команды монадической функции ( "рыбы" ) >=> и <=<. Кажется, что нет <<, хотя (через несколько минут Hoogling). Почему это?

Изменить: я знаю, что это неважно. Мне просто нравится, как некоторые строки кода выглядят с помощью указателей слева. x <- doSomething =<< doSomethingElse просто выглядит лучше, при этом все стрелки идут одинаково, чем x <- doSomethingElse >>= doSomething.

Ответ 1

Насколько мне известно, нет веской причины. Обратите внимание, что ваш Monad также должен быть экземпляром Applicative, поэтому вы можете использовать <* и *> вместо этого в качестве инструментов последовательности.

Ответ 2

Здесь альтернативный ответ, так как аналогичный вопрос был недавно задан и отмечен как дубликат. Оказывается, совсем не ясно, каким должно быть определение (<<) ! Хотя эта проблема упоминалась в комментариях к более раннему ответу, я не думаю, что она была полностью прояснена, что здесь есть существенная проблема.

Очевидно, две разумные возможности для определения:

(<<) :: Monad m => m a -> m b -> m a
p << q = do {x <- p; q; return x}   -- definition #1
p << q = do {q; p}                  -- definition #2

По аналогии с аппликативными операторами (<*) и (*>) ясно, что оператор new (<<) должен сохранять порядок побочных эффектов слева направо и иметь только эффект переключения, какое действие возвращает возвращаемое значение Таким образом, определение № 1, очевидно, является правильным. Это имеет желаемое свойство, что << и <* будут синонимичны для (с хорошим поведением) монад, так же как >> и *> являются синонимами, так что никаких сюрпризов.

Конечно, по аналогии с =<< и >>= ясно, что переключение направления знаков больше, чем должно, приводит к переключению аргументов, поэтому определение № 2, очевидно, является правильным. Это имеет желаемое свойство, что конвейер монадических операций:

u >>= v >>= w >> x >>= y

можно поменять местами с помощью операторов:

y =<< x << w =<< v =<< u

Это также сохраняет тождества для операторов Клейсли:

(f >=> g) x  ===  f x >>= g
(f <=< g) x  ===  f =<< g x

которые, конечно, выглядят так, как будто они должны держать.

Во всяком случае, я не знаю, если это было первоначальная причина (<<) была опущена. (Вероятно, нет, так как это решение предшествовало бы введению аппликативных операторов, поэтому люди приняли бы "определение № 2" как единственную возможность), но я почти уверен, что сейчас это станет камнем преткновения, поскольку другое поведение of (<<) и (<*) были бы довольно неожиданными, учитывая тесную связь, которую люди ожидают между аппликативными и монадными операциями.