Is there a generic way to decompose the free comonad over a failure monad into a “values stream and final error”?
Cofree comonad is useful for iterating partial functions in a way that's polymorphic on the error type. Its
forM-looping in an error monad, but it gathers the produced values in a pure/lazy manner and you only see an error at the end, down in the data struct.
Cofree Identity (no failure permitted!) is an infinite stream, whereas
Cofree Maybe is isomorphic to
Cofree (Either e) a is basically
(NonEmpty a, e) (list of successfull-iteration values plus an error that occurs at the end).
Now I wonder what's the best way to evaluate the results, without specific pattern-matching on a single error monad. Extracting all the values is very easy thanks to the
Foldable instance (e.g.
toList), but I'm not sure how to best get hold of the errors. It would be possible to exploit
Foldable for that to just get rid of the values and leave the error part:
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
but this feels a bit hackish. Is there a better solution?