#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 (,)