使用Lens,如何将setter与另一个函数g组合在一起,使g的输出是要设置的新值



简单示例:

{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Control.Lens
data Point = P { _x :: Double, _y :: Double } deriving (Show)
$( makeLenses ''Point )

这是我试图在命令式风格做的:

point.set( "x", g (point.get("x") ) )

目前我尝试了这个实现:

mapF f p g = let v = g (p ^. f) in set f v p 

它不是一个实际的组合,不习惯,并且还抛出一个错误:

Couldn't match expected type `Mutator b0'
            with actual type `Accessor a0 a0'
Expected type: ASetter s1 t0 a0 b0
  Actual type: Getting a0 s0 a0

即使上面的非参数化版本也可以使用:

mapX p g = let v = g (p^.x) in set x v p

似乎f既可以是getter也可以是setter,而不是两者都是?

您希望over函数,其类型在本例中专门化为:

over :: Setter a b -> (b -> b) -> a -> a

所以你可以写:

over x :: (Double -> Double) -> Point -> Point

最新更新