2011-04-01 59 views
1

比方說,我有:轉換功能,使一些類型的類的實例

data MyType 
myToDouble :: MyType -> Double 

比方說,我想的MyType是民或實或某事的一個實例是雙已經是一個實例。

是否有一種簡單的方法可以完成該操作,而無需手動編寫Num/Real中的所有方法?

所以...有沒有的只是說某種方式:

instance Real MyType by way of myToDouble 

回答

5

非也; Real取決於NumNum有方法返回a(或更準確地說,是在a covariant)。你將如何實現:

(+) :: MyType -> MyType -> MyType 

只給定MyTypemyToDouble

現在,也許你已經擁有了所有其他實例,只是想知道Real。那麼,Real擁有的唯一方法就是自己的toRational,所以:

instance Real MyType where 
    toRational = toRational . myToDouble 

至於你更普遍的問題:不幸的是沒有。如果在類型變量中有一個類的方法都是逆變的(只能作爲參數),那麼你應該能夠在像這樣的投影中自動定義一個類型類。但Haskell沒有這樣做的機制。 (你可以使用Template Haskell自己寫一個)。

可以使用GeneralizedNewtypeDeriving將新類型的實例「轉發」到其基礎類型。例如。

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype MyType = MyType Double 
    deriving (Eq,Ord,Show,Num,Real) 

但是你不能使用任何舊的同構。這是一個恥辱。