GHC类型函数和作用域类型变量

时间:2014-05-01 19:22:37

标签: haskell

考虑以下内容,该内容使用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)'

1 个答案:

答案 0 :(得分:3)

“可能不是单射的”是错误的关键部分。也就是说,我们可能有平等

PersistentView master view ~ PersistentView master0 view

其中mastermaster0不同。由于这种非注入性,编写view :: PersistentView master view -> view修复了用作返回类型(view)的类型变量,但它没有修复master类型变量,这仍然不明确。

视图函数的类型本质上看起来不明确,因为它无法修复master类型变量的值。通常,会使用额外的伪参数,如:

view :: master -> PersistentView master view -> view
view _unused persistentView = ...

然后view (undefined::master) pv会让人选择评估view的类型。