Error while compiling print Either value - haskell

I'm trying to compile simple code snippet.
main = (putStrLn . show) (Right 3.423)
Compile results in the following error:
No instance for (Show a0) arising from a use of `show'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 42 others
In the second argument of `(.)', namely `show'
In the expression: putStrLn . show
In the expression: (putStrLn . show) (Right 3.423)
When i execute same snippet from ghci everything works as expected.
Prelude> let main = (putStrLn . show) (Right 3.423)
Prelude> main
Right 3.423
So the question is what is going on?

The problem is that GHC can't determine what the full type of Right 3.423 is, it can only determine that it has the type Either a Double, and the instance of Show for Either looks like instance (Show a, Show b) => Show (Either a b). Without that extra constraint on Either a Double, GHC doesn't know how to print it.
The reason why it works in interactive mode is because of the dreaded monomorphism restriction, which makes GHCi more aggressive in the defaults it chooses. This can be disabled with :set -XNoMonomorphismRestriction, and that is going to become the default in future versions of GHC since it causes a lot of problems for beginners.
The solution to this problem is to put a type signature on Right 3.423 in your source code, like
main = (putStrLn . show) (Right 3.423 :: Either () Double)
Here I've just used () for a, since we don't care about it anyway and it's the "simplest" type that can be shown. You could put String or Int or Double or whatever you want there, so long as it implements Show.
A tip, putStrLn . show is exactly the definition of print, so you can just do
main = print (Right 3.423 :: Either () Double)
As #ØrjanJohansen points out, this is not the monomorphism restriction, but rather the ExtendedDefaultRules extension that GHCi uses, which essentially does exactly what I did above and shoves () into type variables to make things work in the interactive session.

Related

Why such different behaviour with `Ambiguous type..` error (in ghci)?

