简体   繁体   中英

Workaround to return a lens from a monadic action

Ran into this issue when playing with today's advent of code problem .

Say I have:

data Cache = Cache { _a :: Int, _b :: Int }
makeLenses ''Cache

type Register = Lens' Cache Int

Using Parsec, I can parse the character 'a' as a :: Register and the character 'b' as b :: Register .

register = a <$ char 'a' <|> b <$ char 'b'

which, alone, compiles just fine.

The trouble is when I give register the explicit type Stream sm Char => ParsecT sum Register , ghc complains that it wants to give it the type (Functor f, Stream sm Char) => ParsecT sum ((Int -> f Int) -> Cache -> f Cache) .

I think I understand its reasoning - it wants to float the typeclass constraints out as a far as possible; this is just slightly inconvenient to me for purposes of documenting register .

Is there a standard workaround for situations like this?

The solution that worked for me was to use ALens rather than Lens , as

This type can also be used when you need to store a Lens in a container, since it is rank-1.

Then I just replaced my Lens operators ^. and %~ with their ALens equivalents, ^# and #%~ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM