Haskell: 'do [1,2,3]; ["привет"]'разъяснение поведения
Поэтому я пытаюсь понять, как именно Хаскель do
нотация работает. Я понимаю, что он используется вместе с монадами и что он в основном расширяется (так как на самом деле это синтаксический сахар) в анонимные функции, связанные с любой связью (>>=
) или потом (>>
), как показано здесь https://en.wikibooks.org/wiki/Haskell/Syntactic_sugar.
Однако мой вопрос, почему следующая команда
Prelude> do [1, 2, 3]; "hello"
возвращается
"hellohellohello"
Я знаю, что массивы на самом деле являются монадами (а строки - массивами символов), но я не вижу, как это приводит к описанному выше поведению.
2 ответа
do [1, 2, 3]; "hello"
Desugars для
[1, 2, 3] >> "hello"
который так же, как
[1, 2, 3] >>= (\_ -> "hello")
который так же, как
concatMap (\_ -> "hello") [1, 2, 3]
который так же, как
concat (map (\_ -> "hello") [1, 2, 3])
который так же, как
concat [(\_ -> "hello") 1, (\_ -> "hello") 2, (\_ -> "hello") 3])
который так же, как
concat ["hello","hello","hello"]
который так же, как
"hellohellohello"
Чтобы дополнить ответ Иоахима Брейтнера, рассмотрим это с другой стороны:
do [1, 2, 3]
"hello"
является
do a <- [1, 2, 3]
b <- "hello"
return b
является
do a <- [1, 2, 3]
do b <- "hello"
do return b
является
[b | a <- [1,2,3], b <- "hello"]
такой же, как псевдокод
for a in (a list of Nums) [1, 2, 3]:
-- here we have `a` (a Num)
for b in (a list of Chars) "hello":
-- here we have that same `a` (a Num),
-- and `b` (which is a Char)
emit b -- whatever "emit" means
Конечно, списочные выражения для списков (не "массивов") вещей (какими бы они ни были, скажем, Nums, Chars и т. Д.) Десугаром в одно и то же concatMap
- используя код; но иногда легче обрабатывать их мысленно, как есть, или как спецификацию для некоторых вложенных циклов.
На самом деле кажется, что do
примечание могло бы быть легко for
-отношения в первую очередь.