Почему Ничего >> Только 3 - Ничто в Хаскеле?

Подпись >> Функция в Haskell заключается в следующем:

(>>) :: m a -> m b -> m b

И реализация по умолчанию:

x >> y = x >>= \_ -> y

Под этим я понимаю, что >> Функция всегда возвращает свой правый параметр независимо от значения левого. Лямбда даже не заботится о значении левого параметра (x). Тогда почему Nothing >> Just 3 равно Nothing? Разве это не должно просто вернуться Just 3, так как это значение аргумента справа?

Я знаю что нибудь Just значение, вернется Nothingкогда связано с Nothing, но в этом случае Nothing даже не захвачен лямбдой. Что мне не хватает?

Бонусный вопрос, >>= называется связать. Что такое >> называется?

Благодарю.

5 ответов

Решение

Потому что привязка даже не заботится о значении лямбды!

Just x  >>= f = f x
Nothing >>= _ = Nothing

Обратите внимание (Nothing >>=) не оценивает свой второй аргумент.

Чтобы действительно понять, что (>>) В этом случае вы должны посмотреть на определение (>>=) за Maybe:

(Just x) >>= k      = k x
Nothing  >>= _      = Nothing

Nothing >>= k оценивает Nothing независимо от того, что k функция есть. В конкретном случае (>>), k просто бывает \_ -> y,

Под этим я понимаю, что функция >> всегда возвращает свой правый параметр независимо от значения левого

Это источник вашего замешательства!

m >>= f Запускает f для значений он "находит внутри" m, "объединение" результатов (где то, что означает "находить внутри" монадическое значение и что означает "объединять", зависит от монады).

m >> n должен быть эквивалентен m >>= \_ -> n, Так что для каждого значения он находит внутри m, это вызовет \_ -> n в теме. Но Nothing в Maybe Монада не имеет никаких значений "внутри". Так \_ -> n никогда не может быть призван на что-либо, чтобы проигнорировать это и вернуться n! Так Nothing >>= \_ -> n должен вернуть то, что не зависит от n, так как он не имеет возможности вызвать функцию для получения n, Также в этом контексте нет никаких значений обернутого типа, поэтому единственная доступная опция - это просто Nothing,

Так что вместо вашей интуиции для понимания >> поскольку он игнорирует левое и возвращает то, что справа, лучше думать, что он берет "монадическую структуру" того, что слева, и связывает ее с монадическим значением справа. "Монадическая структура" - это волнообразный термин для "всего, что определяет монадическое значение, кроме значений внутри него".

listA >> listB делает то же самое, независимо от конкретных значений в listA, но это имеет значение, сколько элементов в нем. ioA >> ioB делает то же самое, независимо от того, какое значение производится путем выполнения ioA, но это имеет значение, побочные эффекты были сделаны, чтобы произвести это. stateA >> stateB игнорирует значение, произведенное stateA, но отправляет текущее состояние stateB, А также maybeA >> maybeB делает то же самое, независимо от конкретного значения внутри maybeA, но это имеет значение, есть ли ценность или нет. Обратите внимание, что регистр ведет себя очень похоже на Maybe; если listA тогда пусто listA >> listB тоже должен быть пустым.

Что касается вашего бонусного вопроса, когда я читаю код для себя (в своей голове), я склонен произносить оба >>= а также >> как "связать"; когда я смотрю на код и произношу его, достаточно невербального понимания контекста, чтобы эта двусмысленность не имела значения. Я на самом деле не знаю, что бы я сказал, чтобы поговорить с кем-то о >>= а также >>; может быть "связать" и "забыть связать"?

Я думаю, что есть два способа объяснить выбор.

  1. вы апеллируете к тому факту, что Maybe, в отличие от IO, например, не имеет побочных эффектов. В противном случае отказ от второго аргумента не имеет смысла. С этой точки зрения, это выглядит как произвольный выбор с логической точки зрения, хотя, безусловно, он более эффективен, если не является неожиданным.

  2. Вы заставляете Ничто не представлять ошибку. Тогда ошибка в первом аргументе избавит от необходимости оценивать второй аргумент. Похоже, это обоснование, выбранное авторами:

http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Data-Maybe.html

-- The 'Maybe' type is also a monad.  It is a simple kind of error
-- monad, where all errors are represented by 'Nothing'.

Есть несколько вещей, которые я хотел бы добавить к другим хорошим ответам.

  1. Причина Nothing >>= f должен быть Nothing потому что невозможно проверить, f фактически использует его аргумент (по крайней мере, без ужасных небезопасных хаков).

  2. x >> y = x >>= \_ -> y это не просто реализация по умолчанию. Определение >> должен всегда давать тот же результат, что и этот. Его можно перегрузить только потому, что иногда его можно реализовать более эффективно.

Другие вопросы по тегам