Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Lift state monad to focus on part of a record

With the following code snippet:

data Circle = Circle 
            { center :: Point
            , radius :: Double
            }

data Point = Point (Double, Double)

someFuncOverPoint :: State Point blahblah

I wonder if there is a function that can make the someFuncOverPoint to focus on Circle:

someMagicFunc :: ??? -> State Point blahblah -> State Circle blahblah

Maybe this can be implemented using lens?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Strictly speaking you can. Indeed, we can create a state by first generating the first State Point a, and then pass that into a State, so:

someMagicFunc :: Double -> State Point a -> State Circle a
someMagicFunc r s = State (\s0 -> let ~(s1, a) = runState s s0 in (Circle s1 r, a))

So here we construct a State that works with a function that maps the initial state s0 to the next state s1 and the result, and then we turn that into a 2-tuple with the Circle as state, and the "result" a as well.

That being said, it is a bit strange to change the type of the state. Usually the type of the state remains the same over all the actions.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading