[Haskell-beginners] State Monad: how to use other Stateful computation on sub-state inside
karl at karlv.net
Sat Oct 17 07:40:13 UTC 2015
> On Oct 16, 2015, at 1:28 PM, martin <martin.drautzburg at web.de> wrote:
> The expression to the right of <- must have the type
> State System ItemDb
> But ItemAdd' has the type
> Item -> State ItemDb ()
You have an insight here which is quite general. If you have a monad State s, where s has a subcomponent of type t, you should be able to transform any action State t a into an “equivalent” action State s a, where instead of acting on the whole state, you act on the subcomponent.
What would we need in order to do that transformation in a general way? A function to get the subcomponent out of the whole, and a function to put the new value of the subcomponent back into the whole. In other words, we’d need functions of types s -> t and t -> s -> s.
Putting all of that together, we can imagine a transformation like this:
f :: (s -> t) -> (t -> s -> s) -> State t a -> State s a
I know of some libraries which provide a function with roughly that same type. The difference is that the first two parameters, the “getter” and “setter”, are combined into one parameter, and this combined thing is called a “lens”. Lenses are useful in all kinds of situations, and this just happens to be one of them.
Of course, if you don’t already have a lens, any lens library will give you a way to build one out of the getter and setter functions.
Anyway, the two library functions which provide this transformation are called focus (in the data-lens-fd package, which is used with the lens type defined in the data-lens package)  and zoom (in the lens package) . The lens package is more powerful, but also a good deal more confusing, so I would start with data-lens and data-lens-fd if you want a gentle introduction to lenses.
More information about the Beginners