2009-11-29 150 views
13

是否有方法可以轻松“提升”Haskell中的类实例?在Haskell中提升类实例

我已经经常需要创建,例如,对于一些类,只是“提升”的Num通过类型构造这样的结构民实例:

data SomeType a = SomeCons a 

instance (Num a)=>Num SomeCons a where 
    (SomeCons x) + (SomeCons y) = SomeCons (x+y) 
    negate (SomeCons x) = SomeCons (negate x) 
    -- similarly for other functions. 

是否有办法避免这种情况样板和自动“提升”这个Num结构?当我试图学习存储和编译器不会让我使用deriving(Show)时,我通常必须使用Show和其他类来做到这一点。

回答

19

广义NEWTYPE获得扩展你想要的这里:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

newtype SomeType a = SomeCons a deriving (Num, Show, Eq) 

main = do 
    let a = SomeCons 2 
     b = SomeCons 3 
    print $ a + b 

输出:

*Main> main 
SomeCons 5 
+1

呜呜......为什么这个工程与NEWTYPE但不能与数据? – 2009-11-29 22:29:39

+3

因为newtype不能添加任何构造函数或字段 - 它只是重新包装现有的类型。这可以确保扩展可以与任何类一起使用,而不仅仅是通常可以为任何数据类型派生的类。 – Martijn 2009-11-30 09:02:05

5

GHC实现你想要的:Extensions to the deriving mecanism。 这些修改常常表现出对未来的标准语言的扩展(如看到haskell' wiki

要启用这个扩展,你必须使用以下编译

{-# GeneralizedNewtypeDeriving #-} 

,然后在你的NEWTYPE声明中使用派生,如通常

data SomeType a = SomeCons a deriving (Num) 
1

GeneralizedNewtypeDeriving