Running the following command in GHCi gives an interesting error message
λ> :t (command @'[Member] "test" $ \(_ctx :: FullContext) _ -> pure ())
<interactive>:1:2: error:
• Could not deduce (Calamity.Commands.Context.CalamityCommandContext
c0)
arising from a use of ‘command’
from the context: (Polysemy.Internal.Union.Find
(Polysemy.Final.Final IO) r,
Polysemy.Internal.Union.Find Calamity.Cache.Eff.CacheEff r,
Polysemy.Internal.Union.LocateEffect (Polysemy.Final.Final IO) r
~ '(),
Polysemy.Internal.Union.LocateEffect Calamity.Cache.Eff.CacheEff r
~ '())
bound by the inferred type of
it :: (Polysemy.Internal.Union.Find (Polysemy.Final.Final IO) r,
Polysemy.Internal.Union.Find Calamity.Cache.Eff.CacheEff r,
Polysemy.Internal.Union.LocateEffect (Polysemy.Final.Final IO) r
~ '(),
Polysemy.Internal.Union.LocateEffect Calamity.Cache.Eff.CacheEff r
~ '()) =>
Polysemy.Internal.Sem
(DSLState FullContext r)
(Calamity.Commands.Types.Command FullContext)
at <interactive>:1:1
The type variable ‘c0’ is ambiguous
These potential instances exist:
instance Calamity.Commands.Context.CalamityCommandContext
FullContext
-- Defined at Calamity/Commands/Context.hs:68:10
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: command @'[Member] "test"
In the expression:
(command @'[Member] "test" $ \ (_ctx :: FullContext) _ -> pure ())
GHC complains about some c0 type variable that doesn't appear anywhere else. Interestingly, this only appears for certain types. If we replace Member with Int then it typechecks.
After some digging, the culprit seems to be
type TypedCommandC ps c a r =
[...]
, ParameterInfoForParsers ps r
)
...
class ParameterInfoForParsers (ps :: [Type]) r where
...
instance (ParameterParser x c r, ParameterInfoForParsers xs r) => ParameterInfoForParsers (x : xs) r where
...
Aha! We've introduced a new type variable c that's unrelated to the one mentioned in the type signature of command, leading to the ambiguity error. ParameterParser in turn requires ParameterParser in certain instances. Namely, the instances for types that cause the expression to not typecheck (such as Member).
The fix is simple, add c to the typeclass parameters of ParameterInfoForParsers to ensure it's the same c.
Running the following command in GHCi gives an interesting error message
GHC complains about some
c0
type variable that doesn't appear anywhere else. Interestingly, this only appears for certain types. If we replaceMember
withInt
then it typechecks. After some digging, the culprit seems to beAha! We've introduced a new type variable
c
that's unrelated to the one mentioned in the type signature ofcommand
, leading to the ambiguity error.ParameterParser
in turn requiresParameterParser
in certain instances. Namely, the instances for types that cause the expression to not typecheck (such asMember
). The fix is simple, addc
to the typeclass parameters ofParameterInfoForParsers
to ensure it's the samec
.