2

したがって、基本的に、再帰の終了ケースとしてMaybeT使用したい にラップされたモナド関数がありますNothing

私の理解でfoldrは、リスト全体を消費せずに結果を生成できる場合、無限リストで安全に使用できます。つまりfoldr (&&) True $ repeat False、 を返すことができFalseます。

現時点で私は持っています:

repeaterM a f = foldr (=<<) (return a) $ repeat f

このタイプはチェックしますが、実際には機能しません。この関数を使用して、返されるまで関数を独自の結果に繰り返し適用できない理由を誰かに説明してもらえますNothingか?

4

1 に答える 1

4
foldr            :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
          where
            go []     = z
            go (y:ys) = y `k` go ys

そう

foldr (&&) True $ repeat False
   = go (repeat False) where go [] = True ; go (y:ys) = y && go ys
   = False && go (repeat False) where go [] = True ; go (y:ys) = y && go ys
   = False

あなたが期待するように。

しかし

foldr (=<<) (return a) $ repeat f
   = go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
   = f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
   = f =<< f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
   = f =<< f =<< f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
   ...

ここで行っているのは、返されるまで、関数をそれ自身の結果に繰り返し適用することではありませんNothing

計算を最後から構築しています=<<。LHS を実行する前に、それぞれの RHS を計算する必要があります。しかし、あなたは無限リストを持っているので、計算の最初に到達することはありません.

あなたは定義しようとするかもしれません

repeaterM a f = foldl (>>=) (return a) $ repeat f

代わりは。これもうまくいきません (is7s に感謝します)。

于 2012-06-27T02:35:41.547 に答える