免费的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