Functions for different data constructors

I started learning Haskell a week ago and have one weird problem. I created a simple data type and want to show it in the console. I created 2 functions for 2 constructors of my type. The compiler can call the function if I use a constructor with two arguments. But it cannot call another function, which should catch the constructor with 1 argument.

module Main ( main ) where data MyContainter ab = FirstVersion ab | SecondVersion a deriving(Show,Eq) showContainer (FirstVersion ab) = 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 

Compilers report:

 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 he say that? I created (SecondVersion 1) directly and don’t understand why the compiler does not call showContainer (SecondVersion a).

+7
source share
1 answer

The problem is that showContainer is of type:

 showContainer :: (Show a, Show b) => MyContainer ab -> String 

But when you go through SecondVersion 1 , he does not know what b , because SecondVersion 1 works for any type of b ! When you pass in FirstVersion , it works fine, because since FirstVersion contains both a and b , there is never any ambiguity about what they should be.

So, since the compiler does not know what you need b , and does not know that choosing b does not affect showContainer (in the end, it affects the behavior when you pass FirstVersion , since it uses show for a value of type b ), it refuses.

What the error message says: a variable of type a0 1 is ambiguous, so 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 () :

 startF = showContainer (SecondVersion 1 :: MyContainer Integer ()) 

You probably don't often encounter such errors, since the context in which you use the values ​​usually results in the use of a specific b .

1 GHC, unfortunately, is not the best when choosing types of variables; if you gave showContainer explicit type signature, as I showed, then it would also use b in the error message.

+9
source

All Articles