Reputation: 1437
The type of the expression random (mkStdGen 0)
is Random a => (a, StdGen)
, so I tried:
System.Random> random (mkStdGen 0) :: (Int, StdGen)
(9106162675347844341,1346387765 2103410263)
System.Random> random (mkStdGen 0) :: (Double, StdGen)
(0.9871468153391151,1346387765 2103410263)
But, why does the following work?
System.Random> random (mkStdGen 0)
(9106162675347844341,1346387765 2103410263)
How was it able to "guess" a type in this case?
Upvotes: 1
Views: 147
Reputation: 153102
From the Haskell Report:
Ambiguities in the class
Num
are most common, so Haskell provides another way to resolve them—with a default declaration:default (t1 , … , tn)
where n ≥ 0, and eachti
must be a type for whichNum ti
holds. In situations where an ambiguous type is discovered, an ambiguous type variable,v
, is defaultable if:
v
appears only in constraints of the formC v
, whereC
is a class, and- at least one of these classes is a numeric class, (that is,
Num
or a subclass ofNum
), 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 thePrelude
.)Each defaultable variable is replaced by the first type in the default list that is an instance of all the ambiguous variable’s classes. It is a static error if no such type is found.
Only one default declaration is permitted per module, and its effect is limited to that module. If no default declaration is given in a module then it assumed to be:
default (Integer, Double)
This almost explains the behavior, except that the class Random
in the constraint Random a
is not a subclass of Num
from the Prelude
; to explain this, we must consult the GHC documentation:
At the GHCi prompt, or with GHC if the
-XExtendedDefaultRules
flag is given, the following additional differences apply:
Rule 2 above [ed. note: this is the third rule in our list above] is relaxed thus: All of the classes
Ci
are single-parameter type classes.Rule 3 above [ed. note: this is the second rule in our list above] is relaxed this [sic]: At least one of the classes
Ci
is numeric, or isShow
,Eq
, orOrd
.The unit type
()
is added to the start of the standard list of types which are tried when doing type defaulting.
And now we're a bit closer to an explanation, except that it seems that the second bullet point still isn't satisfied: Random
is neither numeric nor one of the three listed acceptable alternatives. BUT ghci implicitly adds a call to print
for non-IO
actions (and even for IO
actions first tries adding a call to print
to see if things will type-check, falling back on the non-print
ing version only when that fails), and as a result we get an additional Show a
constraint hidden in the type of our expression, and this finally explains why the defaulting rules may be used. Since there is no instance of Random
for ()
, the default falls through to Integer
.
Upvotes: 5