## Is there a generic way to decompose the free comonad over a failure monad into a “values stream and final error”?

The `Cofree`

comonad is useful for iterating partial functions in a way that's polymorphic on the error type. Its `coiter`

resembles `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.

For example, `Cofree Identity`

(no failure permitted!) is an infinite stream, whereas `Cofree Maybe`

is isomorphic to `NonEmpty`

, and `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?

Show source

## Answers ( 1 )

I think it is bad transformation for large streams, because you can have space leak by laziness. But for small streams it maybe usable.

We can divide this transformation on two:

And then combine together: