If you type unzip [] == ([],[])
into GHCi, it will correctly evaluate to True
, but when you add the line example_unzip_1 = unzip [] == ([],[])
to a file and try to open it, you get a type error. Why is this? In the GHC technical jargon, this has to do with "the monomorphism restriction", but what this means practically is that GHC doesn't know what type of lists you're using.
In GHCi, the interpreter automatically does some defaulting for you. If you type in a number like 3
, it prints out 3
. But, if you ask for the type of 3 with :t 3
, you see that it says 3 :: Num p => p
. So, if all GHCi knows is that 3
is a type that is an instance of Num
, how was it able to show it? And, why doesn't it show it as 3.0
, assuming you typed in a Float
? Well, in the absence of further information, GHCi "defaults" the type to Integer
and goes ahead and uses the Show
instance for Integer
. When you type unzip [] == ([],[])
, it defaults the types of the lists too, giving them a concrete type and an Eq
instance.
You're on the right track with your second attempt, (that is, example_unzip_1 = unzip []::[(a,b)] == ([],[])::([a],[b])
), but there are two problems here. First, GHC is a little finicky about type variables, and in this case, because you haven't introduced your type variables with the forall
keyword (which also requires using some language extensions, probably ScopedTypeVariables
), GHC doesn't actually realize that the a
on the left is the same as the a
on the right. But regardless, GHC still won't know which actual types to use when it does the equality check!
The way to fix this is to use actual concrete types. For instance, you could write:
example_unzip_1 = unzip []::[(Int,())] == ([],[])::([Int],[()])
This will properly type check. In fact, because of GHC's good type inference, you only need one type annotation, so you can simplify this to:
example_unzip_1 = unzip []::[(Int,())] == ([],[])