Created
May 2, 2012 09:10
-
-
Save kei-q/2575411 to your computer and use it in GitHub Desktop.
foldl (\io_x _ -> do {x <- io_x; putStrLn x; io_x}) (return "go") [1,2,3] でputStrLnが7回実行されるわけ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| twitterにあったワンライナーを展開すると以下のようになる | |
| > f = foldl io (return "go") [1,2,3] | |
| > io io_x _ = do | |
| > x <- io_x | |
| > putStrLn x | |
| > io_x | |
| foldlの定義は以下の通り | |
| > foldl f z [] = z | |
| > foldl f z (x:xs) = let z' = f z x | |
| > in foldl f z' xs | |
| これを踏まえると、上記のコードは以下のように展開できる | |
| foldl io (return "go") [1, 2, 3] | |
| foldl io (io (return "go")) [2, 3] | |
| foldl io (io (io (return "go"))) [3] | |
| foldl io (io (io (io (return "go")))) [] | |
| io (io (io (return "go"))) | |
| ioはあくまでIO処理をする設計書で、ただちに処理が実行されるわけでないことに注意 | |
| 地道に展開してみると以下のようになる。 | |
| io' = io (return "go") | |
| io'' = io io' | |
| io''' = io io'' | |
| io' = do | |
| x <- return "go" | |
| putStrLn x | |
| return "go" | |
| io'' = do | |
| x <- do | |
| x' <- return "go" | |
| putStrLn x' | |
| return "go" | |
| putStrLn x | |
| do | |
| x' <- return "go" | |
| putStrLn x' | |
| return "go" | |
| io''' = | |
| x <- do | |
| x' <- do | |
| x'' <- return "go" | |
| putStrLn x'' | |
| return "go" | |
| putStrLn x' | |
| do | |
| x'' <- return "go" | |
| putStrLn x'' | |
| return "go" | |
| putStrLn x' | |
| do | |
| x' <- do | |
| x'' <- return "go" | |
| putStrLn x'' | |
| return "go" | |
| putStrLn x' | |
| do | |
| x'' <- return "go" | |
| putStrLn x'' | |
| return "go" | |
| このように、io内でio_xを参照しているところが二箇所あり、そのなかにIO処理が展開されていく。 | |
| 最後にfoldlの展開が終わり、io'''の処理が実行されるため、putStrLnが7(1+2+4)回実行される。 | |
| このことを踏まえると、もしlistの長さを3から4にしたら15(1+2+4+8)回putStrLnが実行されることも理解できる。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment