[Template-haskell] re: newbie question

Isaac Jones ijones@syntaxpolice.org
Wed, 09 Jul 2003 10:34:11 -0400


> [Isaac, you need to join the TH list so you can post to it without
> me having to intervene.]

Done

> Your original makeSum looked better.

OK, thats what I was hoping.

> Solution: use the "smart constructors" from the paper.  More like
> this:

>     genSummers n = fun ("makeSum" ++ (show i)) [clause [] (normal
> (makeSum i)) [] ]

Thanks, for some reason I was blind to the combination of using the
"smart constructors" in together with sequenceQ.  I thought I had
tried every combination to make the types work out.

Here's my solution below.

peace,

isaac


\begin{code}

-- |Given a size, n and n expressions, sum them up, so:
-- > $(makeSum 4) 1 2 3 10
-- => 16
-- > $(makeSum 4) 1.0 2.2 3.4 10.1
-- => 16.7

makeSum :: Int -> ExpQ
makeSum n = lam aPats (sumExps aVars)
    where
    -- create the symbols we'll need:
    aPats ::[Pat]
    aVars ::[ExpQ]
    (aPats,aVars) = genPE "num" n

    sumExps :: [ExpQ] -> ExpQ
    sumExps (h:t) = [| $h + $(sumExps t) |]
    sumExps []    = [| 0 |]

-- |Bring functions named makeSumX into scope where X is in [1..n]
genSummers :: Int -> Q [Dec]
genSummers n = sequenceQ [fun ("makeSum" ++ (show i)) [clause [] (normal (makeSum i)) [] ] | i <- [1..n] ]

-- Then in a different file, I can say
-- $(genSummers 10)
--  to bring makeSum1, makeSum2, etc into scope

\end{code}