Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么对newtype有限制?_Haskell - Fatal编程技术网

Haskell 为什么对newtype有限制?

Haskell 为什么对newtype有限制?,haskell,Haskell,我读到“newtype只有一个构造函数,其中只有一个字段。”这个限制是否增加了任何优势?如果值构造函数仅限于一个字段,为什么我不能在代码中直接使用该字段,而不是用newtype包装它呢?newtype是一种创建无运行时成本的数据抽象的工具 我所说的抽象是什么意思? 假设你有: greetPerson :: String -> String -> String greetPerson greeting name = greeting ++ " " ++ name greetPerso

我读到“newtype只有一个构造函数,其中只有一个字段。”这个限制是否增加了任何优势?如果值构造函数仅限于一个字段,为什么我不能在代码中直接使用该字段,而不是用newtype包装它呢?

newtype
是一种创建无运行时成本的数据抽象的工具

我所说的抽象是什么意思? 假设你有:

greetPerson :: String -> String -> String
greetPerson greeting name = greeting ++ " " ++ name

greetPerson "Hello" "Mike" => "Hello Mike"
这很好,但也为滥用提供了机会:

greetPerson "Mike" "Hello" => "Mike Hello"
问题是,您在任何地方都使用相同的类型(
String
),没有语义含义。让我们使用一个新类型:

newtype Name = Name String

greetPerson :: String -> Name -> String
greetPerson greeting (Name name) = greeting ++ " " ++ name

greetPerson "Hello" (Name "Mike") => "Hello Mike"
我们最终得到了相同的功能,但现在类型签名具有更多的意义,编译器可以在我们滥用它时告诉我们

我所说的无运行时成本是什么意思? 我的示例中的
newtype
仅存在于类型级别,编译器生成的代码与我在整个过程中使用的
String
完全相同

这暗示了为什么
newtype
只允许一个构造函数有一个字段

假设您试图使
newtype
为多个构造函数工作。您如何在运行时区分您使用的是哪一个?您必须存储一些附加信息

与多个字段相同。您需要某种方法将两个字段捆绑在一起

所有这些都会增加一些运行时成本,
newtype
承诺不会这样做

如果需要多个字段或多个构造函数,只需使用
数据

data Foo = Bar String | Baz Int Bool

当存在语义差异时,Newtype为您提供了一种区别于先前类型的方法。例如,
newtype Latittute=Lat Double;newtype Longitude=Lon Double
。你还可以重新定义你的类,很有趣!谢谢,我可以用type关键字来表达这个意思。还有什么额外的好处吗?没有,
type Latitude=Double
不会给你任何类型的安全性。如果将类型为
Double
或其他类型别名的值交换为
Double
,则不会出现编译时错误
type=\ucode>只创建别名。Newtype也很严格,因此关于底部的语义不同,性能也可能不同。如果您想了解更多有关这方面的信息,请访问Haskell wiki