I have a question on how GHCi assumes type of a whole number.
I was reading Yes-No type class of Learn you a Haskell.
Here is a link if you want to read the whole thing. http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass
To put it shortly, this chapter shows that by defining my own class, I can make a function that works with a lot of types.
This book defines YesNo class with a function
yesno :: a -> Bool
and make Int
as a instance of YesNo class
instance YesNo Int where yesno 0 = False yesno _ = True
When I loaded this on my GHCi and typed
yesno 0
it returned error. I thought it is probably because GHCi cannot tell whether 0 is meant to be Int
or Integer
or Double
or other type in Num
class. Actually when I typed yesno (0::Int) it worked.
So just for fun I made Integer
as an instance of YesNo
class and wrote
instance YesNo Integer where yesno 0 = True yesno _ = False
(Note that I flipped True and False) and again, I typed
yesno 0
(without any type declaration) then GHCi showed True
.
Moreover, when I typed
yesno $ fromIntegral 0
it returned True
, which means that GHCi thinks the type of fromIntegral 0
is Integer
.
So, does this mean that when I just type a whole number on GHCi, it usually assumes its value is Integer
in stead of? I am confused because :t 0
returns Num a => a
It's type defaulting together with ghci's extended default rules.
Integer literals are polymorphic, they have the type Num a => a
(since they stand for fromInteger literal
). But when an expression shall be evaluated - necessary for printing its result, for example - the expression must be given a monomorphic type.
By itself,
yesno 0
imposes the two constraints Num a
and YesNo a
on the 0
, and the entire expression would have the ambiguous type
yesno 0 :: (Num a, YesNo a) => Bool
(it's ambiguous, since the type variable in the constraint is not reachable from the type on the right of the =>
).
Generally, ambiguous types are type errors, however, in some cases the ambiguity is resolved by instantiating the constrained type variable with a default type. The rules in the language specification are that a type variable can be defaulted if
In situations where an ambiguous type is discovered, an ambiguous type variable,
v
, is defaultable if:
- `v` appears only in constraints of the form `C v`, where `C` is a class, and - at least one of these classes is a numeric class, (that is, `Num` or a subclass of `Num`), and - all of these classes are defined in the Prelude or a standard library (Figures 6.2–6.3 show the numeric classes, and Figure 6.1 shows the classes defined in the Prelude.)
The constraint (Num a, YesNo a)
meets the first two requirements, but not the third. So by the language standard, it is not defaultable and should be a type error.
However, ghci uses extended default rules and also defaults type variables constrained by classes not defined in the Prelude or the standard libraries.
It would then choose the default for a Num
constraint here, unless an explicit default declaration is in scope, that would be Integer
, or, if Integer
does not satisfy the constraints, Double
is tried.
So when you have an instance YesNo Integer
, ghci can successfully default the type variable a
to Integer
. But with no such instance available, defaulting fails because none of the default candidates has an instance.
So, does this mean that when I just type a whole number on GHCi, it usually assumes its value is Integer?
Yes. Basically, GHCi will first try Integer
, then if that fails, Double
and then finally ()
to resolve ambiguous type constraints. You can read the details about how this works in the GHC User's Guide.
However, note that in compiled modules, the rules are a bit stricter. In particular, defaulting only applies to standard classes, so your example won't work without a type annotation in a compiled module unless you enable the ExtendedDefaultRules
extension which gives you the same behavior as GHCi.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With