Multiple overloads of the bind operator

Hi! Let's say it makes a lot of sense in my domain to define the types WriteReference and ReadOnlyReference. I wish to create a monad that manipulates references, so my first idea was to define

(>>=) :: WriteReference a -> (a -> WriteReference b) -> WriteReference b
(>>=) :: WriteReference a -> (a -> ReadOnlyReference b) -> ReadOnlyReference b
(>>=) :: ReadOnlyReference a -> (a -> ReadOnlyReference b) -> ReadOnlyReference b
(>>=) :: ReadOnlyReference a -> (a -> WriteReference b) -> WriteReference b

return :: a -> ReadOnlyReference a

It looks ugly but it does its job, even though I fear it won't play nice with Haskell syntactic sugar for monads.

Does it make more sense to define Reference as a class, and then to define WriteReference and ReadOnlyReference as instances of this class, so that we can write something like:

data WR a = WR a
data RR a = RR a

class Reference r where get :: r a -> a

instance Reference WR where get (WR x) = x

instance Reference RR where get (RR x) = x

bind :: (Reference r1, Reference r2) => r1 a -> (a -> r2 b) -> r2 b
bind e k = let x = get e in k x

Can anyone help me understand why I should favor one approach over the other?


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

This is more a question for the Haskell Cafe mailing list.

You'll get more response there.

Fair enough, but the

Fair enough, but the question wasn't meant to be Haskell specific: I am more curious about the implications with respect to building such a monad. Is it still a monad? Is it something else?

is it still a monad?

does it satisfy the monad laws?