我有以下类型声明:
data MyType = MyVal Int deriving (Eq, Show)
如您所见,它只有一个带参数的数据类型构造函数。
在书中,它说:
因为MyVal有一个Int参数,所以MyType类型的值必须 包含一个 - 只有一个 - Int值
为什么Int
是MyType类型的值或它是什么意思?
答案 0 :(得分:6)
它没有说Int是类型MyType
,它说MyVal(构造函数)必须只包含一个Int,所以例如你不能MyVal "hey!"
检查
Prelude> data MyType = MyVal Int deriving (Eq, Show)
Prelude> :t MyVal 9
MyVal 9 :: MyType
Prelude> MyVal '9'
<interactive>:12:7: error:
• Couldn't match expected type ‘Int’ with actual type ‘Char’
• In the first argument of ‘MyVal’, namely ‘'9'’
In the expression: MyVal '9'
In an equation for ‘it’: it = MyVal '9'
正如您所看到的,使用MyVal
类型MyType
的唯一方法是使用Int
,因此不允许使用其他类型。
答案 1 :(得分:1)
要超级明确和明确,希望有用:你说&#34;正如你所看到的,它只有一个带参数的数据类型构造函数。&#34;,但我会稍微调整一下
data MyType = MyVal Int deriving (Eq, Show)
此处MyType
是类型。它是一个零参数的类型构造函数,是查看它的一种方式。或者,您可以说它是数据类型构造函数。
但是,MyVal
是值构造函数。它是MyType
数据类型的值构造函数之一(在此示例中只有一个)。也就是说,它实际上是一个构造MyType
类型值的函数。因此,MyType
有一个名为MyVal
的值构造函数,它接受一个参数。该参数的类型为Int 。
如果我们询问GHCi这个函数的类型是什么,那么它的一个参数类型为Int
:
Main> :t MyVal
MyVal :: Int -> MyType
为什么它对#34;包裹&#34;当Int
类型已经是类型时?一个原因是它将MyVal
的含义与Int
分开,因此您可以拥有自己的类型,根据类型检查器和您的代码,它与Int
不同,即使它的表示现在恰好是Int
。
也许明天您可能决定将其更改为Integer
,在这种情况下,您可能需要做的就是更改一个位置,其余代码将起作用(假设您不是使用Int
来引用您打开的MyVal
,并且您拥有数据访问函数来处理MyVal
内部值的基本操作。
顺便说一下,仅仅是FYI,在这样的data
声明中包装单个类型通常不会在专业代码中完成,因为它需要执行周期来包装和解包它。还有另一种声明单值类型的方法,例如this newtype
,它提供了一种免费(在运行时)方式向编译器和类型检查器解释你想要一个具有表示为现有值之一。我确定你所阅读的任何书都会在适当的时候解释这一点,但如果它没有,请记下以后再查看。