为什么有“数据”和“新类型”在Haskell中? [英] Why is there "data" and "newtype" in Haskell?
问题描述
newtype
定义只是一个 data
定义,它遵从一些限制(例如,只有一个构造函数),并且由于这些限制,运行时系统可以更高效地处理 newtype
。对于未定义值的模式匹配处理略有不同。假设Haskell只会知道 data
的定义,否则 c> s:编译器无法自己发现给定的数据定义是否遵从这些限制,并自动更有效地对待它?
我确定我错过了某些东西,因此必须有一些更深的理由。
newtype 和单构造函数 data
引入了一个单值构造函数,但由 newtype
引入的值构造函数是严格的,由 data
引入的值构造函数是惰性的。所以如果你有
data D = D Int
newtype N = N Int
然后 N undefined
相当于 undefined
并在评估时导致错误。但 D undefined
不等于 undefined
,并且只要
编译器不能自己处理它。
不,不是真的 - 这是程序员可以决定构造函数是严格还是懒惰的情况。为了理解什么时候以及如何让构造函数严格或者懒惰,你必须比懒惰更好地理解懒惰评估。我坚持报告中的想法,即 newtype
可以让您重命名现有类型,例如有几种不同类型的度量:
newtype Feet = Feet Double
newtype Cm = Cm Double
在运行时的行为与 Double 完全相同,但编译器承诺不会让您混淆。
It seems that a newtype
definition is just a data
definition that obeys some restrictions (e.g., only one constructor), and that due to these restrictions the runtime system can handle newtype
s more efficiently. And the handling of pattern matching for undefined values is slightly different.
But suppose Haskell would only knew data
definitions, no newtype
s: couldn't the compiler find out for itself whether a given data definition obeys these restrictions, and automatically treat it more efficiently?
I'm sure I'm missing out on something, there must be some deeper reason for this.
解决方案 Both newtype
and the single-constructor data
introduce a single value constructor, but the value constructor introduced by newtype
is strict and the value constructor introduced by data
is lazy. So if you have
data D = D Int
newtype N = N Int
Then N undefined
is equivalent to undefined
and causes an error when evaluated. But D undefined
is not equivalent to undefined
, and it can be evaluated as long as you don't try to peek inside.
Couldn't the compiler handle this for itself.
No, not really—this is a case where as the programmer you get to decide whether the constructor is strict or lazy. To understand when and how to make constructors strict or lazy, you have to have a much better understanding of lazy evaluation than I do. I stick to the idea in the Report, namely that newtype
is there for you to rename an existing type, like having several different incompatible kinds of measurements:
newtype Feet = Feet Double
newtype Cm = Cm Double
both behave exactly like Double
at run time, but the compiler promises not to let you confuse them.
这篇关于为什么有“数据”和“新类型”在Haskell中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文