Haskell - a show for polymorphic types
First, my background is in C ++, so try not to shoot me too hard.
In this contrived example, I'm trying to define a polymorphic type that looks like this:
data T x y
= Cons1 x
| Cons2 y
| Neither
deriving (Show)
I need a data type that contains values โโof any type x
, type, y
or none. View variant Maybe a
. When I try to do this:
main = do
let v = Cons1 1
putStrLn (show v)
some ambiguity arises:
No instance for (Show y0) arising from a use of `show'
The type variable `y0' is ambiguous
Note: there are several potential instances:
instance (Show x, Show y) => Show (T x y)
-- Defined at C:\Projects\Private\Haskell\Play\play.hs:14:27
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
...plus 25 others
In the first argument of `putStrLn', namely `(show t)'
In a stmt of a 'do' block: putStrLn (show t)
In the expression:
do { let t = Cons1 1;
putStrLn (show t) }
Why is this? Why is there ambiguity? 1
in Cons1 1
is what I understand, the number that Show all outputs. The constructor itself, as I thought, was acting as a discriminator when creating Cons1 1 /= Cons2 1
.
source to share
Since the Cons1 1
compiler can only infer the type x
in data T x y
and has no way to infer y
. x
becomes Num a
, but what about y
? In this case, you need to specify it manually:
main = do
let v = (Cons1 1 :: T Int Int) -- just an example
putStrLn (show v)
In some cases, if you use explicit function types, the compiler will be able to do this automatically. But in this case, he really has no hints.
This is the same thing that Nothing
is ambiguous on it. This Maybe String
, Maybe Int
, Maybe Double
, ...?
source to share