gpt4 book ai didi

haskell - Haskell 如何知道数据类型声明是变量还是命名类型?

转载 作者:行者123 更新时间:2023-12-04 06:41:14 24 4
gpt4 key购买 nike

采用数据类型声明,如

data myType = Null | Container TypeA v 

据我了解,Haskell 会将其读作 myType有两种不同的口味。其中之一是 Null Haskell 将其解释为 a 的某个名称……我猜你会称它为该类型的实例?还是亚型?因素?等级?无论如何,如果我们更改 NullNubb它的行为方式基本相同——Haskell 对空值一无所知。

另一种口味是 Container我希望 Haskell 会读到 Container flavor 需要两个字段, TypeAv .我希望这是因为在进行这种类型定义时,第一个单词总是被读作 flavor 的名称,而后面的所有内容都是另一个字段。

我的问题(此外:我有没有弄错?)是,Haskell 怎么知道 TypeA是特定的命名类型而不是无类型变量?我错误地认为它是 v作为无类型变量,如果这是正确的,是因为小写首字母吗?

无类型是指类型如何出现在函数的以下类型声明中:
func :: a -> a 
func a = a

最佳答案

首先,术语:“flavors”被称为“cases”或“constructors”。您的类型有两种情况 - NullContainer .

其次,你所说的“无类型”并不是真正的“无类型”。这不是正确的思考方式。 a在声明中 func :: a -> a并不意味着“无类型”,就像在 JavaScript 或 Python 中变量“无类型”一样(尽管这不是真的),而是“调用此函数的人选择类型”。所以如果我调用 func "abc" ,那么我选择了a成为 String ,现在编译器知道这个调用的结果也一定是String ,因为这就是 func的签名上写着——“我采用您选择的任何类型,并且返回相同的类型”。合适的术语是“通用”。

“untyped”和“generic”之间的区别在于“untyped”是免费的,类型只会在运行时知道,没有任何保证;而泛型类型,即使还不完全清楚,它们之间仍然存在某种关系。例如,您的 func说它返回相同的类型,而不是随机的。或者再举一个例子:

mkList :: a -> [a]
mkList a = [a]

这个函数说“我采用你选择的某种类型,我将返回一个相同类型的列表——绝不是其他东西的列表”。

最后,您的 myType声明实际上是非法的。在 Haskell 中,具体类型必须是 Capitalized , 而值和类型变量是 javaCase .因此,首先,您必须更改类型的名称以满足这一点:
data MyType = Null | Container TypeA v

如果您现在尝试编译它,您仍然会收到一条错误消息,提示“类型变量 v 未知”。看,Haskell 决定 v必须是类型变量,而不是具体类型,因为它是小写的。就这么简单。

如果要使用类型变量,则必须在某处声明它。在函数声明中,类型变量可能会突然“出现”,编译器会认为它们“已声明”。但是在类型声明中,您必须显式声明您的类型变量,例如:
data MyType v = Null | Container TypeA v

存在此要求是为了避免在您有多个类型变量或类型变量来自另一个上下文(例如类型类实例)的情况下出现混淆和歧义。

以这种方式声明,您必须指定一些东西来代替 v每次使用 MyType , 例如:
n :: MyType Int
n = Null

mkStringContainer :: TypeA -> String -> MyType String
mkStringContainer ta s = Container ta s

-- Or make the function generic
mkContainer :: TypeA -> a -> MyType a
mkContainer ta a = Container ta a

关于haskell - Haskell 如何知道数据类型声明是变量还是命名类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52584050/

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