作者:1471446448_9c38cc | 来源:互联网 | 2023-01-19 14:21
1> Jon Purdy..:
你想要的签名是Double -> Double
.
Double d => d -> d
说"我接受任何类型的值d
,并返回相同类型的值,前提是它d
具有一个名为Double
" 的类型类的实例.编译器正在寻找一个被调用的类型类,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的类型(kind * -> Constraint
),但它Double
是一个不带参数(kind *
)的普通类型.您可以使用:kind
or :k
命令查看GHCi中常见类型和类型类的种类,以便更好地理解它们:
> :k Double
Double :: *
> :k Maybe
Maybe :: * -> *
> :k Maybe Double
Maybe Double :: *
> :k Eq
Eq :: * -> Constraint