2011-04-01 39 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) 

但是你不能使用任何旧的同构。这是一个耻辱。