自由Monad的一种描述方法是说它是一个初始的单子(initial monoid),在某个范畴
通过初始性,从自函子
换句话说,从一个Functor
我本来希望能够编写一个函数...
但这种方法无法统一,而以下方法可以实现。
C
的自函子(endofunctors)范畴中,对象是从C
到C
的自函子,箭头是它们之间的自然变换。如果我们取C
为Hask
,那么自函子就是Haskell中被称为Functor的东西,它们是从* -> *
到Hask
的functor,其中*
表示Hask
的对象。通过初始性,从自函子
t
到End(Hask)中的单子m
的任何映射都会诱导出从Free t
到m
的映射。换句话说,从一个Functor
t
到一个Monad 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
free
是指Free
递归原理中的free
:free f = fold (join . f) return
,其中fold :: Functor f => (f b -> b) -> (a -> b) -> Free f a -> b
。相比之下,使用>>=
的foldFree
库不需要Functor
约束,因为Haskell中的Free
数据类型对于所有的f :: * -> *
参数都是有效的,我们可以直接在该结构上进行计算(尽管具有非函子f
的Free f a
并不是很有用)。 - András Kovács