I want to reuse some code like the following:
instance ToJavascript j => YesodTemplate j where toBuilder = toJavascript
This requires overlapping using wrapped instances , etc. So the solution I have seen is to use a wrapper.
newtype Wrapped a = Wrapped { unwrapped :: using a }
instance ToJavascript j => YesodTemplate (Wrapped j) j where
toBuilder = toJavascript
I have the extra unwrapped j in there so data declaration with default functions that I can write the template class as
class YesodTemplate yt inner where toBuilder :: inner -> Builder file :: (inner -> yt) -> FilePath -> Q Exp file wrap fp = readFileQ fp >>= stringToTH wrap
The wrap function is a dummy to satisfy the type system. But this still won't compile.
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)
-ddump-splicesflag to see the generated TH. - sclvinstance ToJavascript j => YesodTemplate j where ...to be a design flaw. I don't think the behavior of GHC is specified that the compiler will always choose the polymorphic instance or a type specialized instance defied elsewhere (maybe it chooses first defined?). There was a thread in Jan/Feb '11 on Haskell Cafe about it and I don't think anyone commented with a definitive description of what GHC should do or what it does do. The thread was named "Inheritance and Wrappers". - stephen tetley