{-# LANGUAGE TemplateHaskell #-} import Data.Foldable import Language.Haskell.TH data Point = Point { x :: Double , y :: Double } deriving Show data Point3 = Point3 { x3, y3, z3 :: 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|]]) addPoint3 :: Point3 -> Point3 -> Point3 addPoint3 a b = $(zipFields [|Point3|] [|(+)|] [[|x3|], [|y3|], [|z3|]]) |] main :: IO () main = do print $ addPoint (Point 1.0 2.0) (Point 0.3 0.4) print $ addPoint3 (Point3 1.0 2.0 3.0) (Point3 0.4 0.5 0.6)