1 名前:デフォルトの名無しさん [04/02/10 22:16] Haskellの公式HP www.haskell.org/ 日本語サイト www.sampou.org/cgi-bin/haskell.cgi www.teu.ac.jp/kougi/koshida/Prog6/index.html 過去ログ、関連スレは>>2-5
255 名前:デフォルトの名無しさん mailto:sage [04/10/16 05:13:41] >>251 まず、mainだけ特殊な評価をうけるとは考えないことにします。 右から評価されると無限ループも書けないというのは、 main = loop where loop = act >> loop act = print "x" ここでloopの右辺を先に評価したらact >> (act >> (act >> ..))と ネストした列ができるだけでloopの処理が進まないという意味です。 末尾再帰も同様のことになります。 先に述べたように、特殊な評価装置や特殊ルールは考えないので、これは、 (>>)がそういう順序に評価を導くように定義されているということを意味します。 単にmainそのものを評価しても、(\_ -> ...)の形か、 (コンストラクタ) ...の形になって...の部分は評価されずに終わります。 これでは...の中に書いてあるIOアクションの列をどう評価、 実行していけばいいかはわかりません。 そこで、mainは関数であって(type IO a = World -> (a, World)、 プログラムの実行とはmain worldを評価する、つまりmain worldの 返り値を求める評価を行うことだと考えることにします。 例えば(putStr "X") worldを評価すると、 "X"が出力されたWorldを返します("X"が出力される)。
256 名前:デフォルトの名無しさん mailto:sage [04/10/16 05:15:13] これは、普通の評価なので、main worldの返り値(a, world)が求まれば いいので、まず返り値に必要な部分から計算されます。 したがって、遅延評価ならば、a >> bにおいてworldに最後に関与する 「外側」にある"b"のほうから評価が行われるはずだということになります。 これが「右から(Lazyに)」の意味です。 ちろんこれではループも書けないのでIOモナドとしては使えません。 しかし、WorldについてStrictなモナドだとすれば、 左から評価されるようになります。 -- typeではモナドの定義がHaskell98では書けない。 newtype IO a = IO { runIO :: World -> (a, World) } instance Monad IO where ioact >>= f = IO $ \world -> world `seq` let (a, world') = runIO ioact world in runIO (f a) $! world' もしよくわからなければ、Control.Monad.Stateのlazyなstateモナドで loopや末尾再帰のプログラムを書いて挙動を観察してみてください。