简体   繁体   中英

Haskell - deriving show for polymorphic types

First off, my background is in C++, so try not to shoot me down 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 want a datatype that holds values of either type x , type y or neither. A variant of sorts of 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 an ambiguity? 1 in Cons1 1 is from what I understand a number, which all derive Show. The constructor itself, I thought, acted as a discriminator, making Cons1 1 /= Cons2 1 .

With Cons1 1 the compiler is only able to derive the x type in data T xy and has no way to infer y . x becomes Num a , but what about y ? You'll need to specify it manually in that case:

main = do
    let v = (Cons1 1 :: T Int Int) -- just an example
    putStrLn (show v)

In some cases, if you'll use explicit function types, the compiler will be able to infer it automagically. But in this case it really has no hints.

It's the same as Nothing being ambiguous on it's own. Is it Maybe String , Maybe Int , Maybe Double , ...?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM