我尝试了明显的组合S -> ((E->A,E),S)和(E->S->(A,S),E),但在任一情况下,我都不知道如何为组合定义操作(return,extract等)。
将两个单子(O和I)结合起来可以形成一个单子,如果O或I有一个extract方法,即它们是copointed的。每个共同单子都是copointed的。如果O和I都是copointed,则有两种不同的“自然”方式可以获得单子,这两种方式可能不等价。
你有:
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是copointed,即存在一个函数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
单子
这带领我们到
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
这定义了一个新的单子。我假设你可以以同样的方式定义一个新的余单子,但我没有尝试过。
forall r.F(r)->r
上的任何自然单子结构(在F上自然)都会导致F上的一个余单子。你认为这是正确的吗? - mnishS -> ((E->A, E), S)
和 (E->S->(A, S), E)
都同时具有Monad和Comonad实例。实际上,给出一个Monad/Comonad实例等价于在其点 ∀r.r->f(r) 或其余点 ∀r.f(r)->r 上赋予monoid结构,至少在经典的非构造意义下是这样(我不知道构造性答案)。这个事实表明,实际上一个Functor f 有很大的机会既可以是Monad又可以是Comonad,只要它的点和余点是非平凡的。 Fₑ Fₛ
--> -->
Hask ⊣ Hask ⊣ Hask
<-- <--
Gₑ Gₛ
Fₜ(a) = (a,t)
Gₜ(a) = (t->a)
Fₜ ⊣ Gₜ 的证明:
Fₜ(x) -> y ≃
(x,t) -> y ≃
x -> (t->y) ≃
x -> Gₜ(y)
FₛFₑ(x) -> y ≃
Fₑ(x) -> Gₛ(y) ≃
x -> GₑGₛ(y)
所以 FₛFₑ ⊣ GₑGₛ。这提供了一对单子和余单子,即
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) 的状态单子,G是带有反状态(e,s)的共状态余子,因此它们确实具有非常自然的含义。
组合伴随是一种自然、频繁出现的数学操作。例如,在拓扑空间上的层(一种允许在“类型层面”进行复杂(非自由)构造的笛卡尔闭类别)之间的一个几何态射被定义为一对伴随,仅要求其左伴随是左精确的(即保持有限极限)。如果这些层是拓扑空间上的层,则将伴随组合简单地对应于组合(唯一的)连续基变换映射(相反方向),具有非常自然的含义。
另一方面,直接组合单子/余子似乎在数学中非常少见。这是因为通常认为(余)单子是(余)代数理论的载体,而不是模型。在这种解释下,相应的伴随就是模型,而不是单子。问题在于,组合两个理论需要另一个理论,一个关于如何组合它们的理论。例如,想象一下组合两个幺半群理论。那么你可能会得到至少两个新的理论,即列表的理论或环状代数的理论,其中两种二元运算分别分配。从先验上看,它们都不比另一个更好/更自然。这就是“单子无法组合”的含义;它并不表示该组合不能成为单子,但它确实表示需要另一个关于如何组合它们的理论。
相反,组合伴随自然地产生另一个伴随,因为通过这样做,您隐含地指定了组合两个给定理论的规则。因此,通过取组合伴随的单子,您将获得还指定组合规则的理论。
Bool
和Int
结合起来,也要同时使用它们?” - luqui