Один из способов описать свободную монаду - сказать, что это начальный моноид в категории эндофункторов (некоторой категории C
), объекты которых являются эндофункторами от C
до C
, стрелки - это естественные преобразования между ними. . Если мы возьмем C
за Hask
, то эндофунктор - это то, что называется Functor
в haskell, которое является функтором от * -> *
, где *
представляет объекты Hask
По умолчанию любая карта из эндофунктора t
в моноид m
в End(Hask)
индуцирует карту из Free t
в m
.
Иначе говоря, любое естественное преобразование из функтора t
в монаду m
вызывает естественное преобразование из Free t
в m
Я ожидал, что смогу написать функцию
free :: (Functor t, Monad m) => (∀ a. t a → m a) → (∀ a. Free t a → m a)
free f (Pure a) = return a
free f (Free (tfta :: t (Free t a))) =
f (fmap (free f) tfta)
но это не может быть унифицировано, тогда как следующие работы
free :: (Functor t, Monad m) => (t (m a) → m a) → (Free t a → m a)
free f (Pure a) = return a
free f (Free (tfta :: t (Free t a))) =
f (fmap (free f) tfta)
или его обобщение с подписью
free :: (Functor t, Monad m) => (∀ a. t a → a) → (∀ a. Free t a → m a)
Я ошибся в теории категорий или в переводе на Haskell?
Мне было бы интересно услышать здесь немного мудрости ..
PS: код с включенным
{-# LANGUAGE RankNTypes, UnicodeSyntax #-}
import Control.Monad.Free