7

次の Haskell の関数の例quuxと、継続モナド および の定義を考えてみましょうcallCC

instance Monad (Cont r) where
    return x = cont ($ x)
    s >>= f  = cont $ \c -> runCont s $ \x -> runCont (f x) c

callCC :: ((a -> Cont r b) -> Cont r a) -> Cont r a
callCC f = cont $ \h -> runCont (f (\a -> cont $ \_ -> h a)) h

quux :: Cont r Int
quux = callCC $ \k -> do
    let n = 5
    k n
    return 25

私がこの例を理解しているように。do ブロックは次のように考えることができます。

k n >>= \_ -> return 25 == 
cont $ \c -> runCont (k n) $ \x -> runCont ((\_ -> return 25) x) c

kそして、 whichの定義から\a -> cont $ \_ -> h a、上記では\x -> runCont ((\_ -> return 25) x) c、アンダースコアで無視される引数に渡されていることがわかります。アンダースコア引数は決して使用されないため、最終的にreturn 25は事実上「無視」されます。そのため、遅延評価から評価されることはありません。

callCCしたがって、この実装は基本的に遅延評価に強く依存していると言えます。callCC厳密な (非遅延) 関数型言語でこれを行うにはどうすればよいでしょうか?

4

1 に答える 1