This example works with ghci, load this file:
import Safe
t1 = tailMay []
and put in ghci:
> print t1
Nothing
But if we add analogous definition to previous file, it doesn't work:
import Safe
t1 = tailMay []
t2 = print $ tailMay []
with such error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show Ordering -- Defined in `GHC.Show'
instance Show Integer -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 22 others
That is 3rd sample for ghc with the same error:
import Safe
t1 = tailMay
main = do
print $ t1 []
print $ t1 [1,2,3]
Why? And how to fix the second sample without explicit type annotation?
The issue here is that tailMay [] can generate an output of type Maybe [a] for any a, while print can take an input of type Maybe [a] for any a (in class Show).
When you compose a "universal producer" and a "universal consumer", the compiler has no idea about which type a to pick -- that could be any type in class Show. The choice of a could matter since, in principle, print (Nothing :: Maybe [Int]) could print something different from print (Nothing :: Maybe [Bool]). In this case, the printed output would be the same, but only because we are lucky.
For instance print ([] :: [Int]) and print ([] :: [Char]) will print different messages, so print [] is ambiguous. Hence, GHC reject it, and requires an explicit type annotation (or a type application # type, using an extension).
Why, then, such ambiguity is accepted in GHCi? Well, GHCi is meant to be used for quick experiments, and as such, as a convenience feature, it will try hard to default these ambiguous a. This is done using the extended defaulting rules, which could (I guess) in principle be turned on in GHC as well by turning on that extension.
This is, however, not recommended since sometimes the defaulting rule can choose some unintended type, making the code compile but with an unwanted runtime behavior.
The common solution to this issue is using an annotation (or # type), because it provides more control to the programmer, makes the code easier to read, and avoids surprises.

Why do I get an ambiguous occurrence error when I define an instance?

I have a type Foo and want to make it an instance of Show, so that I can use it in GHCi:
data Foo = Foo
instance Show Foo where
show Foo = "Foo"
However, when I try to use it, I get an ambiguous occurrence error:
ghci> show Foo
<interactive>:4:1:
Ambiguous occurrence `show'
It could refer to either `Main.show', defined at Foo.hs:4:1
or `Prelude.show',
imported from `Prelude' at Foo.hs:1:1
(and originally defined in `GHC.Show')
Why? I just defined the function that belongs to a typeclass, didn't I?
TL;DR: Indent your instance bindings.
Enable warnings and you will notice that you didn't implement the instance operation show, but instead a new function with the same name:
Foo.hs:3:10: Warning:
No explicit implementation for
either `showsPrec' or `Prelude.show'
In the instance declaration for `Show Foo'
Therefore there are now two shows. Main.show (the one you've just accidentally defined) and Prelude.show (the one by the class you've wanted to use).
We can verify that by looking at their types (although we need to fully qualify their names):
ghci> :t Main.show
Main.show :: Foo -> [Char]
ghci> :t Prelude.show
Prelude.show :: Show a => a -> String
That's because your where bindings need to be indented, just like you would indent them in a usual function. Even a single space is enough:
instance Show Foo where
show Foo = "Foo"
Remember, Haskell uses whitespace to delimit blocks. Just ask yourself: when would the where stop otherwise?

In GHCi, why can't I show `pure 1` in REPL?

I tried to assign a lifted value to a.
λ> :m Control.Applicative
λ> let a = pure 1
When I evaluated a in REPL, it prints 1.
λ> a
1
Therefore, I thought there may be an implementation of show for a, and tried this:
λ> show a
But the GHCi throws an error:
<interactive>:70:1-4:
No instance for (Show (f0 a0)) arising from a use of ‘show’
The type variables ‘f0’, ‘a0’ are ambiguous
Note: there are several potential instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Show a, Show b) => Show (a, b) -- Defined in ‘GHC.Show’
instance (Show a, Show b, Show c) => Show (a, b, c)
-- Defined in ‘GHC.Show’
...plus 32 others
In the expression: show a
In an equation for ‘it’: it = show a
Does anyone have any ideas about this?
GHCi is defaulting the Applicative f => f to IO. When you do
λ> a
1
you actually run an IO Integer action such as
λ> let a = return 1
λ> a
1
GHCi by default prints the result of IO actions. Hence the 1 in the result line. (Quite confusingly, this 1 is not the value of a, nor the output of running a as an IO action -- just the returned value of the latter.)
GHCi uses a sophisticated heuristics to handle user input. First, it tries to show it, possibly defaulting some type classes like numeric ones. This fails in your case. When that fails, it tries to see if the input is an IO action. In such case, the action is run and, if the result can be showed, it is printed.
Note that this GHCi magic only happens at the top level.
When you try to show a, GHCi tries its magic on the whole show a, not on a, so the same effect does not happen.

How to work around issue with ambiguity when monomorphic restriction turned *on*?

So, learning Haskell, I came across the dreaded 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's a bunch of material about this, e.g. here, and it is not so hard to workaround.
I can either add an explicit type signature for f, or I can turn off the monomorphic restriction (with ":set -XNoMonomorphismRestriction" directly in ghci, or in a .ghci file).
There's some discussion about the monomorphic restriction, but it seems like the general advice is that it is ok to turn this off (and I was told that this is actually off by default in newer versions of ghci).
So I turned this off.
But then I came across another issue:
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 example code in the 'Real World Haskell' book, which wasn't working for me, and which you can find on this page: http://book.realworldhaskell.org/read/monads.html (it's the Monads chapter, and the getRandom example function, search for 'getRandom' on that page).
If I leave the monomorphic restriction on (or turn it on) then the code works. It also works (with the monomorphic restriction on) if I change it to:
Prelude> let (a,_) = System.Random.random (System.Random.mkStdGen 4) in a :: Int
-106546976
or if I specify the type of 'a' earlier:
Prelude> let (a::Int,g) = System.Random.random (System.Random.mkStdGen 4) in a :: Int
-106546976
but, for this second workaround, I have to turn on the 'scoped type variables' extension (with ":set -XScopedTypeVariables").
The problem is that in this case (problems when monomorphic restriction on) neither of the workarounds seem generally applicable.
For example, maybe I want to write a function that does something like this and works with arbitrary (or multiple) types, and of course in this case I most probably do want to hold on to the new generator state (in 'g').
The question is then: How do I work around this kind of issue, in general, and without specifying the exact type directly?
And, it would also be great (as a Haskell novice) to get more of an idea about exactly what is going on here, and why these issues occur..
When you define
(a,g) = random (mkStdGen 4)
then even if g itself is always of type StdGen, the value of g depends on the type of a, because different types can differ in how much they use the random number generator.
Moreover, when you (hypothetically) use g later, as long as a was polymorphic originally, there is no way to decide which type of a you want to use for calculating g.
So, taken alone, as a polymorphic definition, the above has to be disallowed because g actually is extremely ambiguous and this ambiguity cannot be fixed at the use site.
This is a general kind of problem with let/where bindings that bind several variables in a pattern, and is probably the reason why the ordinary monomorphism restriction treats them even stricter than single variable equations: With a pattern, you cannot even disable the MR by giving a polymorphic type signature.
When you use _ instead, presumably GHC doesn't worry about this ambiguity as long as it doesn't affect the calculation of a. Possibly it could have detected that g is unused in the former version, and treated it similarly, but apparently it doesn't.
As for workarounds without giving unnecessary explicit types, you might instead try replacing let/where by one of the binding methods in Haskell which are always monomorphic. The following all work:
case random (mkStdGen 4) of
(a,g) -> a :: Int
(\(a,g) -> a :: Int) (random (mkStdGen 4))
do (a,g) <- return $ random (mkStdGen 4)
return (a :: Int) -- The result here gets wrapped in the Monad

Can Either be used for a kind of simple polymorphism?

I tried writing a simple function that takes an Either type (possibly parameterized by two different types) and does one thing if it gets Left and another thing if it gets Right. the following code,
someFunc :: (Show a, Show b) => Either a b -> IO ()
someFunc (Left x) = print $ "Left " ++ show x
someFunc (Right x) = print $ "Right " ++ show x
main = do
someFunc (Left "Test1")
someFunc (Right "Test2")
However, this gives,
Ambiguous type variable `b0' in the constraint:
(Show b0) arising from a use of `someFunc'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' expression: someFunc (Left "Test1")
and
Ambiguous type variable `a0' in the constraint:
(Show a0) arising from a use of `someFunc'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: someFunc (Right "Test2")
If I understand correctly, when I call the function with Left x, it is complaining because it doesn't know the type of the Right x variant, and vice-versa. However, this branch of the function is not used. Is there a better way to do this?
You can make this work by explicitly specifying the other type:
main = do
someFunc (Left "Test1" :: Either String ())
someFunc (Right "Test2" :: Either () String)
but I agree with x13n that this probably isn't the best way to do whatever you're trying to do. Note that someFunc is functionally identical to
someFunc :: (Show a) => Bool -> a -> IO ()
someFunc False x = print $ "Left " ++ show x
someFunc True x = print $ "Right " ++ show x
because the only information you derive from the structure of the Either is whether it's a Left or Right. This version also doesn't require you to specify a placeholder type when you use it.
This is a good question, because it made me think about why Haskell behaves this way.
class PseudoArbitrary a where
arb :: a
instance PseudoArbitrary Int where
arb = 4
instance PseudoArbitrary Char where
arb = 'd'
instance PseudoArbitrary Bool where
arb = True
reallyDumbFunc :: (PseudoArbitrary a, PseudoArbitrary b) =>
Either a b -> Either a b
reallyDumbFunc (Left x) = Right arb
reallyDumbFunc (Right x) = Left arb
So check this out. I've made a typeclass PseudoArbitrary, where instances of the typeclass provide a (pseudo-)arbitrary element of their type. Now I have a reallyDumbFunction that takes an Either a b, where both a and b have PseudoArbitrary instances, and if a Left was put in, I produce a Right, with a (pseudo-)arbitrary value of type b in it, and vice versa. So now let's play in ghci:
ghci> reallyDumbFunc (Left 'z')
Ambiguous type variable blah blah blah
ghci> reallyDumbFunc (Left 'z' :: Either Char Char)
Right 'd'
ghci> reallyDumbFunc (Left 'z' :: Either Char Int)
Right 4
Whoa! Even though all I changed was the type of the input, it totally changed the type and value of the output! This is why Haskell cannot resolve the ambiguity by itself: because that would require analyzing your function in complicated ways to make sure you are not doing things like reallyDumbFunc.
Well, that depends heavily on what you are trying to do, doesn't it? As you already found out, in order to use Left constructor, you need to know the type it constructs. And full type requires information on both a and b.
Better way to achieve polymorphism in Haskell is to use type classes. You can easily provide different implementations of "methods" for different instances.
Good comparison of both object-orientation and type classes concepts can be found here.

Resources