免费的monad和免费的操作

描述自由单体的一种方式是说它是内功能体(属于某种类别C )类别中的一个初始幺半群,其对象是从CC的末端执行体,箭头是它们之间的自然变换。 如果我们把C作为Hask ,endofunctor就是Haskell中所谓的Functor ,它是来自* -> *函子,其中*表示Hask的对象

按照初始性,从endofunctor tEnd(Hask)的monoid m任何映射End(Hask)引发一个从Free tm的映射。

否则,从Functor t到Monad m任何自然转换都会诱导从Free tm的自然转换

我希望能够编写一个函数

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

上一篇: Free monad and the free operation

下一篇: Why is "bind" written as >>= in Haskell Monads?