{-# LANGUAGE TemplateHaskell #-} import Data.Foldable import Language.Haskell.TH data Point = Point { x :: Double , y :: Double } deriving Show let zipFields :: Q Exp -> Q Exp -> [Q Exp] -> Q Exp zipFields ctor op fields = foldl' (\prefix field -> [|$prefix ($op ($field a) ($field b))|]) ctor fields in [d| addPoint :: Point -> Point -> Point addPoint a b = $(zipFields [|Point|] [|(+)|] [[|x|], [|y|]]) |] main :: IO () main = print $ addPoint (Point 1.0 2.0) (Point 0.3 0.4)