如何将状态monad S -> (A, S)
与costate comonad (E->A, E)
合并?
我尝试了两种明显的组合S -> ((E->A, E), S)
和(E->S->(A, S), E)
,但在任何一种情况下我都不知道如何定义操作(return
,extract
,...等等。)组合。
答案 0 :(得分:3)
如果O
或I
被限制,即使用O
方法,则合并两个monad I
和extract
会产生一个monad。每个comonad都是copointed。如果同时考虑O
和I`,那么你有两种不同的“自然”方式来获得一个可能不等同的monad。
你有:
unit_O :: a -> O a
join_O :: O (O a) -> O a
unit_I :: a -> I a
join_I :: I (I a) -> I a
为了清楚起见,我添加了_O
和_I
后缀;在实际的Haskell代码中,它们不会存在,因为类型检查器会自行解决这个问题。
您的目标是证明O (I O (I a)))
是monad。我们假设O
被定位,即有一个函数extract_O :: O a -> a
。
然后我们有:
unit :: a -> O (I a)
unit = unit_O . unit_I
join :: O (I (O (I a))) -> O (I a)
问题当然是在实施join
。我们遵循这一策略:
fmap
上方O
extract_O
来获取内部O
join_I
合并两个I
monad 这导致我们
join = fmap_O $ join_I . fmap_I extract
要使这项工作,您还需要定义
newtype MCompose O I a = MCompose O (I a)
并将相应的类型构造函数和解构函数添加到上面的定义中。
另一种选择使用extract_I
代替extract_O
。这个版本更简单:
join = join_O . fmap_O extract_I
这定义了一个新的monad。我假设你可以用同样的方式定义一个新的comonad,但我没有尝试过这个。
答案 1 :(得分:2)
正如另一个答案所示,两个组合S -> ((E->A, E), S)
和(E->S->(A, S), E)
同时拥有Monad和Comonad实例。事实上,给Monad / Comonad实例是
相当于给一个
幺半群结构。其点∀r.r-> f(r)或其 copoints ∀r.f(r) - > r,至少在经典中,
非建设性的意义(我不知道建设性的答案)。这个事实表明实际上是一个
Functor f很有可能
无论是Monad还是Comonad,只要它的要点和关键点都是非平凡的。
然而,真正的问题是Monad / Comonad实例是否具有自然特征 计算/分类意义。在这种特殊情况下,我会说" no",因为你似乎没有 先验有关如何以适合您的计算需求的方式撰写它们的知识。
组成两个(共)单子的标准分类方法是通过附件。让我总结一下你的情况:
Fₑ Fₛ
--> -->
Hask ⊣ Hask ⊣ Hask
<-- <--
Gₑ Gₛ
Fₜ(a) = (a,t)
Gₜ(a) = (t->a)
FₜₜGPro的证明:
Fₜ(x) -> y ≃
(x,t) -> y ≃
x -> (t->y) ≃
x -> Gₜ(y)
现在你可以看到状态monad(s->(a,s))≃(s-> a,s-> s)是组合GₛFₛ和costate comonad 是FₑGₑ。该附录说Hask可以解释为(共)状态(共)代数的模型。
现在,&#39; adjunctions撰写。&#39;例如,
FₛFₑ(x) -> y ≃
Fₑ(x) -> Gₛ(y) ≃
x -> GₑGₛ(y)
所以FₛFₑₑGₑGₛ。这给出了一对monad和comonad,即
T(a) = GₑGₛFₛFₑ(a)
= GₑGₛFₛ(a,e)
= GₑGₛ(a,e,s)
= Gₑ(s->(a,e,s))
= e->s->(a,e,s)
= ((e,s)->a, (e,s)->(e,s))
G(a) = FₛFₑGₑGₛ(a)
= FₛFₑGₑ(s->a)
= FₛFₑ(e->s->a)
= Fₛ(e->s->a,e)
= (e->s->a,e,s)
= ((e,s)->a, (e,s))
T只是具有状态(e,s)的状态monad,G是具有costate(e,s)的costate comonad,所以 这些确实有很自然的含义。
组合附件是一种自然的,频繁的数学运算。例如,几何态射 topoi(在类型级别上允许复杂(非自由)构造的类型的笛卡尔闭合类别被定义为一对附加,仅要求其左伴随左精确< / em>(即保留有限的限制)。如果那些topoi是拓扑空间上的滑轮, 组成附录只是对应于组成(独特的)连续基础变化图(在相反的方向上),具有非常自然的意义。
另一方面,直接编写monads / comonads似乎是数学中非常罕见的练习。 这是因为通常(共)单子被认为是(共)代数理论的载体,而不是 模型。在此解释中,相应的附加是模型,而不是monad。问题 构成两种理论需要另一种理论,一种关于如何构成它们的理论。例如, 想象一下构成两种幺半群理论。那么你可能会得到至少两个新的理论, 即列表列表理论,或两种二元运算分布的环状代数。 先验比其他更好/更自然。这就是&#34; monads没有撰写&#34 ;;它并没有说组成不能成为monad,但它确实说你需要另一种理论来组成它们。
相比之下,组合附属物自然会导致另一个附属因素,因为你这样做了 指明组成两个给定理论的规则。因此,通过采用组合附加的单子,你得到的理论也规定了构成规则。