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.