[Haskell-beginners] State Monad: how to use other Stateful computation on sub-state inside

Karl Voelker 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) [1] and zoom (in the lens package) [2]. 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.


1: http://hackage.haskell.org/package/data-lens-fd-2.0.5/docs/Data-Lens.html#v:focus
2: http://hackage.haskell.org/package/lens-4.13/docs/Control-Lens-Zoom.html#v:zoom

More information about the Beginners mailing list