--------------------------------------------------------------------------------
--                                                                            --
--  Rec is used to define recursive types                                     --
--                                                                            --
--  Algebra is used to define recursive functions (via fold)                  --
--                                                                            --
--------------------------------------------------------------------------------

-- Rec class

class Rec rec where
  rec :: f (rec f) -> rec f
  cer :: rec f -> f (rec f)

-- Algebra class

class Functor f => Algebra f a where
  phi :: f a -> a

-- fold
  
fold :: (Rec rec,  Algebra f a) => rec f -> a 
fold = phi . map fold . cer 

-- REC data 

data REC f = REC (f (REC f))

instance Rec REC where
  rec x = (REC x)
  cer (REC x) = x

--------------------------------------------------------------------------------




  
  
