Чтобы завершить ответ Сиби, >>
можно увидеть как ;
на других языках, таких как C или C++..
Когда вы делаете это на C (или эквиваленте на другом языке)
printf("фу"); printf("бар");
Очевидно, вы печатаете foobar
(побочный эффект), но эти вызовы printf
также имеют возвращаемое значение, которое в нашем случае представляет собой печатаемую длину, т.е. 3 3. Вы когда-нибудь задумывались, что происходит с этими числами? Их выбрасывают, потому что в C expr 1; выражение 2 означает
- оценить expr1
- отказаться от результата
- оценить expr2
(В этот момент вы могли бы спросить себя, почему компилятор должен беспокоиться об оценке expr1, если он должен отбросить его результат? Из-за побочного эффекта. В случае printf
побочным эффектом является печать чего-либо. Вы редко интересуются самим возвращаемым значением.)
Таким образом, ;
можно рассматривать как оператор, принимающий 2 выражения и возвращающий новое. Это точно так же, как и оператор >>
.
Когда вы пишете
print "foo" >> print "bar"
он точно эквивалентен printf("foo");printf("bar")
, за исключением того, что (и это главное отличие) >>
не является чем-то волшебным, как ;
в C. >>
это определяемый пользователем оператор, и его можно переопределить для каждого типа монады. Вот почему программисты на Haskell так любят Monad: короче говоря, она позволяет вам переопределить собственное поведение ;
.
Как мы видели, в C ;
просто оценивается выражение и отбрасывается его значение. На самом деле, это немного сложнее, потому что это не так, если это break
или return
. Ничто в монаде Возможно можно рассматривать как break
или return
. >>
оценивает первое выражение и останавливается, если оно Nothing
. В противном случае он отбрасывает свое значение и продолжает работу.
Ваш первый пример можно увидеть в C
(я думаю, что это правильно C)
3; return
и
return; 3
В первом примере вычисляется 3
, отбрасывается его значение и выполняется возврат. Второй возвращается сразу.
Чтобы ответить на ваш вопрос when is it usefull
? Почти все время, когда вы используете IO, даже если вы редко его видите.
Вместо того, чтобы писать
print "foo" >> print "bar"
Haskell предоставляет синтаксический сахар, который преобразует (почти) символы новой строки в >>
с помощью do-нотации, так что вы напишите
do
print "foo"
print "bar"
что строго эквивалентно предыдущей версии (это факт, что версия нотации преобразуется компилятором в предыдущую).
Это даже эквивалентно (хотя и редко используется)
do print "foo"; print "bar"
Подводя итог, >>
можно рассматривать как эквивалент ;
или новой строки в других языках с той разницей, что ее точное значение зависит от контекста (на который действует монада). >>
в монаде Maybe отличается от >>
в IO-монаде.
person
mb14
schedule
20.07.2014