So, while studying Haskell, I came across a terrible monomorphic restriction, soon enough, with the following (in ghci):
Prelude> let f = print.show Prelude> f 5 <interactive>:3:3: No instance for (Num ()) arising from the literal `5' Possible fix: add an instance declaration for (Num ()) In the first argument of `f', namely `5' In the expression: f 5 In an equation for `it': it = f 5
So there is a ton of material about this, for example. here , and it's not that hard to get around. I can either add an explicit type signature for f, or I can disable the monomorphic constraint (with ": set -XNoMonomorphismRestriction" directly in ghci or in the .ghci file).
In some discussions about the monomorphic constraint, but it seems like a general tip is that this is normally disabled (and I was told that it is really disabled by default in newer versions of ghci).
So, I turned it off.
But then I ran into another problem:
Prelude> :set -XNoMonomorphismRestriction Prelude> let (a,g) = System.Random.random (System.Random.mkStdGen 4) in a :: Int <interactive>:4:5: No instance for (System.Random.Random t0) arising from the ambiguity check for `g' The type variable `t0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance System.Random.Random Bool -- Defined in `System.Random' instance System.Random.Random Foreign.C.Types.CChar -- Defined in `System.Random' instance System.Random.Random Foreign.C.Types.CDouble -- Defined in `System.Random' ...plus 33 others When checking that `g' has the inferred type `System.Random.StdGen' Probable cause: the inferred type is ambiguous In the expression: let (a, g) = System.Random.random (System.Random.mkStdGen 4) in a :: Int In an equation for `it': it = let (a, g) = System.Random.random (System.Random.mkStdGen 4) in a :: Int
This is actually simplified from the example code in the book "Real World Haskell", which does not work for me, and which you can find on this page: http://book.realworldhaskell.org/read/monads.html (this is the Monads chapter and function getRandom example, find "getRandom" on this page).
If I leave a monomorphic restriction on (or turn it on), then the code works. It also works (with a monomorphic constraint) if I change it to:
Prelude> let (a,_) = System.Random.random (System.Random.mkStdGen 4) in a :: Int -106546976
or if I set type 'a' before:
Prelude> let (a::Int,g) = System.Random.random (System.Random.mkStdGen 4) in a :: Int -106546976
but for this second workaround, I have to enable the extension 'scoped type variables' (using :: set -XScopedTypeVariables).
The problem is that in this case (problems with a monomorphic restriction), none of the workarounds seems to be generally applicable.
For example, perhaps I want to write a function that does something like this and works with arbitrary (or several) types, and, of course, in this case, I most likely want to stay in the new state of the generator (in 'g') .
The question is: how can I get around this problem as a whole and without directly indicating the exact type?
And it would also be great (as a newcomer to Haskell) to get more information about what is going on here and why these problems arise.