If you look at the documentation for the Control.Lens module there's a very handy image of different parts of the lens package. Since you want to construct a Lens
, you can look at the Lens
part of the diagram. The topmost function shown is
lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
This constructs a Lens from a getter and a setter.
The function s -> a
is a getter – the type signature means, "If you give me a data structure s
, I will pick an a
value out of it." The s -> b -> t
function is the setter, and the type signature means, "If you give me an s
and a new value b
, I will create for you a new structure t
." (The types are different because lenses can actually change types of things.)
If your getter is tmGet
and your setter is tmSet
, you can therefore construct a lens with
tmAt :: Boolean -> Lens s t a b
tmAt b = lens (tmGet b) (tmSet b)
for whatever your actual s
, t
, a
, and b
parameters are. In the example of a tuple, it would be
tmAt :: Bool -> Lens (a, a) (a, a) a a
(In other words, if you give the Lens a function a -> a
, it can transform an (a, a)
-tuple into another (a, a)
-tuple.)
If you want to be fancy, you can also rewrite tmAt
as
tmAt = lens <$> tmGet <*> tmSet