なんですが、Haskell は PrtStrLn とかを任意のところに挟むわけにはいきません。こいつは IO Monad なので。 例えば
fact1 0 = return 1
fact1 n = do
putStrLn (show n)
c <- fact1 (n -1)
return ( n * c )
とかは、問題なく動くんだけど、自作の Monad をはさむと、
fact4 0 = return 1
fact4 n = do
putStrLn (show n)
c <- fact2 (n -1)
Tn [c] ( n * c )
これは型エラー。これは Monad T1 を返す関数なんだけど、 putStrLn (show n) は IO を返すので、それが衝突してしまう。
mylift m =
Tn [] ( do
c <- m
putStrLn (show c)
return c
)
fact2 0 = return 1
fact2 n = do
mylift $ putStrLn (show n)
c <- fact2 (n -1)
Tn [c] ( n * c )
とすると、mylift が IO a -> T1 なので、型は合います。合いますが、IO Monad を誰も触ってくれないので印字してくれません。これは誰も見ない printf だから消されてしまったみたいなものだな。
つまり、IO Monad と T1 Monad が合成できれば良いわけね。調べてみると、
http://www.slideshare.net/tanakh/monad-tutorial
http://d.hatena.ne.jp/m-hiyama/20070507/1178496486
全然自明ではないらしい。Haskell 内蔵の Error とか Maybe とかには、ErrorIO とか MaybeIO とかあるらしい。
自作 Monad 用には、MonadIO とか MonadTrans とかあるらしいのだけど、
* 使い方がまったくわかりません
うううう。困ったものだ。Haskell library の source を見てみるのだが、どうにもこうにも。困ったものだ。まぁ、時間が解決するとは思いますが。
No comments:
Post a Comment