Type Mismatch [GHC-83865]
GHC expected one type, but was given another. Unlike dynamically-typed programming languages,
type signatures in Haskell are like a contract between the programmer and the compiler.
In its simplest form, when you call a function f
with type a -> b
, with some argument x
,
the compiler will check whether x
has type a
and if that is not the case, it will trigger
the type mismatch error. This case is illustrated by the terms
example, below.
Type mismatch errors are quite general, however, so you will still encounter them in many other situations.
Examples
Values of Different Types
Function inc
has type Int -> Int
, hence it expects an argument
of type Int
; yet, on the definition of two
it was called with
an argument of type String
.
If you ever need to know the type of something, you can ask for it in ghci
with the command :type
(or its shorthand :t
):
ghci> :t "x"
"x" :: String
Error Message
Terms.hs:6:11: error: [GHC-83865]
• Couldn't match type ‘[Char]’ with ‘Int’
Expected: Int
Actual: String
• In the first argument of ‘inc’, namely ‘"x"’
In the expression: inc "x"
In an equation for ‘two’: two = inc "x"
|
4 | two = inc "x"
|
Terms.hs
inc :: Int -> Int
inc i = i + 1
two = inc "x"
inc :: Int -> Int
inc i = i + 1
two = inc 1
Type expected, but kind received.
Forgetting the type parameter to Maybe
is the culprit, but it is only caught in the
context of the the arrow in the declaration of isNothing
, which can be confusing.
The arrow (->
) in Haskell is a type constructor. It takes two types
of kind Type
, and returns a fresh type, also of kind Type
. That is, for x -> y
to make any sense, GHC needs x
and y
to be types of kind Type
, which is not
the case in this example: Maybe
by itself has kind Type -> Type
.
If you ever need to know the kind of something, you can ask ghci
with the :kind
(or its shorthand :k
), keeping in mind
that *
(pronounced “star”) is a synonym for Type
:
ghci> :k (->)
(->) :: * -> * -> *
ghci> :k Maybe
Maybe :: * -> *
Error Message
Type.hs:1:14: error: [GHC-83865]
• Expecting one more argument to ‘Maybe’
Expected a type, but ‘Maybe’ has kind ‘* -> *’
• In the type signature: isNothing :: Maybe -> Bool
|
1 | isNothing :: Maybe -> Bool
|
Type.hs
isNothing :: Maybe -> Bool
isNothing Nothing = True
isNothing _ = False
isNothing :: Maybe a -> Bool
isNothing Nothing = True
isNothing _ = False