Haskell如何确定正确的数据构造函数?

Haskell如何确定正确的数据构造函数?,haskell,Haskell,这是我的密码: data TC a = DC1 a | DC2 a getDC :: TC a -> String getDC (DC1 x) = "created by first data constructor" getDC (DC2 x) = "created by second data constructor" 拥抱: Main> getDC (DC1 10) “由第一个数据构造函数创建” “由第二个数据构造函数创建” 因

这是我的密码:

data TC a = DC1 a | DC2 a

getDC           :: TC a -> String  
getDC (DC1 x)   = "created by first data constructor"  
getDC (DC2 x)   = "created by second data constructor"  

拥抱:

Main> getDC (DC1 10)
“由第一个数据构造函数创建”

“由第二个数据构造函数创建”


因此,解释器可以确定使用哪个数据构造函数。 我知道,每个值都有一个关联的类型。让我们检查一下:


DC1 10::Num a=>TC a

DC2 10::Num a=>TC a


在那里只能看到类型构造函数(TC)


解释器为什么、在哪里以及如何保存有关数据构造函数的附加信息?

当类型提供重要的编译时信息时,您仍在运行时操作值。使用的构造函数只是值的一个属性,特别是,您可以使用模式匹配来确定值中使用的构造函数的选择

getDC           :: TC a -> String  
getDC (DC1 x)   = "created by first data constructor"  
getDC (DC2 x)   = "created by second data constructor"

-- or, to be more clear about the pattern matching

getDC           :: TC a -> String  
getDC dc = case dc of
  (DC1 x) -> "created by first data constructor"  
  (DC2 x) -> "created by second data constructor"

为了更清楚一点,让我们尝试使用自然数,而不是使用抽象的TC类型

data Nat = Zero | Succ Nat
换句话说,我们写为0的内容可以表示为
Nat
as

Zero :: Nat
我们写的3可以表示为

Succ (Succ (Succ Zero))
我们可以在'Nat'上写一个函数

isThree :: Nat -> Bool
isThree (Succ (Succ (Succ Zero))) = True
isThree _                         = False

并且该函数的行为在其类型(
Nat->Bool
)中没有指示,因此该行为必须由值执行。实际上,我们使用模式匹配来破坏值并强制执行行为。

将值视为包含标记字段的框,该字段标识用于创建它的数据构造函数以及该构造函数所需的附加参数。由于Haskell是静态类型的,所以运行时不必区分不同类型的值,因此标记只需要标识该类型中的数据构造函数。您只能通过模式匹配间接检查标记,但是知道类型和标记后,您可以确定数据构造函数,并且可以安全地访问参数


注意,如果一个类型只有一个数据构造函数,那么该类型的值不需要标记。

这个问题类似于说data Bool=True | False…让b=True;编译器如何知道b是真的而不是假的?那有点。。。ADT的“点”。
Zero :: Nat
Succ (Succ (Succ Zero))
isThree :: Nat -> Bool
isThree (Succ (Succ (Succ Zero))) = True
isThree _                         = False