类型签名错误Haskell

类型签名错误Haskell,haskell,Haskell,这可能是一个愚蠢的问题,但我想更好地理解类型签名,以及为什么在运行代码时出现以下错误。代码如下 area :: Double d => d -> d area x = x^2 * 3.14 我得到的错误如下 Double is applied to too many type arguments In the type signature for `area': area :: Double d => d -> d 您需要的签名是Double->Double Doub

这可能是一个愚蠢的问题,但我想更好地理解类型签名,以及为什么在运行代码时出现以下错误。代码如下

area :: Double d => d -> d
area x = x^2 * 3.14
我得到的错误如下

Double is applied to too many type arguments
In the type signature for `area': area :: Double d => d -> d

您需要的签名是
Double->Double

Double d=>d->d
表示“我获取任何类型的值
d
,并返回相同类型的值,前提是
d
有一个名为
Double
的typeclass实例”。编译器正在寻找一个名为
Double
的类型类,但没有这样的类型类;相反,它会找到一个名为
Double
的类型,并给出一个错误

通过一些扩展(例如
TypeFamilies
GADTs
),您可以这样编写此类型:

(d ~ Double) => d -> d
这表示“我获取任何类型的值
d
,并返回相同类型的值,前提是
d
等于
Double
”。这只是一种迂回的说法
Double->Double
;如果编写这种类型的函数,编译器实际上会将其展开为
Double->Double

> :set -XTypeFamilies
> let f :: (d ~ Double) => d -> d; f x = x
> :t f
f :: Double -> Double
更严格地说,您遇到的错误是一种类型错误。类型是“类型的类型”,用于检查诸如为类型提供正确数量的类型参数之类的内容。因为您为
Double
提供了一个类型参数,GHC推断它应该是一个类型类,如
Eq
Ord
,它以1个类型作为参数(种类
*->约束
),但
Double
是一个不带参数的普通类型(种类
*
)。您可以使用
:kind
:k
命令查看GHCi中常见类型和类型类的种类,以便更好地了解它们:

> :k Double
Double :: *

> :k Maybe
Maybe :: * -> *

> :k Maybe Double
Maybe Double :: *

> :k Eq
Eq :: * -> Constraint

您需要的签名是
Double->Double

Double d=>d->d
表示“我获取任何类型的值
d
,并返回相同类型的值,前提是
d
有一个名为
Double
的typeclass实例”。编译器正在寻找一个名为
Double
的类型类,但没有这样的类型类;相反,它会找到一个名为
Double
的类型,并给出一个错误

通过一些扩展(例如
TypeFamilies
GADTs
),您可以这样编写此类型:

(d ~ Double) => d -> d
这表示“我获取任何类型的值
d
,并返回相同类型的值,前提是
d
等于
Double
”。这只是一种迂回的说法
Double->Double
;如果编写这种类型的函数,编译器实际上会将其展开为
Double->Double

> :set -XTypeFamilies
> let f :: (d ~ Double) => d -> d; f x = x
> :t f
f :: Double -> Double
更严格地说,您遇到的错误是一种类型错误。类型是“类型的类型”,用于检查诸如为类型提供正确数量的类型参数之类的内容。因为您为
Double
提供了一个类型参数,GHC推断它应该是一个类型类,如
Eq
Ord
,它以1个类型作为参数(种类
*->约束
),但
Double
是一个不带参数的普通类型(种类
*
)。您可以使用
:kind
:k
命令查看GHCi中常见类型和类型类的种类,以便更好地了解它们:

> :k Double
Double :: *

> :k Maybe
Maybe :: * -> *

> :k Maybe Double
Maybe Double :: *

> :k Eq
Eq :: * -> Constraint

Double
是一种
类型
,但您使用它的方式就像使用
类型类一样。请参阅。好的,这很有帮助。的可能重复项。
Double
是一个
类型
,但您使用它的方式就像它是一个
typeclass
。看到了。好吧,这很有帮助。可能是重复的。考虑到问题的基本层面,我觉得这个答案中关于种类的所有讨论都是多余的,可能对OP来说相当混乱。@luqui:我发现在我的Haskell之旅的早期了解种类是有帮助的,但我很感激它可能对每个人都没有同样的帮助。我将这些信息分成了一个单独的部分,并添加了更多的解释,希望至少更清楚。我发现这个答案中所有关于种类的讨论都是多余的,可能对OP来说相当混乱,考虑到这个问题的基本层面。@luqui:在哈斯凯尔之旅的早期,我发现了解物种是很有帮助的,但我很感激它可能对每个人都没有同样的帮助。我将这些信息分成了一个单独的部分,并添加了更多的解释,希望至少更清楚。