作者slyfox (klanloss)
看板PLT
标题[问题] Lazy Evaluation?
时间Sat Nov 12 13:30:37 2011
刚刚在练习写 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 很耐死的,一定是有什麽误会…
感谢
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 71.202.208.114
1F:推 godfat:因为 sequence 吧? 11/13 05:53
2F:推 ccshan:失败版的意思是:先读无穷多个字元,再取其开头部份。 11/13 14:10
3F:→ slyfox:啊! 所以 >>= 是凶手!! 11/13 14:34
4F:→ slyfox:想起来 sequence 是用 foldr 实做的了 难怪! 11/13 14:36
5F:推 Favonia:>>= 应该不会强迫左边算到底,所以应该是无辜的 xD 11/13 20:29
6F:→ slyfox:那我还是不理解。。。 11/14 06:13
7F:推 Favonia:我的意思是说只有 >>= 并不妨碍,可能你的理解是正确的 xD 11/14 06:19
8F:→ slyfox:但在此例 sequence 被 >>= 规定要"算到底"吧? 11/14 15:10
9F:推 Favonia:>>= 只需要判断左边没有 fail 即可,但 sequence 要如何决 11/14 21:13
10F:→ Favonia:定有没有 fail? 只能全部看过一次!只要有个 fail 就会全 11/14 21:15
11F:→ Favonia:部 fail. 然後 sequence 为了应付 >>= 也只需要检查有没有 11/14 21:16
12F:→ Favonia:fail 就好,不需要「算到底」。除非用 deepseq 之类的东西 11/14 21:17
13F:→ Favonia:恶搞否则很难算到底... 11/14 21:17
14F:→ Favonia:上面的理解有个作弊的地方,就是我假设 sequenceWhile 要 11/14 21:19
15F:→ Favonia:算到至少 Weak head normal form. 实际上得从 main 开始 11/14 21:19
16F:→ Favonia:逆推才知道什麽是非算不可的... 11/14 21:19
17F:→ godfat:请不要推文超过三行... 11/14 23:24