Haskell - 派生出多态类型

时间:2014-12-03 21:11:02

标签: haskell

首先,我的背景是用C ++编写的,所以尽量不要太用力地击打我。

在这个人为的例子中,我试图定义一个如下所示的多态类型:

data T x y
    = Cons1 x
    | Cons2 y
    | Neither
    deriving (Show)

我想要一个数据类型,其中包含x类型的值,类型y或两者都没有。各种Maybe a的变体。当我尝试这样做时:

main = do
    let v = Cons1 1
    putStrLn (show v)

出现了一些含糊之处:

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) }

这是为什么?为什么会有歧义? 1中的Cons1 1来自我所理解的数字,这些数字都来自Show。我认为,构造函数本身就是一个鉴别器,正在制作Cons1 1 /= Cons2 1

1 个答案:

答案 0 :(得分:4)

使用Cons1 1,编译器只能在x中派生data T x y类型,无法推断yx变为Num a,但是y呢?在这种情况下,您需要手动指定它:

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

在某些情况下,如果您使用显式函数类型,编译器将能够自动推断它。但在这种情况下,它确实没有任何提示。

Nothing对其自身含糊不清的情况相同。是Maybe StringMaybe IntMaybe Double,......?