2017-03-23 50 views
1

我目前得到的代碼下面這個模式:從多個實例中移除重複報關單

f1' x1 x2 .. xm1 = ... 
f2' x1 x2 .. xm2 = ... 
. 
. 
, 
fn' x1 x2 .. xmn = ... 

instance C D1 where 
    f1 = f1' 
    f2 = f2' 
    . 
    . 
    . 
    fn = fn' 

instance C D2 where 
    f1 = f1' 
    f2 = f2' 
    . 
    . 
    . 
    fn = fn' 

. 
. 
. 

instance C DN where 
    f1 = f1' 
    f2 = f2' 
    . 
    . 
    . 
    fn = fn' 

基本上,我已經得到了我想要實現的一些數據類型的一類,但所有這些實現一樣。但是在實例實現中有很多重複代碼,對於m函數和n實例,我必須編寫大致O(m*n)代碼行,我寧願它更像O(m+n)

有沒有一種很好的方法來消除重複?我想像模板哈斯克爾會做的伎倆,但我不想重新發明輪子,如果處理這個問題已經存在。

+1

如果他們都是一樣的,你就不能提供默認的實現? – Zeta

+0

我不能那麼傷心,我不控制這個類(在我的例子中'C'實際上是'Enum')。 – Clinton

+2

不是抽象的例子,你可以添加兩個類型以及你的函數嗎? – Zeta

回答

0

您可以爲您的課程提供默認實現。就拿Functor例如:

class Functor f where 
    fmap  :: (a -> b) -> f a -> f b 

    -- | Replace all locations in the input with the same value. 
    -- The default definition is @'fmap' . 'const'@, but this may be 
    -- overridden with a more efficient version. 
    (<$)  :: a -> f b -> f a 
    (<$)  = fmap . const 

您也可以選擇爲deriving選項,你可以發現這個問題的更多信息:How does deriving work in Haskell?有關於如何控制deriving一些信息。

+0

C是不是我的課程只有實例是我的 – Clinton

+0

是派生一個選項? – mathk

0

也許你可以先創建另一個空類型的類:

instance SomeD D1 
-- ... 
instance SomeD DN 

然後讓:

class SomeD 

然後使用每種類型一行使各類SomeDD1 ... DN實例SomeD typeclass的任何實例C如下所示:

instance (SomeD t) => C t where 
    f1 = f1' 
    -- ... 
    fn = fn' 

(我不知道這是否正常工作,或者如果它需要一些語言擴展,可惜我現在不能測試它。)

+0

這不起作用,並沒有真正允許它的擴展。唯一可行的是,如果沒有其他'C'的實現。是的,你可以讓它編譯,但是當你嘗試使用它時,一切都變得混亂。 – luqui