gpt4 book ai didi

haskell - 为什么我们需要 Sum 类型?

转载 作者:行者123 更新时间:2023-12-04 01:27:37 25 4
gpt4 key购买 nike

想象一种不允许数据类型使用多个值构造函数的语言。而不是写

data Color = White | Black | Blue

我们会有
data White = White
data Black = Black
data Blue = Black
type Color = White :|: Black :|: Blue

在哪里 :|: (这里不是 | 以避免与 sum 类型混淆)是一个内置类型联合运算符。模式匹配将以相同的方式工作
show :: Color -> String
show White = "white"
show Black = "black"
show Blue = "blue"

如您所见,与副产品相比,它产生了扁平结构,因此您不必处理注入(inject)。而且,与 sum 类型不同,它允许随机组合类型,从而获得更大的灵 active 和粒度:
type ColorsStartingWithB = Black :|: Blue

我相信构造递归数据类型也不是问题
data Nil = Nil
data Cons a = Cons a (List a)
type List a = Cons a :|: Nil

我知道联合类型存在于 TypeScript 和其他语言中,但为什么 Haskell 委员会选择 ADT 而不是它们?

最佳答案

Haskell 的 sum 类型与您的 :|: 非常相似。 .

两者的区别在于 Haskell 求和类型 |是一个标记的联合,而你的“总和类型”:|:未标记。

标记意味着每个实例都是唯一的 - 你可以区分 Int | Int来自 Int (实际上,这适用于任何 a ):

data EitherIntInt = Left Int | Right Int

在这种情况下: Either Int Int包含比 Int 更多的信息因为可以有 LeftRight Int .

在您的 :|: ,您无法区分这两个:
type EitherIntInt = Int :|: Int

你怎么知道是左还是右 Int ?

有关以下部分的扩展讨论,请参阅评论。

标记联合还有另一个优点:编译器可以验证您作为程序员是否处理了所有情况,这对于一般的未标记联合来说是依赖于实现的。您处理了 Int :|: Int 中的所有案件吗? ?这要么与 Int 同构根据定义或编译器必须决定哪个 Int (左或右)选择,如果它们无法区分,这是不可能的。

考虑另一个例子:
type (Integral a, Num b) => IntegralOrNum a b = a :|: b    -- untagged
data (Integral a, Num b) => IntegralOrNum a b = Either a b -- tagged

什么是 5 :: IntegralOrNum Int Double在未标记的联盟中?它都是 Integral 的一个实例和 Num ,所以我们不能确定,必须依赖实现细节。另一方面,标记的联合确切地知道 5应该是因为它被标记为 LeftRight .

至于命名:Haskell 中的不相交联合是联合类型。 ADT 只是实现这些的一种手段。

关于haskell - 为什么我们需要 Sum 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40620913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com