{-# LANGUAGE Haskell2010 #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
class PoC m where
type Wrapper m :: * -> *
wrap :: l -> Wrapper m l
我正在使用haskell-src-exts,我想升级我的AST以获得新生成的标签。由于我想以可扩展的方式进行,我创建了一个类似上面代码的界面。但是,升级AST的代码不起作用。我有以下内容:
upgrade :: forall f m l. (PoC m, Functor f) => f l -> f (Wrapper m l)
upgrade x = fmap (wrap :: l -> Wrapper m l) x
但无论是否使用ScopedTypeVariables
,我都会遇到同样的错误:
/tmp/PoC.hs:10:19:
Could not deduce (Wrapper m ~ Wrapper m0)
from the context (PoC m, Functor f)
bound by the type signature for
upgrade :: (PoC m, Functor f) => f l -> f (Wrapper m l)
at /tmp/PoC.hs:9:12-69
NB: `Wrapper' is a type function, and may not be injective
The type variable `m0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: l -> Wrapper m0 l
Actual type: l -> Wrapper m l
In the first argument of `fmap', namely
`(wrap :: l -> Wrapper m l)'
In the expression: fmap (wrap :: l -> Wrapper m l) x
In an equation for `upgrade':
upgrade x = fmap (wrap :: l -> Wrapper m l) x
但我不明白GHC在哪里绑定m0
。这可能是“可能不是单一的”问题的核心吗?
答案 0 :(得分:2)
事实上,非注入性是一个问题。 Injectivity将允许GHC知道如果f a ~ f b
然后a ~ b
,但由于您可以有两个PoC m
个实例,并且Wrapper m
类型的选择相同,因此很难知道{{1}你解决了m
之后的问题。
您应该可以通过向Wrapper m
添加包含wrap
类型参数的输入词来修复它。这可以是从不评估的代理参数
m