[问题] Lazy Evaluation?

楼主: slyfox (klanloss)   2011-11-12 13:30:37
刚刚在练习写 Haskell 时,遇到个小问题,一时不解上来发问。
我想写一个 function 用来读 stdin 直到读到特定的字符
成功版:
getCharUntil :: Char -> IO [Char]
getCharUntil c = do x <- getChar
if x == c then return []
else do xs <- getCharUntil c
return $ x : xs
失败版:
sequenceWhile :: Monad m => (a -> Bool) -> [m a] -> m [a]
sequenceWhile f ms = sequence ms >>= return . takeWhile f
getCharUntil' c = sequenceWhile (/=c) $ repeat getChar
失败版会一直读不停
Lazy evaluation 很耐死的,一定是有什么误会…
感谢
作者: godfat (godfat 真常)   2010-01-13 05:53:00
因为 sequence 吧?
作者: ccshan (善终结)   2010-01-13 14:10:00
失败版的意思是:先读无穷多个字符,再取其开头部份。
楼主: slyfox (klanloss)   2010-01-13 14:34:00
啊! 所以 >>= 是凶手!!想起来 sequence 是用 foldr 实做的了 难怪!
作者: Favonia (00010110110001101010100)   2010-01-13 20:29:00
>>= 应该不会强迫左边算到底,所以应该是无辜的 xD
楼主: slyfox (klanloss)   2010-01-14 06:13:00
那我还是不理解。。。
作者: Favonia (00010110110001101010100)   2010-01-14 06:19:00
我的意思是说只有 >>= 并不妨碍,可能你的理解是正确的 xD
楼主: slyfox (klanloss)   2010-01-14 15:10:00
但在此例 sequence 被 >>= 规定要"算到底"吧?
作者: Favonia (00010110110001101010100)   2010-01-14 21:13:00
>>= 只需要判断左边没有 fail 即可,但 sequence 要如何决定有没有 fail? 只能全部看过一次!只要有个 fail 就会全部 fail. 然后 sequence 为了应付 >>= 也只需要检查有没有fail 就好,不需要“算到底”。除非用 deepseq 之类的东西恶搞否则很难算到底...上面的理解有个作弊的地方,就是我假设 sequenceWhile 要算到至少 Weak head normal form. 实际上得从 main 开始逆推才知道什么是非算不可的...
作者: godfat (godfat 真常)   2010-01-14 23:24:00
请不要推文超过三行...

Links booklink

Contact Us: admin [ a t ] ucptt.com