2011-03-11 57 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的。