I'm writing a type class à la mtl-style transformers. Looks like this:
class (Monad m, Stream s m t) => MonadStuff s m | m -> s where
-- function signatures go here…
I'm trying to say by that that m
should be instance of Monad
and there
should be instance of Stream s m t
, where t
doesn't really matter but
s
and m
are from the right side of the definition (after =>
).
Haskell says:
Not in scope: type variable ‘t’
So, obviously I cannot do that. Or can I? Should I remove Stream s m t
constraint and add it to every function in the class instead or is there
another way?
If it's really true that it doesn't really matter what t
is, then perhaps you can ask the person writing the instance to choose it:
{-# LANGUAGE TypeFamilies #-}
class (Monad m, Stream s m (StuffType m)) => MonadStuff s m | m -> s where
type StuffType m
Or, since you already have MPTCs and fundeps turned on, you could consider doing this, which requires no extra extensions but is otherwise basically identical:
class (Monad m, Stream s m t) => MonadStuff s m t | m -> s t where
However, I am suspicious that in fact the choice of t
does matter: unless Stream
has a fundep that is at least as informative as m s -> t
, you will not be able to use this constraint in a meaningful way. In that case, you should move the constraint into the signatures of the methods that mention t
or will be using the Stream
methods.
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