
Hi list, there is one thing about the "Finally tagless" EDSL approach that really confuses me: (Well more than one actually but this one more so) When to decide to introduce a term as a primitive in the syntax class and when to define it from primitives already defined. For example this one here: type Arr exp a b = exp a -> exp b class EDSL exp where lam :: (exp a -> exp b) -> exp (Arr exp a b) app :: exp (Arr exp a b) -> exp a -> exp b int :: Int -> exp Int -- Integer literal add :: exp Int -> exp Int -> exp Int sub :: exp Int -> exp Int -> exp Int mul :: exp Int -> exp Int -> exp Int Let's take "mul" here, defined as a "primitive", in other words defined in the EDSL class. Technically, with lam, app and add already defined, I could have defined "mul" outside the EDSL class, just built from the 3 primitive operators. Of course doing so then does not give me the possibility to choose alternative evaluation strategies for "mul" itself, only for lam, app and add. So what is a good measure for deciding when to define a term primitive or not? Günther