Difference between free monads and fixpoints of functors?

后端 未结 2 1006
抹茶落季
抹茶落季 2020-12-23 03:24

I was reading http://www.haskellforall.com/2013/06/from-zero-to-cooperative-threads-in-33.html where an abstract syntax tree is derived as the free monad of a functor repres

2条回答
  •  -上瘾入骨i
    2020-12-23 04:31

    There is a deep and 'simple' connection.

    It's a consequence of adjoint functor theorem, left adjoints preserve initial objects: L 0 ≅ 0.

    Categorically, Free f is a functor from a category to its F-algebras (Free f is left adjoint to a forgetful functor going the other way 'round). Working in Hask our initial algebra is Void

    Free f Void ≅ 0
    

    and the initial algebra in the category of F-algebras is Fix f: Free f Void ≅ Fix f

    import Data.Void
    import Control.Monad.Free
    
    free2fix :: Functor f => Free f Void -> Fix f
    free2fix (Pure void) = absurd void
    free2fix (Free body) = Fix (free2fix <$> body)
    
    fixToFree :: Functor f => Fix f -> Free f Void
    fixToFree (Fix body) = Free (fixToFree <$> body)
    

    Similarly, right adjoints (Cofree f, a functor from Hask to the category of F-coalgebras) preserves final objects: R 1 ≅ 1.

    In Hask this is unit: () and the final object of F-coalgebras is also Fix f (they coincide in Hask) so we get: Cofree f () ≅ Fix f

    import Control.Comonad.Cofree
    
    cofree2fix :: Functor f => Cofree f () -> Fix f
    cofree2fix (() :< body) = Fix (cofree2fix <$> body)
    
    fixToCofree :: Functor f => Fix f -> Cofree f ()
    fixToCofree (Fix body) = () :< (fixToCofree <$> body)
    

    Just look how similar the definitions are!

    newtype Fix f 
      = Fix (f (Fix f))
    

    Fix f is Free f with no variables.

    data Free f a 
      = Pure a 
      | Free (f (Free f a))
    

    Fix f is Cofree f with dummy values.

    data Cofree f a 
      = a <: f (Cofree f a)
    

提交回复
热议问题