Haskell类型类中的产品类型和求和类型对应关系

8

看起来像是类型类,例如ApplicativeMonadArrow在类型类AlternativeMonadPlusArrowPlus中有某种求和类型的等效物。例如,可以使用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涉及这些关系,但不幸的是我找不到明确的依赖原因。

可能的情况是,如果没有成为一个乘积,就不可能成为一个总和,但仅仅成为一个总和是有可能的。 - AJF
1个回答

6
Arrow基本上是单子范畴1的类,其中“单子”不是指Monoid,而是Haskell类型的乘积单子。即具有单位元素()和乘法(,)。现在,总和类型也组成了一个单子,这就是ArrowChoice使用的内容。这两个类在这个意义上是互补的;ArrowChoice不应该真正成为Arrow的子类。

在单子范畴中,您可以继续拥有单子函子。如何得到这些取决于您使用的类型单子。对于(), (,),您将获得:

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)

原来后者基本上是没有用的,因为 VoidHask初始对象,这意味着存在恰好一个Void -> a(即对于 所有 类型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

这反过来对于产品类型是没有意义的,因为()终端对象。

现在有趣的是,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,但实际上不是这样!事实上,它等同于决策函子,这些函子与余单子的关系类似于应用函子与单子的关系。

AlternativeMonadPlus似乎没有太多的数学支持,它们本质上是在“非Kleisliing”ArrowChoice类时得到的,但使用由ProdMonoidalFtor产生的Kleisli范畴。这一切都有点可疑。


1这仅考虑first/leftsecond/right***/+++。至于剩下的&&&|||arr,这些更具体,我认为应该在单独的类中


sumZip 也是无意义的,因为你可以使用 either (fmap Left) (fmap Right),对吧? - chi
我想是的,但我不确定证明。 - leftaroundabout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接