ajnsit / monadbi

BiDirectional monads that can be transformed into each other (atleast partially).
http://github.com/ajnsit/monadbi
GNU General Public License v3.0
1 stars 0 forks source link

What happened to monadbi? #1

Open rowandavies opened 9 years ago

rowandavies commented 9 years ago

I just stumbled on this repo via a hayoo search. The concept seems related to a technique we've been using recently that we've been calling relative monads. See, e.g.,: https://github.com/CommBank/lambdajam-relative-monads

I just wanted to ask what happened to the concept behind this repo - did you find something else that subsumed monadbi?

ajnsit commented 9 years ago

The particulars of the problem I was trying to solve with monadbi escape me at the moment, but I used the monad-control package to accomplish the same thing.

I think the primary reason I abandoned monadbi at that time was that I couldn't come up with reasonable laws for the instances, nor figure out how to achieve certain effects, such as being able to retain all the state information after having raised and lowered a transformer stack containing StateT.

I'm pretty sure there is a good idea hiding somewhere in this, so I'm glad to see someone else looking into such an approach.

rowandavies commented 9 years ago

Ah, I guess that is encouraging from our point of view, thanks for responding.

Being sure of the laws is one reason we're emphasizing a presentation based on relative monads which follow monads closely. You should be able to guess the laws from the class definition:

class (Monad r, Monad m) => RelMonad r m where
    rReturn :: r a -> m a
    rBind :: m a -> (r a -> m b) -> m b

I think it may be equivalent to what you had for monadbi in the sense that you can convert between instances of the two type classes.

The issue with StateT I think is clearer with rBind - if some state is in m a but not in r a then the laws require that rBind appropriately propagate the state to the result of the rBind, similar to an ordinary bind.

But, the main code organisation we're emphasizing is a little different to monad transformers with lifts, we're instead organising our code by defining type classes of operations that are available on "all monads m that are relative to a particular type R, i.e., we have an instance of RelMonad R m". Then, we choose a specific type N for each of our concrete monads and implement RelMonad R N instances, i.e., rReturn and rBind, generally directly, since they are pretty simple, but we can also compose simpler RelMonad instances.