Reputation: 71
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
Upvotes: 1
Views: 271
Reputation: 54979
The signature you want is 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
”. The compiler is looking for a typeclass called Double
but there is no such typeclass; instead it finds a type called Double
, giving an error.
With some extensions (such as TypeFamilies
or GADTs
) you can write this type like so:
(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
”. That’s just a roundabout way of saying Double -> Double
; if you write a function of this type, the compiler will actually expand it out to 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 *
). You can see the kinds of common types & typeclasses in GHCi with the :kind
or :k
command to get a better understanding of them:
> :k Double
Double :: *
> :k Maybe
Maybe :: * -> *
> :k Maybe Double
Maybe Double :: *
> :k Eq
Eq :: * -> Constraint
Upvotes: 5