I started studying Haskell one week ago and have one strange problem. I created a simple data type and want to show it in a console. I created 2 functions for 2 constructors of my type. The compiler can call function if I use a constructor with 2 arguments. But it can’t call another function which should catch a constructor with 1 argument.
module Main (
main
) where
data MyContainter a b = FirstVersion a b
| SecondVersion a
deriving(Show,Eq)
showContainer (FirstVersion a b) = show b
showContainer (SecondVersion a) = show a
--startF = showContainer (FirstVersion 1 2) -- it works
startF = showContainer (SecondVersion 1) -- it doesn't work
main = putStr startF
The compilers tells:
Ambiguous type variable `a0' in the constraint:
(Show a0) arising from a use of `showMaybe'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: showMaybe (SecondVersion 1)
In an equation for `startF': startF = showMaybe (SecondVersion 1)
Why does it tell that? I created (SecondVersion 1) directly and don’t understand why the compiler doesn’t call showContainer (SecondVersion a).
The problem is that
showContainerhas the type:But when you pass
SecondVersion 1, it doesn’t know whatbis, becauseSecondVersion 1works for any type ofb! When you pass aFirstVersion, it works fine, because, asFirstVersioncontains both anaand ab, there’s never any ambiguity as to what they should be.So, since the compiler has no way of knowing what
byou want, and no way of knowing that the choice ofbdoesn’t affectshowContainer(after all, it does affect the behaviour when you passFirstVersion, since it usesshowon a value of typeb), it gives up.That’s what the error message is saying: the type variable
a01 is ambiguous, so please add a type signature to tell me what it is. In this case, it doesn’t matter what it is, so you can just set it to():You probably won’t run into errors like this very often, since the context you use the values in will usually force a specific
bto be used.1 GHC isn’t the best at picking type variables, unfortunately; if you gave
showContaineran explicit type signature like I showed, then it’d usebin the error message too.