module Data.Derive.Update(makeUpdate) where
import Language.Haskell
import Data.Derive.Internal.Derivation
import Data.Maybe
makeUpdate :: Derivation
makeUpdate = derivationCustom "Update" $ \(_,d) -> Right $ concatMap (makeUpdateField d) $ dataDeclFields d
makeUpdateField :: DataDecl -> String -> [Decl ()]
makeUpdateField d field =
[TypeSig () [name upd] (TyFun () (TyParen () (TyFun () typF typF)) typR)
,bind upd [pVar "f",pVar "x"] $ RecUpdate () (var "x") [FieldUpdate () (qname field) (App () (var "f") (Paren () $ App () (var field) (var "x")))]
,TypeSig () [name set] (TyFun () typF typR)
,bind set [pVar "v",pVar "x"] $ RecUpdate () (var "x") [FieldUpdate () (qname field) (var "v")]]
where
set = field ++ "_s"
upd = field ++ "_u"
typR = TyFun () (dataDeclType d) (dataDeclType d)
typF = fromJust $ lookup field $ concatMap ctorDeclFields $ dataDeclCtors d