2011-09-23 34 views
8

我只是好奇,爲什麼我寫這個,解釋爲 「非法類型同義詞家庭」

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl γ where 
    var = varhz 

instance (HzMonad , Data.Suitable.Suitable α) => VarDecl (ExprTyp α) where 
    var = varhz 

-- error 
Hz2/Language.hs:114:53: 
    Illegal type synonym family application in instance: ExprTyp α 
    In the instance declaration for `VarDecl (ExprTyp α)' 

其中

varhz :: 
    (HzMonad , Data.Suitable.Suitable α) => 
    String -> ExprTyp α -> (ExprTyp α) 

是什麼,而不是反正呢?非常感謝。

+3

我沒有能量(今晚)來輸入完整的答案,但簡單的答案是,這是另一個根深蒂固的假設類型級別事物被認爲是錯誤的例子家庭被添加到混合。代字號是一個類型相等斷言。 –

+0

啊,我現在明白了,沒問題。謝謝你的提示。如何解決這個問題是另一個故事,我仍然試圖弄清楚。 – gatoatigrado

回答

2

我認爲這個問題是對 => 右側的一切必須是一個類型構造或類型變量。 ExprTyp可以指多個不同類型的構造函數。用等號約束代替它確實可行,但由此產生的實例將毫無用處,因爲編譯器將無法推斷出關於γ的任何內容,因爲它是ExprTyp - ExprTyp可能會被別名化。

在我的情況 - 我試圖寫一個DSL單子 - 解決方案是在新類型的構造函數中包裝關聯類型的所有用法。例如,如果我們開始用,

class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprTyp m a -> m() 

然後包裹這將導致

newtype ExprT a = ExprT a 
class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprT (ExprTyp m a) -> m() 

然後,例如,變量聲明(我寫了tupled變量聲明代碼)可能是,

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl (ExprT γ) 
instance (Monad , VarDecl α, VarDecl β) => VarDecl (α, β) 

如果有不明之處,請發表評論。