У меня есть небольшая загадка, мне интересно, не могли бы вы помочь мне прояснить.
Давайте определим функцию, которая возвращает список:
let f = replicate 3
Мы хотим сопоставить эту функцию с бесконечным списком, объединить результаты и затем взять только те вещи, которые соответствуют предикату.
takeWhile (< 3) $ concatMap f [1..]
Отлично! Это возвращает [1,1,1,2,2,2]
, что я и хочу.
Теперь я хочу сделать что-то подобное, но функция f теперь оборачивает свои результаты в монаду. В моем случае это монада ввода-вывода, но она подходит для обсуждения моей проблемы:
let f' x = Just $ replicate 3 x
Для сопоставления и сопоставления я могу использовать:
fmap concat $ mapM f' [1..5]
Возвращает: Just [1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
Если я хочу использовать takeWhile
, это все еще работает:
fmap (takeWhile (< 3) . concat) $ mapM f' [1..5]
Что возвращает: Просто [1,1,1,2,2,2]. Отлично!
Но, если я составлю список, по которому я сопоставлю бесконечный список, это не сделает то, что я ожидал:
fmap (takeWhile (< 3) . concat) $ mapM f' [1..]
Похоже, что takeWhile
никогда не происходит. Так или иначе, я не получаю ленивый расчет, который я ожидал. Я немного растерялся.