Почему функция последовательности Haskell не может быть ленивой или почему рекурсивные монадические функции не могут быть ленивыми

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

Пытаться

sequence $ map return [1..]::[[Int]]
sequence $ map return [1..]::Maybe [Int]

и ghci попадет в бесконечный расчет.

Если переписать функцию последовательности в более читабельном виде, как показано ниже:

sequence' []     = return []
sequence' (m:ms) = do {x<-m; xs<-sequence' ms; return (x:xs)}

и попробовать:

sequence' $ map return [1..]::[[Int]]
sequence' $ map return [1..]::Maybe [Int]

мы получаем ту же ситуацию, бесконечный цикл.

Попробуйте ограниченный список

sequence' $ map return [1..]::Maybe [Int]

это даст ожидаемый результатJust [1,2,3,4..] после долгого ожидания.

Из того, что мы попробовали, мы можем прийти к выводу, что хотя определение последовательности «кажется ленивым, оно строгое и должно разбирать все числа, прежде чем результат последовательности» может быть напечатан.

Не только последовательность », если мы определим функцию

iterateM:: Monad m => (a -> m a) -> a -> m [a]
iterateM f x = (f x) >>= iterateM0 f >>= return.(x:)

и попробовать

iterateM (>>=(+1)) 0

тогда происходит бесконечный расчет.

Как мы все знаем, немонадная итерация определяется так же, как и вышеупомянутый iterateM, но почему итерация ленива, а iterateM строг. Как видно из вышеизложенного, iterateM и sequence 'являются рекурсивными монадическими функциями. Есть ли что-то странное в рекурсивных монадических функциях?

Ответы на вопрос(3)

Ваш ответ на вопрос