2013-01-25 44 views
3

我想表達我有3個相關的類型類。用Haskell中的函數依賴表達類型關係

我有兩個文件。第一:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 
module ModA where 

class Class a b c | a -> b, b -> c where 
    getB :: a -> b 
    getC :: b -> c 

二:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 
module B where 

import qualified ModA 

data A = A {f1::String} 

data B = B {f2::String} 

data C = C {f3::String} 

instance ModA.Class A B C where 
    getB a = B "hey" 
    getC a = C "ho" 

getABForMe = ModA.getB (A "boo") 

getACForMe = ModA.getC (B "yo") 

的錯誤,我得到:

No instance for (ModA.Class a0 B C) 
    arising from a use of `ModA.getC' 
Possible fix: add an instance declaration for (ModA.Class a0 B C) 
In the expression: ModA.getC (B "yo") 
In an equation for `getACForMe': getACForMe = ModA.getC (B "yo") 

我缺少什麼?

回答

6

您可以進行函數依賴「通知」:

class Class a b c | a->b, b->c, c->a where 
    getB :: a -> b 
    getC :: b -> c 

因此,任何一種類型的參數,可以從任何其他的推斷。但我不確定你是否真的想要這個;爲什麼不用一個fundep和一個方法創建一個類型類,並創建它的兩個實例(instance Class A Binstance Class B C)?

+0

就是這樣!工作得很好,謝謝。關於爲什麼部分,我工作的真實代碼比這個小小的對稱例子更加涉及。這個圓形fundep解決方案算不算黑客? –

2

在調用getC時,GHC無法知道第一類參數a的類型。該呼叫修復bB類型,並且功能依賴性允許GHC推斷c必須是C。但沒有關於a的信息可用。

+0

我該如何解決這個問題呢? –