I'm having trouble understanding all the nuances of the lens library in Haskell.
Suppose I have the following lens
activePlayer :: Lens' Game Player
activePlayer = lens get set
where
get (Game {_players = (index, seq) }) = S.index seq index
set g@(Game {_players = (index, seq) }) player =
g { _players = (index, S.update index player seq) }
Performing the following at the ghci prompt works with no problems:
> :t do{use (activePlayer); activePlayer.= undefined}
:: Control.Monad.State.Class.MonadState Game m => m ()
However when I try and parameterize it into a function I get the following error.
> :t \p -> do{use p; p.=undefined}
<interactive>:1:17:
Couldn't match type `Accessor a0 a0' with `Mutator b0'
Expected type: ASetter s0 s0 a0 b0
Actual type: Getting a0 s0 a0
In the first argument of `(.=)', namely `p'
In a stmt of a 'do' block: p .= undefined
In the expression:
do { use p;
p .= undefined }
It looks like p
is getting inferred as an Accessor
, when I want it to be inferred as a full Lens
. I tried forcing p
to be a Lens
with the following, but ghci complained about RankNTypes in Lens' a b
.
:t \p -> do{use p; p.=undefined} :: Lens' a b -> m c
I would greatly appreciate it if anyone could help me figure out why p
is being inferred the way it is, and how I can make it behave as a full Lens
.