Объединение функций подкачки и сопряжения в haskell

#haskell

Вопрос:

Я очень новичок в haskell и начал читать книгу «Программирование на хаскелле». Я наткнулся на функцию под названием swap

 swap (x,y) = (y,x) 
 

и пара функций.

 pair x y = (x,y) 
 

Затем я начал задаваться вопросом, можно ли как-то объединить эти две функции вот так

 swapPair x y = (y,x) 
 

и использование двух функций priar в качестве справочных функций.

Комментарии:

1. Ответы ниже предоставляют несколько альтернатив, в том числе некоторые в так называемом «стиле без точек». Тем не менее, если вы новичок, я бы посоветовал вам сосредоточиться только на простейшей, прямой композиции swapPair x y = swap (pair x y) и игнорировать более продвинутые опции, которые на самом деле не улучшают ни читабельность, ни производительность.

2. Существует базовая функция высшего порядка Хаскелла, называемая curry типом ((a, b) -> c) -> a -> b -> c . Он принимает [функцию, которая потребляет кортеж и возвращает что-то] и возвращает [функцию, которая потребляет первый элемент кортежа и возвращает [функцию, которая потребляет второй элемент кортежа и возвращает что-то]]. swapPair является curry swap .

Ответ №1:

Самый очевидный способ, которым это можно сделать, — это

 swapPair x y = swap (pair x y)
 

что то же самое, что

 swapPair x y = swap $ pair x y
 

Поскольку y он появляется только в конце обеих сторон, он может быть уменьшен по времени прибытия. Это требует изменения оператора приложения на композиционный:

 swapPair x = swap . pair x
 

Как показал Виллем Ван Онсем, это можно сделать полностью без очков. Я бы не рекомендовал этого делать, но вот как это работает: сначала вы учитываете, что . оператор сам по себе является функцией, которая применяется к некоторым аргументам

 swapPair x = (.) swap (pair x)
 

Тогда это снова можно будет записать как композицию:

 swapPair x = (.) swap . pair $ x
 

eta-снизить

 swapPair = (.) swap . pair
 

и, наконец, может быть применен синтаксис раздела оператора:

 swapPair = (swap .) . pair
 

Комментарии:

1. Просто чтобы дать ему название, хотя оно обычно не используется, оно уже долгое время плавает вокруг (.:) = (.) . (.) , и его можно определить как swap .: pair . Недавно я обнаружил, что Agda имеет возможность определять его swap ◦ ◦ pair с помощью операторов mixfix. Для этого не требуется определять все больше и больше операторов.

Ответ №2:

Вы можете использовать их с:

 swapPair :: a -> b -> (b, a)
swapPair = (swap .) . pair
 

Здесь мы, таким образом, сначала передаем два параметра pair для создания 2-кортежа, а затем применяем swap их к этому 2-кортежу.

Но мы можем сделать это без swap и pair , и просто работать с:

 swapPair :: a -> b -> (b, a)
swapPair = flip (,)