うーん、8 時間悩んだあげく Monad はなんとなくわかってきた。 ようするに「次の世界ジェネレータ」みたいなもんか。 Y コンビネータをやっておいたのがよかったな。 あれの連想でなんとなくわかる。 あっちは関数を連続生成してたのに対して、 こっちはプログラム実行環境を連続生成してるわけだ。
ただ、現実的にそれを外す方法がわかんないんだよー! IO から読むと全部「IO x」の型になってるから、 普通の関数が全く適用できない。なんとか IO を外したいんだけどなあ。
ででででで、できたーーー! 12 時間もかかってしまった……。
http://i.loveruby.net/ja/haskell/tail.hs
module Main where import System import IO main :: IO () main = do args <- getArgs case args of [] -> doTailFile stdin args -> mapM_ (\a -> do f <- openFile a ReadMode doTailFile f hClose f) args doTailFile :: Handle -> IO () doTailFile f = do all <- hGetContents f rows <- return (lines all) mapM_ (\line -> putStrLn line) (tailFile rows (replicate 10 "")) tailFile :: [String] -> [String] -> [String] tailFile [] buf = buf tailFile (x:xs) buf = tailFile xs (concat [(tail buf),[x]])
10 行以下のファイルを tail すると空行で埋められちゃうんだけど、 そこは勘弁してくだせい。あいかわらず端末が stdin だとうまく動かない。
さ、これでスッキリしたから朝ごはん食べて、 今度こそ fileutils と setup.rb をいじるかな。
14 時だけどね。
あ、ちなみにさっきの「IO が付くからどーたらこーたら」ってのは 勘違いですね。do と <- を使って束縛すればあとは普通に処理できるみたい。
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
(???) IO ??????????????????????????
すいません、失敗しました。
たぶん IO は外せません。外せたら実行順序が保てなくなるはずです。
ああ、やっぱりそうなんですね。なんか変だなーとは思ったんですが。
しかし、一回 IO が付いたら二度と外れないってことは、
ずーっとひきずってまわらないといけないのか。
一度でもこの世ならぬものを覗いたらずっとそれをひきずるのが
掟なのだ。だが、とっておきの呪文をさずけよう。
unsafePerformIO :: IO a -> a
ただし、これをつかったことを純粋Functioalistに知られてはならぬ。もし、知られてしまったら。。。あなおそろしや
ghc --make tail.lhs -o hstail
とかして、コンパイルしてバイナリ hstail をつくれば、標準入力もうまく動作するかも。
runhugsではうまく動作しませんねぇ。知らんかった。^^;