Transforming from on State-transformer to another

Is there a way to have a function of type (a -> b) -> State a c -> State b c ? In the particular case of interest, I am interested in is actually b -> State a c -> (State (a,b) c), which is of course a special case of the above. This matches 'first' on Data.Bifunctor, but State is not a Bifunctor. Nor a Profunctor, AFAIK. Use case: a Stateful computation where a local sub-computation needs more (local) state that will be, in-time, de-allocated. I guess the usual solution is probably to use 2 stacked State, but I'm curious if there's another way. Jacques

You need something like Lens to "zoom" into the state. As state monad can not only `get` but also `put` the state, the plain a -> b function is not enough: you need Lens a b. See https://hackage.haskell.org/package/lens-4.18.1/docs/Control-Lens-Zoom.html#... or https://hackage.haskell.org/package/optics-extra-0.2/docs/Optics-Zoom.html#v... - Oleg On 20.11.2019 20.08, Jacques Carette wrote:
Is there a way to have a function of type (a -> b) -> State a c -> State b c ?
In the particular case of interest, I am interested in is actually b -> State a c -> (State (a,b) c), which is of course a special case of the above.
This matches 'first' on Data.Bifunctor, but State is not a Bifunctor. Nor a Profunctor, AFAIK.
Use case: a Stateful computation where a local sub-computation needs more (local) state that will be, in-time, de-allocated.
I guess the usual solution is probably to use 2 stacked State, but I'm curious if there's another way.
Jacques
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Ah, that looks perfect, thank you. Jacques On 2019-11-20 1:15 p.m., Oleg Grenrus wrote:
You need something like Lens to "zoom" into the state. As state monad can not only `get` but also `put` the state, the plain a -> b function is not enough: you need Lens a b.
See https://hackage.haskell.org/package/lens-4.18.1/docs/Control-Lens-Zoom.html#... or https://hackage.haskell.org/package/optics-extra-0.2/docs/Optics-Zoom.html#v...
- Oleg
On 20.11.2019 20.08, Jacques Carette wrote:
Is there a way to have a function of type (a -> b) -> State a c -> State b c ?
In the particular case of interest, I am interested in is actually b -> State a c -> (State (a,b) c), which is of course a special case of the above.
This matches 'first' on Data.Bifunctor, but State is not a Bifunctor. Nor a Profunctor, AFAIK.
Use case: a Stateful computation where a local sub-computation needs more (local) state that will be, in-time, de-allocated.
I guess the usual solution is probably to use 2 stacked State, but I'm curious if there's another way.
Jacques
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Nov 20, 2019, at 1:08 PM, Jacques Carette
wrote: In the particular case of interest, I am interested in is actually b -> State a c -> (State (a,b) c), which is of course a special case of the above.
Use case: a Stateful computation where a local sub-computation needs more (local) state that will be, in-time, de-allocated.
Perhaps I misunderstood your use-case, but it seems that with a local sub-computation that needs extra state you can just: ... st <- get (c, (st', _)) <- runStateT local (st, extra) put st' ... where local :: StateT (a, b) m c. -- Viktor.

For what it's worth, I do sometimes define a version of MonadReader's
"local" for MonadState; it runs a State computation on a transformed State.
I've heard this used often enough to wonder why it's not a standard part of
MonadState.
On Wed, Nov 20, 2019 at 3:41 PM Viktor Dukhovni
On Nov 20, 2019, at 1:08 PM, Jacques Carette
wrote: In the particular case of interest, I am interested in is actually b -> State a c -> (State (a,b) c), which is of course a special case of the above.
Use case: a Stateful computation where a local sub-computation needs more (local) state that will be, in-time, de-allocated.
Perhaps I misunderstood your use-case, but it seems that with a local sub-computation that needs extra state you can just:
... st <- get (c, (st', _)) <- runStateT local (st, extra) put st' ...
where local :: StateT (a, b) m c.
-- Viktor.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com
participants (4)
-
Brandon Allbery
-
Jacques Carette
-
Oleg Grenrus
-
Viktor Dukhovni