Sure, you can define a variadic addition function, with some typeclass hackery:1
{-# LANGUAGE TypeFamilies #-}
class Add r where
add' :: (Integer -> Integer) -> r
instance Add Integer where
add' k = k 0
instance (n ~ Integer, Add r) => Add (n -> r) where
add' k m = add' (\n -> k (m+n))
add :: (Add r) => r
add = add' id
And so:
GHCi> add 1 2 :: Integer
3
GHCi> add 1 2 3 :: Integer
6
The same trick is used by the standard Text.Printf
module. It's generally avoided for two reasons: one, the types it gives you can be awkward to work with, and you often have to specify an explicit type signature for your use; two, it's really a hack, and should be used rarely, if at all. printf
has to take any number of arguments and be polymorphic, so it can't simply take a list list, but for addition, you could just use sum
.
1 The language extension isn't strictly necessary here, but they make the usage easier (without them, you'd have to explicitly specify the type of each argument in the examples I gave, e.g. add (1 :: Integer) (2 :: Integer) :: Integer
).