-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doesn't support transformer state that depends on the transformed monad #4
Comments
Yes, this is a known limitation of Note that it's also a limitation of previous versions of
to quote "...this type ensures that the result of running the action in m has no remaining side effects in m." However, I'm not sure anymore why this is important. I will ask Anders Kaseorg (author of |
OK, thanks. I agree with that quote that ensuring the specific choice of monad |
Do you mean something like this:
However the polymorphicness of this is problematic for your
Here the type checker will complain that in can't deduce Or do you have something else in mind? |
Here is what I imagined:
I have no idea if this would work or not, but it seems correct to me. (edit: Turned off syntax highlighting since it was flagging up all the Unicode as invalid.) (edit 2: Corrected Unicode mix-up.) |
And it supports making your instance MonadTransControl (FooT s) where
newtype StT (FooT s) m α = StFoo {unStFoo ∷ StT (StateT (Bar m s)) m α}
liftWith f = FooT $ liftWith $ \run → f (liftM StFoo ∘ run ∘ unFooT)
restoreT = FooT ∘ restoreT ∘ liftM unStFoo However users can make more errors with it like: instance MonadTransControl (StateT s) where
newtype StT (StateT s) m α = StState {unStState ∷ StateT s m α}
liftWith f = lift $ f $ return ∘ StState
restoreT m = StateT $ \s -> m >>= \st → runStateT (unStState st) s This looks a bit like the problematic code that Anders posted in his email to us: peel = lift (return return) I'm not sure how bad it is to allow this. A solution could be to add more laws that ban this definition. I don't think the current set of laws is sufficient: liftWith . const . return = return
liftWith (const (m >>= f)) = liftWith (const m) >>= liftWith . const . f
liftWith (\run -> run t) >>= restoreT . return = t If you know a law that I missed please post it. Cheers, Bas |
Hmm. The problem is that we want a value of type I think this could be fixed with a really silly, lawless addition to the typeclass:
Then the only monadic computations you can define ST to be are ones that are isomorphic to the "correct" definitions (consider that But this feels like a hack. Edit: Actually, if adding
I actually like this a lot: the monadic state of It might be worth making Edit 2: Hmm, this doesn't work; the MaybeT/ErrorT/ListT instances break it. On this basis, I question the correctness of the cpp-generated Edit 3: By the way, the documentation for |
An idea that occurs to me as far as adding laws goes is to add one to make sure that restoring a single Then the pathological Further along those lines, it might be a good idea to express that the restoration must be agnostic as to whatever the current state is: restoring
|
I assume you mean:
I like it! Maybe we can make it a bit stronger by using a bind instead of
|
Yes, that works, though it can be simplified and generalised to:
However, I think I have a better solution. I have devised a new MonadTransControl definition that:
Edit 2: Oh, I forgot to mention the main benefit to this new design: 4. it doesn't allow you to exploit polymorphism a la the broken I've put it on hpaste; basically,
I tried to match the existing style in monad-control for the This is the easy part; the hard parts are
Two obvious laws to start with are
Thanks for reading this babble; I'd love to know what you think of this scheme and, especially, if you have any ideas on how to simplify it. :-) Edit: And another, scarier law: |
Just pinging this issue in case my comment fell through the cracks — no problem if you don't have any comments yet :) |
Sorry Elliott, I didn't have time yet to carefuly look at your implementation. I will try do to it this weekend. |
Great, just checking; I've heard of GitHub failing to mail about issue comments before... |
What is the status of this issue? |
Basically I forgot about it. What would help the issue is:
Due to being very busy at my new startup I don't have time to do any of these things. |
I know this is really old, but another example to consider is newtype ListT m a = ListT m (Maybe (a, ListT m a)) So the result of running one layer may include more layers, which depend on |
@ehird, your hpaste is gone. Is your code available anywhere else? |
Hi,
I have a monad that looks like
The problem here is that
Bar m s
is part of the monadic state, and depends onm
, so an attempt to define the associatedStT
falls down:(
m
is unbound.)Do you have any suggestions for solving this issue? I think it's a limitation in monad-control, but I'm not quite sure.
The definition of Bar in my code is as follows:
(obviously it's not called Bar though :))
The text was updated successfully, but these errors were encountered: