Конечно, вы можете определить VARIADIC дополнение функция, с некоторыми повозка, запряженная волами: класс типов
{-# 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
. Обычно его избегают по двум причинам: один, типы, которые он дает вам, могут быть неудобными для работы, и вам часто приходится указывать явную подпись типа для вашего использования; два, это действительно взлом, и его следует использовать редко, если вообще. printf
должен принимать любое количество аргументов и быть полиморфным, поэтому он не может просто взять список списка, но для добавления вы можете просто использовать sum
.
Расширение языка не является строго необходимым здесь, но они делают использование проще (без них, вы должны явно указать тип каждого аргумента в примерах, которые я дал, например add (1 :: Integer) (2 :: Integer) :: Integer
).
Он не сказал, что '+' не принимает вход, но что '1 + 1' не принимает никаких данных. (То есть '1 + 1' не является функцией.) –
Возможно, посмотрите на http://stackoverflow.com/questions/3467279/how-to-create-a-polyvariadic-haskell-function – phimuemue
Возможны функции Variadic, но только с чрезмерным хакером типа (и, я считаю, расширением языка). Также обратите внимание, что ответ (я предполагаю, что вы имеете в виду принятый) не указывает, что '+' не имеет ввода - результат '1 + 1' не является функцией (не принимает никаких параметров). '+' - это обычная двоичная (как, например, взятие двух параметров), за исключением того, что вы должны записать ее как '(+)' для синтаксических соображений. – delnan