将州monad与costate comonad相结合

时间:2014-06-26 20:46:10

标签: haskell functional-programming monads category-theory comonad

如何将状态monad S -> (A, S)与costate comonad (E->A, E)合并?

我尝试了两种明显的组合S -> ((E->A, E), S)(E->S->(A, S), E),但在任何一种情况下我都不知道如何定义操作(returnextract,...等等。)组合。

2 个答案:

答案 0 :(得分:3)

如果OI被限制,即使用O方法,则合并两个monad Iextract会产生一个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,但它确实说你需要另一种理论来组成它们。

相比之下,组合附属物自然会导致另一个附属因素,因为你这样做了 指明组成两个给定理论的规则。因此,通过采用组合附加的单子,你得到的理论也规定了构成规则。