2011-03-11 87 views
1

我想重用像下面的一些代碼:類型類的多態實例實例化

 
instance ToJavascript j => YesodTemplate j where toBuilder = toJavascript 

這需要使用重疊包裹的情況下,等於是我見過的解決方案是使用的包裝。

 
newtype Wrapped a = Wrapped { unwrapped :: using a } 
instance ToJavascript j => YesodTemplate (Wrapped j) j where 
    toBuilder = toJavascript 

我有多餘的未包裝的J有那麼默認功能的數據聲明,我可以寫模板類爲

 
class YesodTemplate yt inner where 
    toBuilder :: inner -> Builder 
    file :: (inner -> yt) -> FilePath -> Q Exp 
    file wrap fp = readFileQ fp >>= stringToTH wrap 

的包裝功能是滿足類型系統的虛擬。 但是,這仍然不會編譯。

 
juliusFile :: FilePath -> Q Exp juliusFile = file (Wrapped :: ToJavascript j => j -> Wrapped j) Ambiguous type variable `inner1' in the constraint: (ToJavascript inner1) arising from an expression type signature Probable fix: add a type signature that fixes these type variable(s) In the first argument one of `file', namely `(Wrapped :: ToJavascript j => j -> Wrapped j)' In the expression: file (Wrapped :: ToJavascript j => j -> Wrapped j) In an equation for `juliusFile': juliusFile = file (Wrapped :: ToJavascript j => j -> Wrapped j) 
+1

模板haskell問題是一個紅鯡魚的位。如果沒有模板haskell,你應該能夠獲得你關心的所有類型錯誤,然後能夠更合理地推理它們。使用'-ddump-splices'標誌來查看生成的TH。 – sclv 2011-03-11 22:28:14

+0

當我使用-ddump-splices運行它時,它不會提供比編譯器已經提供給我更多有用的信息 - 它已經給出問題發生的位置。但是,是的,問題在於我對類型的推理,而不是TH。之前我還沒有創建過這類複雜類型的東西。 – 2011-03-11 23:56:27

+1

如果你可以發佈一些蒸餾掉的模板haskell免費的代碼並說明了你的問題,那麼思考和可能的幫助會更加直接。 – sclv 2011-03-12 00:14:57

回答

0

感謝大家的幫助和鼓勵!

我最終做了什麼,而不是使用包裝的實例,是使用數據聲明與默認功能,可以被覆蓋。這種方法更清潔,因爲沒有包裝和虛擬變量 - 我認爲斯蒂芬是正確的,原來的方法不是什麼haskell/GHC的。