Hi, I have a problem with quantified constraints not working as I think they should do. Consider the following typeclass
class Monad m => MonadStoreTrans c k f m | m -> f, m -> k, k -> c where
type InitialStoreInfo m
liftTask :: f a -> m a
lookupTaskResult :: c a => k a -> m (Maybe a)
saveTaskResult :: c a => k a -> a -> m ()
runStoreTrans :: InitialStoreInfo m -> m a -> f a
It describes a monad transformer with added ability of looking up keys k a -> a
and saving them in store. I have one HashMap-based implementation, which works fine:
instance
( Monad m
, TaskPipeline k
, TestEquality k
, forall a. Hashable (k a)
, c ~ TaskValueConstraint k
) => MonadStoreTrans c k m (NonPersistentStoreT k m) where
Ignoring other constraints, I have a quantified constraint forall a. Hashable (k a)
, which allows me to call hash
on any key k a
supplied in functions lookupTaskResult
and saveTaskResult
.
I wanted to have another instance of MonadStoreTrans
, describing a logging transformer on top of other transformer:
instance
( MonadStoreTrans c k f n
, forall a. Show (k a)
, forall a. c a => Show a
) => MonadStoreTrans c k f (LoggingStoreT n) where
However, this time the quantified constraint forall a. Show (k a)
doesnât work (while the second one forall a. c a => Show a
works). When I try to show a key k a
supplied to one of the functions, I get an error
⢠Could not deduce (Show (k a)) arising from a use of âshowâ
from the context: (MonadStoreTrans c k f n, forall a. Show (k a),
forall a. c a => Show a)
bound by the instance declaration
at /home/mateusz/testing-framework/src/Testing/Store/LoggingTrans.hs:(27,3)-(30,46)
or from: c a
bound by the type signature for:
lookupTaskResult :: forall a.
c a =>
k a -> LoggingStoreT n (Maybe a)
at /home/mateusz/testing-framework/src/Testing/Store/LoggingTrans.hs:35:3-18
⢠In the first argument of â(<>)â, namely âshow keyâ
In the second argument of â(<>)â, namely
âshow key <> " as " <> show valâ
In the second argument of â($)â, namely
â"Found cached key: " <> show key <> " as " <> show valâtypecheck(-Wdeferred-type-errors)
My gut tells me there is something in play with instance resolution, as adding the same constraint to the previous declaration (without âbasicâ constraint MonadStoreTrans c k f n
) works just fine. Any ideas how to make it work?