简体   繁体   English

类型签名错误Haskell

[英]Type Signature error Haskell

This is probably a dumb question but I would like to understand type signatures better and why I am getting the following error when I run my code. 这可能是一个愚蠢的问题,但我想更好地理解类型签名,以及为什么在运行代码时出现以下错误。 Code is below. 代码如下。

area :: Double d => d -> d
area x = x^2 * 3.14

The error I am getting is below. 我得到的错误如下。

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

The signature you want is Double -> Double . 您想要的签名是Double -> Double

Double d => d -> d says “I take a value of any type d , and return a value of that same type, provided that d has an instance of a typeclass called Double ”. Double d => d -> d表示:“只要d具有类型为Double的类型类的实例,我就可以获取任何类型d的值,并返回相同类型的值”。 The compiler is looking for a typeclass called Double but there is no such typeclass; 编译器正在寻找一个叫做Double类型类,但是没有这样的类型类。 instead it finds a type called Double , giving an error. 而是找到一个名为Double类型 ,并给出一个错误。

With some extensions (such as TypeFamilies or GADTs ) you can write this type like so: 使用某些扩展名(例如TypeFamiliesGADTs ),您可以这样编写此类型:

(d ~ Double) => d -> d

This says “I take a value of any type d , and return a value of that same type, provided that d is equal to Double ”. 这就是说:“只要d等于Double ,我就可以取任何类型d的值,并返回相同类型的值”。 That's just a roundabout way of saying Double -> Double ; 这只是说Double -> Double一种回旋方式。 if you write a function of this type, the compiler will actually expand it out to Double -> Double : 如果您编写此类型的函数,则编译器实际上会将其扩展为Double -> Double

> :set -XTypeFamilies
> let f :: (d ~ Double) => d -> d; f x = x
> :t f
f :: Double -> Double

More technically, the error you've encountered is a kind error—kinds are the “types of types” and are used to check things like giving the correct number of type parameters to a type. 从技术上讲,您遇到的错误是一种类型错误-种类是“类型的类型”,用于检查诸如为类型提供正确数量的类型参数之类的事情。 Because you give a type parameter to Double , GHC infers that it should be a typeclass like Eq or Ord that takes 1 type as an argument (kind * -> Constraint ), but Double is a plain type that takes no arguments (kind * ). 因为您为Double提供了一个类型参数,GHC推断它应该是一个像EqOrd这样的类型类,它以1个类型作为参数(kind * -> Constraint ),但是Double是一个不带参数的普通类型(kind * ) 。 You can see the kinds of common types & typeclasses in GHCi with the :kind or :k command to get a better understanding of them: 您可以使用:kind:k命令查看GHCi中常见类型和类型类的:kind ,以更好地理解它们:

> :k Double
Double :: *

> :k Maybe
Maybe :: * -> *

> :k Maybe Double
Maybe Double :: *

> :k Eq
Eq :: * -> Constraint

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM