2013-06-11 4 views
5

semplice esempio:Usando Lens, come si configura il setter con un'altra funzione g tale che l'uscita di g sia il nuovo valore da impostare?

{-# LANGUAGE TemplateHaskell #-} 

import Language.Haskell.TH 
import Control.Lens 

data Point = P { _x :: Double, _y :: Double } deriving (Show) 
$(makeLenses ''Point) 

Questo è quello che sto cercando di fare in stile imperativo:

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

Attualmente ho provato questa implementazione:

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

Non è una composizione effettiva, non idiomatico e genera anche un errore:

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 

Anche se una versione non parametrizzata di quanto sopra potrebbe funzionare:

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

Sembra f potrebbe essere un getter o setter, non entrambi?

risposta

8

si desidera che la funzione di over, il cui tipo è specializzata in questo caso:

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

Così si avrebbe solo scrivere:

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