
Sittampalam, Ganesh schrieb:
Bas van Dijk wrote:
Just for clarity, are you referring to the restricted monads from the rmonad package[1]?
yes
If so, I see no reason (yet) why the RMonad type class can't be defined as:
class RMonad m where join :: Suitable m a => m (m a) -> m a
Where the Set instance becomes:
instance RMonad Set where join ss = withResConstraints $ \SetConstraints -> fold union empty ss
I haven't tried it, but I think you'd need Suitable m (m a) in the constraints, either of join itself, or of (>>=) to make the default definition typecheck.
I ran into similar problems with trying to make RApplicative. Many of the Applicative combinators use intermediate functions heavily, leading to a need for Suitable m (a -> b) for various a and b, and there are often multiple different possible definitions of the combinators that lead to different constraints being needed.
I tried the same and got the same problems. My favorite example is a list like monad on StorableVector. Suitable StorableVector a means Storable a and there is no Storable (a -> b) I could define an RApplicative class only if I introduced an auxiliary type, in the example a stream-fusion:Stream. Then I could define a ZipList instance for StorableVector by converting each StorableVector to Stream and the zipped resulting Stream back to StorableVector.