Lens ("prism"?) useful to get a field from a nested sub-record

97 views Asked by At

Considering these types:

data A = A { a :: Int }
data B = B { a :: Int }  -- a again!
data C = C1 A | C2 B

is there a way to get a from C object with some lens (prism?) returning Int and not Maybe Int? Because with pattern-matching (well, or with RecordWildCards):

case c of
  C1 c1 -> a c1
  C2 c2 -> a c2

I can get the Int, but with lens/prisms I think I will always get Maybe Int. Is it possible to be done with lens at all? My intuition is that lens don't know about "determinism" of a accessor over C, that it cannot be Maybe...

1

There are 1 answers

0
leftaroundabout On BEST ANSWER

You can define your own lens

aC :: Lens' C Int
--aC:: Functor f => (Int -> f Int) -> C -> f C
aC f (C1 (A x)) = fmap (C1 . A) $ f x
aC f (C2 (B x)) = fmap (C2 . B) $ f x

Exercise for you: check that this obeys the lens laws.