-- | A pseudo derivation. For each field in the data type, deriving -- @LazySet@ generates a function like a record updator, but lazy. -- This is very useful in certain situations to improve laziness -- properties. Example: -- -- > data Foo = Foo { x :: Int, y :: Int, z :: Int } -- -- becomes: -- -- > setX v f = Foo v (y f) (z f) -- > setY v f = Foo (x f) v (z f) -- > setZ v f = Foo (x f) (y f) v module Data.Derive.LazySet(makeLazySet) where import Language.Haskell.TH.All import Data.Char import Data.List {- data State = State {x :: Int, y :: Int} ==> setX a0 b0 = State a0 (y b0) setY a0 b0 = State (x b0) a0 -} makeLazySet :: Derivation makeLazySet = derivation lazyset' "LazySet" lazyset' dat = map f fields where fields = nub $ concatMap (\f -> map ((,) f) (ctorFields f)) (dataCtors dat) f (ctor,field) = funN name [sclause [vr "a0", vr "b0"] (lK (ctorName ctor) body)] where name = "set" ++ toUpper (head field) : tail field body = [ if fld == field then vr "a0" else l1 fld (vr "b0") | fld <- ctorFields ctor ]