2014-11-01 49 views
1

考虑以下数据类型:数据构造 - 同种

data JoinList m a = Empty 
        | Single m a 
        | Append m (JoinList m a) (JoinList m a) 
    deriving (Eq, Show) 

使用ghci,我所做的:

*JoinList> :t Single 5 3 
Single 5 3 :: (Num m, Num a) => JoinList m a 

为什么在这里需要两个Num类型?由于这两种类型都Num,那么我们为什么不能有:

Single 5 3 :: (Num m) => JoinList m m

+0

'Num'是一个类,不是数据类型。 'Int'是一个实例,'Float'也是一个实例。两个实例不一定是相同的。 – 2014-11-01 01:05:31

+2

简短的回答是:由于同样的原因,在您的ADT中有两个类型变量有两个Num约束。 – 2014-11-01 01:15:18

回答

5

它不是一个给定的他们是同一类型。

您允许类型在JoinList的定义中有所不同,并且您没有声明5和3是类型签名中相同的Num。

GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Prelude> :l joinlist.hs 
[1 of 1] Compiling JoinList   (joinlist.hs, interpreted) 
Ok, modules loaded: JoinList. 
Prelude> :t Single 5 3 
Single 5 3 :: (Num a, Num m) => JoinList m a 
Prelude> let same = Single 5 3 :: Num a => JoinList a a 
Prelude> :t same 
same :: Num a => JoinList a a 

由于文字是多态的Num值,它们可能是引擎盖下的两种不同的具体类型。

Prelude> let diff = Single 5 3 :: JoinList Int Float 
Prelude> diff 
Single 5 3.0 
Prelude> :t diff 
diff :: JoinList Int Float