確かに、いくつかの型クラスのハッカーを使用して、可変引数加算関数を定義できます。
{-# 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
など:
GHCi> add 1 2 :: Integer
3
GHCi> add 1 2 3 :: Integer
6
Text.Printf
標準モジュールでも同じトリックが使用されます。通常、これは 2 つの理由で回避されます。1 つは、提供される型が扱いにくい場合があること、および使用のために明示的な型シグネチャを指定する必要がある場合が多いことです。2 つ目は、これは本当にハックであり、使用する場合はめったに使用しないでください。printf
任意の数の引数を取り、ポリモーフィックである必要があるため、単純にリスト list を使用することはできませんが、追加の場合はsum
.
1ここでは言語拡張は厳密には必要ありませんが、使用が容易になります (言語拡張がないと、私が示した例で各引数の型を明示的に指定する必要がありますadd (1 :: Integer) (2 :: Integer) :: Integer
)。