4

I'm trying to figure out the difference between unfold/coiter from Control.Comonad.Cofree and unfold/ana from Data.Control.Fixedpoint. Hackage libraries are resp. free and recursion-schemes.

Cofree and Fix seem to be cousins, and I'm trying to figure out what is possible with both and what is possible with only one of them.

I could write an instance of Foldable for Cofree so I can apply cata to a free monad obtained from unfold/coiter:

type instance Base (Cofree f a) = f

instance Functor f => Foldable (Cofree f a) where
    project = unwrap

But I couldn't construct an Unfoldable instance:

instance Functor f => Unfoldable (Cofree f a) where
    embed = xembed

xembed :: Functor f => f (Cofree f a) -> Cofree f a 
xembed = undefined

Is it possible at all?

nponeccop
  • 13,141
  • 1
  • 39
  • 101

1 Answers1

4

No, you can't write this function for Cofree in general. Consider f ~ Proxy (where data Proxy a = Proxy):

xembed :: Proxy (Cofree Proxy a) -> Cofree Proxy a
-- i.e.
xembed :: () -> a

Has to get an a out of nowhere.

However, you can write xembed for Free: wrap :: f (Free f a) -> Free f a. And similarly you can't write xproject :: Free f a -> f (Free f a) in general.

shachaf
  • 8,710
  • 1
  • 29
  • 51
  • Do you mean I can't write `project` for free monads, and `embed` for free comonads? – nponeccop Aug 31 '13 at 10:37
  • 1
    Yes, I fixed that (it's a cofree comonad, not a free comonad! :-) ). However, now that I looked at what these classes actually are, maybe your `Base` type is just not what you want (I'm not quite sure what you're after there). `Cofree f a` is the fixed point of `\self -> (a,f self)` and `Free f a` is the fixed point of `\self -> Either a (f self)`, not just of `f`. – shachaf Aug 31 '13 at 15:05