Cofree
comonad は、エラー型で多態的な方法で部分関数を反復するのに役立ちます。これはエラー モナドでのループに似ていますが、生成された値を純粋/遅延的な方法で収集し、データ構造体の最後にエラーが表示されるだけですcoiter
。forM
たとえば、Cofree Identity
(失敗は許可されません!) は無限ストリームですが、Cofree Maybe
は と同形NonEmpty
であり、Cofree (Either e) a
基本的には(NonEmpty a, e)
(成功した反復値のリストと最後に発生するエラー) です。
ここで、単一のエラーモナドで特定のパターンマッチングを行わずに、結果を評価する最良の方法は何だろうと考えています。インスタンスのおかげですべての値を抽出するのは非常に簡単ですがFoldable
(例: )、エラーtoList
を取得する最善の方法がわかりません。それを悪用して、値を取り除き、エラー部分を残すことができます。Foldable
vals'n'err :: (Monad m, Foldable m)
=> Cofree m a -> (NonEmpty a, (m ()))
vals'n'err (a :< q) = case toList q of
[] -> (a:|[], const () <$> q)
l -> first (pure a<>)
$ foldr1 (\(bs,e) (cs,f) -> (bs<>cs, e>>f)) $ vals'n'err<$>l
しかし、これは少しハックな気がします。より良い解決策はありますか?