Подтвердить что ты не робот

Как связать второй аргумент в функции, но не первый (элегантным способом)?

Есть ли способ в Haskell связать второй аргумент, но не первый из функции без использования лямбда-функций или определения другой "локальной" функции?

Пример. У меня есть двоичная функция вроде:

sub :: Int -> Int -> Int
sub x y = x - y 

Теперь, если я хочу связать первый аргумент, я могу сделать это с помощью (sub someExpression):

mapSubFrom5 x = map (sub 5) x

*Main> mapSubFrom5 [1,2,3,4,5]
[4,3,2,1,0]

Это отлично работает, если я хочу привязать первые n аргументов без "пробела".

Если я хочу связать второй аргумент, но не первый, два параметра, о которых я знаю, более подробные:

Либо через другую, локальную, функцию:

mapSub5 x = map sub5 x
    where sub5 x = sub x 5

*Main> mapSub5 [1,2,3,4,5]
[-4,-3,-2,-1,0]

Или используя лямбда:

mapSub5 x = map (\x -> sub x 5) x

В то время как обе работают нормально, мне нравится элегантность "sub 5" и интересно, есть ли такой же элегантный способ привязать n-й (n > 1) аргумент функции?

4b9b3361

Ответ 1

flip, который создает новую функцию с первыми двумя инвертированными аргументами, уже упоминался как решение для решения проблемы.

Однако стоит отметить, что Haskell определяет хороший синтаксис инфикса для двоичных операторов.

Прежде всего, это просто

sub = (-)

С круглыми скобками все операторы также являются синтаксически - обычными функциями. Теперь мы можем работать с операторами с некоторым специальным синтаксисом. Связывание с первым операндом:

addOne = (1 +)

... и ко второму

half = (/ 2)

Таким образом, ваш код становится

map (-5) [1..5]

К сожалению, -5 является числовым литералом, но вы получаете точку.:) Теперь, поскольку мы можем превратить любую функцию в двоичный оператор, поместив обратные элементы вокруг нее, как в

f x y == x `f` y

мы можем использовать этот специальный синтаксис оператора для записи

map (`sub` 5) [1..5]

<ч/" > Примечание.. Каррирование первого аргумента является общим, второе - как в вашем случае - возможно. Но: я бы этого не делал для дальнейших аргументов. Функции Haskell написаны в стиле, в котором общие для карри расположены именно по этой причине.

Использование некоторого специального синтаксиса для дальнейших аргументов кажется для меня слишком скрытым. Просто используйте лямбда и дайте переменным описательные имена.

Ответ 2

Для n = 2 только другой способ привязки:

mapSub5 x = map (`sub` 5) x

Ответ 3

Как связать второй аргумент:

div2 = flip div 2

ghci> div2 10
5

В вашем случае вы можете написать

ghci> map (flip (-) 5) [1..5]
[-4,-3,-2,-1,0]

Обратите внимание, что в Haskell вы можете писать операторы в форме префикса как (-). Это то же самое, что и sub в вашем вопросе.