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?
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.