Reputation:
I'm Trying to figure out how I can Sum up the Arguments of a Function which has a given signature sum :: Int -> ... -> Int
with 1024 Int arguments...
Clever Currying / Recursion is surely the deal I just can't grasp how to even start.
Upvotes: 0
Views: 211
Reputation: 2818
The fact that it's 1024 is probably meant to be a clue that you should build up to it in powers of two. Here's a solution as far as 16 which you can extend.
It's using a continuation passing style as a way to let you have one
function consume some arguments and then another consume some more.
To see what's going on, try calculating out a small example by hand,
say add4 id 1 2 3 4
.
add2 :: (Int -> a) -> Int -> Int -> a
add2 k x y = k (x + y)
add4 :: (Int -> a) -> Int -> Int -> Int -> Int -> a
add4 k = add2 (add2 (add2 k))
-- type signatures omitted from now on...
add8 k = add4 (add4 (add2 k))
add16 k = add8 (add8 (add2 k))
f = add16 id
And now you can do:
>f 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
136
I could also have written the functions more pointfree, for example:
add8 = add4 . add4 . add2
Upvotes: 7
Reputation: 153112
{-# LANGUAGE FlexibleInstances #-}
class SumArgs a where sumArgs :: Int -> a
instance SumArgs Int where sumArgs = id
instance SumArgs a => SumArgs (Int -> a) where sumArgs m n = sumArgs (m+n)
sumFourExample :: Int -> Int -> Int -> Int -> Int
sumFourExample = sumArgs
In ghci:
> sumFourExample 2 3 4 5
14
Upvotes: 5