Arrow 基本上是 monoidal categories1 的类——“monoid”不是指 Monoid,而是 Haskell 类型的 product-monoid。即,单位元素() 和乘法(,)。现在,sum 类型也构成了一个幺半群,这就是 ArrowChoice 使用的。这两个类别在这个意义上是互补的。 ArrowChoice 不应该是 Arrow 的子类。
在幺半群类别中,您可以继续拥有monoidal functors。这些结果如何取决于您用作类型monoid的内容。对于(), (,),你得到
class ProdMonoidalFtor f where
prodUnit :: () -> f ()
prodZip :: (f a, f b) -> f (a,b)
type (+) = Either
class SumMonoidalFtor f where
sumUnit :: Void -> f Void
sumZip :: f a + f b -> f (a+b)
原来后者基本上没用,因为Void是Hask的initial object,这意味着allVoid -> a(即absurd) /em> 类型 a。然而,真正有意义的是带有+的comonoidal functors:
class SumCoMonoidalFtor f where
sumCounit :: f Void -> Void -- I bet you find this useless too, but it's not totally.
sumCozip :: f (a+b) -> f a + f b
这反过来对产品类型没有意义,因为() 是 终端 对象。
现在有趣的是ProdMonoidalFtor 等价于Applicative:
instance (ProdMonoidalFtor f) => Applicative f where
pure x = fmap (const x) $ prodUnit ()
fs <*> xs = fmap (\(f,x) -> f x) $ prodZip (fs,xs)
然后有人可能会怀疑Alternative 等同于SumMonoidalFtor,但事实并非如此!实际上,它相当于decisive functors,相当于comonads,就像应用程序对monads一样。
虽然 Alternative 和 MonadPlus 似乎并没有太多的数学支持,但它们本质上是你在“un-Kleisliing”ArrowChoice 类时得到的,但使用来自 @ 的 Kleisli 类别987654352@。这有点可疑。
1这里只考虑first/left、second/right和***/+++。至于剩下的&&&、|||和arr,这些更具体,IMO属于in seperate classes。