考虑以下内容,该内容使用ScopedTypeVariables编写:
defaultGetRestView :: forall view master . ( PersistEntity (PersistentView master view) , PersistStore (YesodPersistBackend master (HandlerT master IO)) , MonadTrans (YesodPersistBackend master), YesodPersist master , PersistMonadBackend (YesodPersistBackend master (HandlerT master IO)) ~ PersistEntityBackend (PersistentView master view) ) => Key (PersistentView master view) -> HandlerT master IO view defaultGetRestView key = ((runDB $ get404 key) :: HandlerT master IO (PersistentView master view)) >>= (return . (view :: PersistentView master view -> view))
我遇到了一个我不明白的类型错误。我明确声明我正在调用的'view'函数是适用于(PersistentView主视图)的函数:
NB: `PersistentView' is a type function, and may not be injective
The type variable `master0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: PersistentView master view -> view
Actual type: PersistentView master0 view -> view
In the second argument of `(.)', namely
`(view :: PersistentView master view -> view)'
答案 0 :(得分:3)
“可能不是单射的”是错误的关键部分。也就是说,我们可能有平等
PersistentView master view ~ PersistentView master0 view
其中master
与master0
不同。由于这种非注入性,编写view :: PersistentView master view -> view
修复了用作返回类型(view
)的类型变量,但它没有修复master
类型变量,这仍然不明确。
视图函数的类型本质上看起来不明确,因为它无法修复master
类型变量的值。通常,会使用额外的伪参数,如:
view :: master -> PersistentView master view -> view
view _unused persistentView = ...
然后view (undefined::master) pv
会让人选择评估view
的类型。