我无法理解 Haskell 中镜头库的所有细微差别。
假设我有以下镜头
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) }
在 ghci 提示符下执行以下操作没有问题:
> :t do{use (activePlayer); activePlayer.= undefined}
:: Control.Monad.State.Class.MonadState Game m => m ()
但是,当我尝试将其参数化为函数时,出现以下错误。
> :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 }
当我希望将其推断为完整时,它看起来p
被推断为. 我尝试强制使用以下内容,但 ghci 抱怨 RankNTypes in 。Accessor
Lens
p
Lens
Lens' a b
:t \p -> do{use p; p.=undefined} :: Lens' a b -> m c
如果有人能帮助我弄清楚为什么p
会以这种方式推断出来,以及如何使它表现得像一个完整的Lens
.