5

简单的例子:

{-# 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,而不是两者兼而有之?

4

1 回答 1

8

您希望over函数,其类型专门用于这种情况:

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

所以你只需写:

over x :: (Double -> Double) -> Point -> Point
于 2013-06-11T20:43:34.077 回答