Consider the following, which is written in a context with 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))
I am having a type error I don't understand. I am explicitly declaring that the 'view' function that I'm calling is the one that applies to (PersistentView master view):
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)'
The "may not be injective" is the key part of the error. That is, we may have the equality
PersistentView master view ~ PersistentView master0 view
where master differs from master0. Because of this non-injectivity, writing view :: PersistentView master view -> view fixes the type variable used as a return type (view) but it does not fix the master type variable, which remains ambiguous.
The type for the view function looks inherently ambiguous, in that it allows no way to fix the value of the master type variable. Usually, an extra dummy argument is used for this, as in:
view :: master -> PersistentView master view -> view
view _unused persistentView = ...
Then view (undefined::master) pv would let one to choose the type at which to evaluate view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With