2016-09-15 54 views
0

這是一個問題的修改的只是問一些分鐘前組件的元組 - 但這種情況下我的問題......如何使屬於一個類型的類的實例II

我有以下問題:我定義了一個類型類,並且想把這個類的元組聲明爲實例。但我不知道如何讓GHC接受這個聲明。這裏一個很簡單的例子:

class Test x a where 
    elm :: a 

而且知道元組我想要做這樣的事情

instance (Test x a, Test x b) => Test x (a,b) where 
    elm = (elm, elm) 

此外,我使用

{-# LANGUAGE MultiParamTypeClasses  #-} 
{-# LANGUAGE FlexibleInstances   #-} 

添加型x這裏引起的麻煩... 這是如何做到的?在此先感謝您的任何建議!

+1

它不能。如果我調用'elm :: Int',則無法知道它是否應該使用'instance Test Int Int'與'instance Test()Int'相比'instance Test FooType Int'。也許你應該提高抽象水平並詢問導致你走上這條道路的問題。 –

+0

這是一個壞消息......'elm'應該只提供這兩種類型中的一種的特殊元素。例如。 '實例測試一個Int其中elm = 0' ... – dmw64

回答

3

這與元組沒有任何關係。問題很簡單,x發生在班級負責人中,但不是elm的簽名 - 因此當您的代碼中的某處出現elm時,無法確定使用x類型的內容。

事實上,如果elmTest的唯一方法,那麼就沒有必要有x參數在所有 - 簡單地刪除它,您的實例將被罰款:

class Test a where 
    elm :: a 
instance (Test a, Test b) => Test (a,b) where 
    elm = (elm, elm) 

更有可能的是,你居然有沒有使用x一些其他的方法,比如

class Test x a where 
    elm :: a 
    beech :: x -> a 

在這種情況下,它可能是有意義的分解出elm成一個簡單的超:

class PreTest a where 
    elm :: a 
class (PreTest a) => Test x a where 
    beech :: x -> a 

或者,您可以通過其他方式獲取x信息,而不是通過方法的簽名。這可以用fundep來完成:

{-# LANGUAGE FunctionalDependencies #-} 
class Test x a | a->x where 
    elm :: a 

這表明只能有一個確切實例Test _ a任何類型a,因此編譯器可以明確地從中推斷x

但是我非常懷疑你並不是真的想要這樣 - 這樣的類比完整的雙參數類靈活得多。現代Haskell傾向於贊成與fundep MultiParamTypeClasses相比的基本上等效的關聯類型同義詞,並且當xa實際上是兩個獨立參數時,它們大多使用MTPC。

+0

非常感謝!是的,分解聲音非常好 - 我會嘗試我的真實例子(一個字段向量空間的類型類型)!(其實,我雖然關於使用FunctionalDependencies,但這確實不是我想要的!) – dmw64

相關問題