9

モナドを厳密に折りたたむにはどうすればよいですか? Data.Foldablestrictfoldl'と monadicfoldlMがありますが、 strict はありませんfoldlM'か? 厳密さはモナド自体によって何らかの形で定義されていますか? もしそうなら、それが何であるかをどのように解決しますか?

リング要素の膨大なリストの積がゼロかどうかを判断する必要があると想像してください。ただし、私のリングは整数ドメインではありません。つまり、デバイザが含まれていません。この場合、リストfoldlの乗算を再帰的に追跡する必要がありますが、完全な積を待つのではなく、積がゼロになる瞬間に戻ります。***False

safelist :: [p] -> Bool
safelist [] = True
safelist (x:xs) = snd $ foldl' f (x,True) xs
   where  f (u,b) v = (w, b && w /= Zero)  where  w = u *** v

Maybeモナドを使用してこのコードを少し単純化することもできますfoldlMが、そうすると必要な厳密さが欠けているように見えます。

4

1 に答える 1

11

そのような標準関数はありませんが、定義するのは簡単です:

foldM' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM' _ z [] = return z
foldM' f z (x:xs) = do
  z' <- f z x
  z' `seq` foldM' f z' xs

これは単なる標準ですが、 ( と比較して)foldM同じseqing が含まれています。ほとんどのモナドでは、スタックをオーバーフローさせずに左折を使用する必要があるという意味で「厳密」です。これは、過剰なサンクが戻り値自体に含まれている場合にのみ役立ちますが、 の便利なアプリケーションは、最後のステップの値を使用してモナド計算を実行するため、その可能性は低くなります。foldl'foldl(>>=)foldM

あなたのコードはそのままで十分に単純だと思います。foldM'これ以上エレガントになるとは思えません。

于 2012-01-18T23:32:33.690 に答える