类型类非常多不是像OO类,这怎么强调也不过分。
特别是,“如果1.0
变成Num
”没有任何意义。 Num
是一个类型的类,而不是一个类型,所以没有任何东西可以“变成Num
”。事实上,在Haskell –中都没有任何东西变成别的东西,所有东西都有一个具体的类型,这是固定的。
现在你问,多态函数是如何工作的呢?那么,它被称为参数多态性的一个原因:什么似乎是“任意类型a
”实际上是一个类型参数。就像函数参数一样,这些变量并不是变量,它们可以在事后改变它们的值,但是它们是可变的,因为函数的调用者可以选择任何特定的“类型值”对于a
–只要它满足类型约束。
因此,在某种意义上,文字1
是一个函数:它接受一个类型参数a
,并返回一个值1 :: a
。它要求的是a
在类Num
。
然后我们有(+)
和1.0
,两者都需要相同的a
参数。 (+)
再次需要Num
,没什么新意;但是1.0
要求Fractional a
。因此,所有的一切,1 + 1.0
是接受的” “三份类型参数a
一个功能,并要求
Num a
Num a
Fractional a
–这也需要Num a
因为Num
是Fractional
超。
如果我们真的不得不写类型出来作为
(1 + 1.0) :: (Num a, Num a, Fractional a, Num a) => a
因此被允许离开了冗余约束,只留下Fractional a
,这意味着所有的其他人来说将是非常尴尬的。我们不能做的只是留下Num
的限制之一,因为这并不意味着Fractional
。
你写道:“所以如果我们有一个数字为1的数字,它可以是分数(因为有些数字是分数),或者它不可能是。好的,但问题是,你怎么知道1可以是分数?这是一个合法的问题,因为你告诉我,1可以是或不是分数。在这里发生了一些有关Num的特殊魔法,Haskell有特殊的对待,或者这是关于类型和函数的更一般的东西?请详细说明。 – stackoverflowuser 2015-02-07 18:43:16
@stackoverflowuser直接从语句“每个小数是一个数字”,我们知道这是因为“小数”被定义为'类数量a =>小数a其中...'。 – sepp2k 2015-02-07 18:56:25
这对我来说没有意义。 “每个分数都是数字”告诉你每个分数都是一个数字,而不是每个数字都是一个分数。 1是Num。我现在很困惑。换句话说:假设我创建了自己的类型,它是Num的一个实例。这种类型的值如何成为分数?靠魔术?也许Haskell在1的情况下做了一些特殊的魔术,它不适用于我自己的Num类型的值? – stackoverflowuser 2015-02-07 20:26:39