看起来类型类如 Applicative , Monad和 Arrow在类型类中具有某种等价的总和类型,例如 Alternative , MonadPlus和 ArrowPlus分别。例如,Applicative 和 Alternative 可用于定义以下内容:
(<&&>) :: Applicative f => f a -> f b -> f (a, b)
a <&&> b = (,) <$> a <*> b
(<||>) :: Alternative f => f a -> f b -> f (Either a b)
a <||> b = (Left <$> a) <|> (Right <$> b)
但是,在所有这些情况下(以及 ArrowChoice ),产品类型类是总和类型类的先决条件。是否有依赖于先决条件类的类型类规则或通用函数? Typeclassopedia涉及这些关系,但不幸的是我找不到任何明确的依赖原因。
最佳答案
Arrow
基本上是 monoidal categories 的类1 – “monoid”不是指 Monoid
,而是 Haskell 类型的乘积monoid。即,使用单位元素 ()
和乘法 (,)
。现在,求和类型也构成了一个幺半群,这就是 ArrowChoice
使用的。从这个意义上说,这两个类别是互补的。 ArrowChoice
实际上不应该是 Arrow
的子类。
在幺半群类别中,您可以继续得到 monoidal functors 。这些结果如何取决于你使用什么作为你的类型幺半群。对于 (), (,)
,您将得到
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
是 initial object Hask,这意味着所有类型 a
都存在一个 Void -> a
(即 absurd
) 。然而,真正有意义的是带有 +
的共形仿函数:
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
这对于产品类型来说是没有意义的,因为 ()
是 terminal 对象。
现在有趣的是,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就像应用词对于单子(monad)一样。
虽然 Alternative
和 MonadPlus
似乎并没有太多数学支持,但它们本质上就是“un-Kleisliing”ArrowChoice 时得到的结果
类,但使用源自 ProdMonoidalFtor
的 Kleisli 类别。这一切都有点可疑。
1仅考虑第一个
/左
、第二个
/右
和***
/+++
。至于剩下的&&&
、|||
和arr
,这些更具体,IMO属于in seperate classes .
关于haskell - Haskell 类型类中的乘积和求和类型并行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29935479/