原则上,实际需要的镜头操作员是%%~
,这只是方便的同义词id
。但是,由于 和 中使用的元组顺序存在令人讨厌的不兼容atomicModifyIORef
,(,) a
Functor
它需要进行一些交换才能工作。我不认为生成的运算符是预定义的,但我在swappedId
下面给出了初步名称。
请注意,Lens
类型定义为
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
事实证明,如果你让f
成为(,) a
Functor
,这几乎完全符合你想要用来转换你的类型inc
,除了你真的希望a
成为元组的最后一个元素而不是第一个元素。解决这个问题后,我得到了以下结果:
import Data.IORef
import Control.Lens
l `swappedId` f = f & mapping swapped %~ l
main = do
let inc x = (x+1, x)
ior <- newIORef ((1, 1) :: (Int, Int))
thisShouldBe1 <- atomicModifyIORef ior $ _1 `swappedId` inc
print thisShouldBe1
print =<< readIORef ior