2013-01-24 101 views
4

我在我的代碼中有類似這個類。對於我的情況來說,添加一個'作爲Foo類的另一個參數是沒有意義的。模式匹配類型同義詞/類型內部類型參數同義詞

class Foo a where 
    type FCtx a a' :: Constraint 
    type FCtx a a' =() 

    f :: (FCtx a a') => a -> a' 

data D b = D b 

instance (Integral b) => Foo (D b) where 
    -- the next line does not compile because b' does not appear on the LHS 
    type FCtx (D b) a' = (a' ~ D b', Integral b') 

    f (D x) = D $ fromIntegral x 

對於這個具體Foo情況下,我想a'以這種方式有關。我想出的唯一辦法,使這項工作是通過增加一個「虛擬」類與「明顯的」類型同義詞:

class DClass d where 
    type DType d 

instance DClass (D b) where 
    type DType (D b) = b 

Foo實例現在變成了:

instance (Integral b) => Foo (D b) where 
    type FCtx (D b) a' = (a' ~ D (DType a'), Integral (DType a')) 
    f (D x) = D $ fromIntegral x 

的問題是我不得不爲我的特定數據類型創建一個完整的類(和實例),只是爲了表示(D b)確定b的類型同義詞/函數依賴關係。我不會有這個類的任何其他實例,因爲我總是想要DType a'意味着類型參數爲D b

我想什麼做的卻是這樣的:

type DParam (D b) = b 

instance (Integral b) => Foo (D b) where 
    type FCtx (D b) a' = (a' ~ D (DParam a'), Integral (DParam a')) 
    f (D x) = D $ fromIntegral x 

或者甚至某些表達這種約束,而無需使用類型同義詞,在所有的更好的方式。看起來很愚蠢,我應該被迫創建一個類型爲同一個實例的(開放)類來完成這個任務,並且不安全的是其他人可能會創建我不打算的新實例。

至少,是否沒有將類型/實例DClass轉換爲「模式匹配類型同義詞」的一些規範方法?

+0

您可以隨時不能導出您所做的類型類。 – Satvik

+0

這是真的。我只是在尋找一個更輕的解決方案。 – crockeea

+1

如果我沒有記錯,無論類型類是否在導出列表中,它們都會被導出。 – vivian

回答

5

稍微重量更輕,使用類型系列:

type family DParam d :: * 
type instance DParam (D b) = b 

不知道你是否能做得更好現在...