免费的monad和免费的操作
描述自由单体的一种方式是说它是内功能体(属于某种类别C
)类别中的一个初始幺半群,其对象是从C
到C
的末端执行体,箭头是它们之间的自然变换。 如果我们把C
作为Hask
,endofunctor就是Haskell中所谓的Functor
,它是来自* -> *
函子,其中*
表示Hask
的对象
按照初始性,从endofunctor t
到End(Hask)
的monoid m
任何映射End(Hask)
引发一个从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
Haskell翻译似乎是错误的。 一个很大的提示是你的free
实现不会在任何地方使用monadic绑定(或连接)。 你可以找到free
foldFree
与以下定义:
free :: Monad m => (forall x. t x -> m x) -> (forall a. Free t a -> m a)
free f (Pure a) = return a
free f (Free fs) = f fs >>= free f
关键的一点是f
专攻t (Free ta) -> m (Free ta)
,从而一举消除一个Free
层。
我不知道类别理论部分,但Haskell部分绝对不是你的原始实现和原始类型签名的良好类型。
特定
free :: (Functor t, Monad m) => (∀ a. t a → m a) → (∀ a. Free t a → m a)
当你在Free tfta
模式匹配时,你会得到
tfta :: t (Free t a)
f :: forall a. t a -> m a
free :: (forall a. t a -> m a) -> forall a. Free t a -> m a
因此
free f :: forall a. Free t a -> m a
导致
fmap (free f) :: forall a. t (Free t a) -> t (m a)
所以为了能够将t (ma)
折叠成你想要的ma
,你需要在它上面应用f
(“将t
变成m
”),然后利用m
是Monad的事实:
f . fmap (free f) :: forall a. t (Free t a) -> m (m a)
join . f . fmap (free f) :: forall a. t (Free t a) -> m a
这意味着您可以通过更改free
的第二个分支来修复您的原始定义:
{-# LANGUAGE RankNTypes, UnicodeSyntax #-}
import Control.Monad.Free
import Control.Monad
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) = join . f . fmap (free f) $ tfta
这typechecks,可能可能可能是你想要的:)
链接地址: http://www.djcxy.com/p/47699.html