相关我之前关于遍历数据结构的问题 https://stackoverflow.com/questions/1855371/avoiding-boilerplate-when-dealing-with-many-unrelated-types,当我将代码与 uniplate 包一起使用时,我在使代码变得通用时遇到问题。我正在处理中的数据结构语言.扩展.注释.语法 http://hackage.haskell.org/packages/archive/haskell-src-exts/1.1.4/doc/html/Language-Haskell-Exts-Annotated-Syntax.html模块,它们都是带有类型参数的通用模块l
. This l
整个树都是一样的。
我正在编写的代码是这样的:
doInt :: Child1 l -> Child1 l
doInt (Child1 l n) = Child1 l (n + 1)
doString :: Child2 l -> Child2 l
doString (Child2 l (_:s)) = Child2 l ('j' : s)
replace :: Data l => Parent l -> Parent l
replace = transformBi doInt
. transformBi doString
此代码在最后两行都会产生以下错误:
Ambiguous type variable `l' in the constraint:
`Data l' arising from a use of `transformBi' at Test.hs:31:10-52
Probable fix: add a type signature that fixes these type variable(s)
我明白为什么这段代码不明确:transformBi
接受一个(to -> to)
and from
并将其变成from
;就我而言,两者之间没有联系l
in Child1 l
和l
in Parent l
。我不知道如何解决它。我尝试添加类型约束,例如transformBi (doInt :: Child1 l -> Child1 l)
,但我得到同样的错误;就好像我在介绍一个新的l
当我这样做的时候。
我如何告诉编译器我正在使用相同的l
for replace
, transformBi doInt
and transformBi doString
?
Edit: 这是演示我正在做的事情的完整程序 http://gist.github.com/251520。在GHC 6.10.4下,该程序无法编译,并出现上述错误。
看起来你需要作用域类型变量 http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#scoped-type-variables扩大。
{-# LANGUAGE ScopedTypeVariables #-}
replace :: forall l. Data l => Parent l -> Parent l
replace = transformBi (doInt :: Child1 l -> Child1 l)
. transformBi (doString :: Child2 l -> Child2 l)
注意量化must明确携带l
纳入范围。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)