Состав кортежей и функций
Есть ли лучший способ выразить (\(a, b) -> a < b)
с функцией композиции? Я чувствую, что что-то упускаю и экспериментирую с curry
только смутило меня больше.
2 ответа
curry
это неправильная вещь, чтобы использовать здесь; это превращает функцию, работающую с кортежами, в карри. Вы хотите противоположность, которая uncurry
:
uncurry :: (a -> b -> c) -> (a, b) -> c
В этом случае это uncurry (<)
,
(Другим полезным источником для комбинаторов, полезных при написании функций для кортежей, является Control.Arrow
; поскольку (->)
это пример Arrow
, ты можешь читать a b c
как b -> c
.)
Просмотр типов - лучший способ в Haskell, чтобы понять, что делает любая функция:
curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c
curry
: функция пары → функция карри (функция карри).
uncurry
: функция карри → функция пары.
В конце страницы Хаскелла на карри есть небольшие упражнения:
- упрощать
curry id
- упрощать
uncurry const
- экспресс
snd
с помощьюcurry
или жеuncurry
и другие основные функции прелюдии и без лямбд- Напишите функцию
\(x,y) -> (y,x)
без лямбды и только с функциями прелюдииПопробуйте выполнить эти упражнения прямо сейчас, они дадут вам исчерпывающую информацию о системе типов и применении функций на Haskell.
Есть несколько интересных приложений uncurry
попробуйте передать различные аргументы функциям ниже и посмотрите, что они делают:
uncurry (.) :: (b -> c, a -> b) -> a -> c
uncurry (flip .) :: (b -> a -> b1 -> c, b) -> b1 -> a -> c
uncurry (flip (.)) :: (a -> b, b -> c) -> a -> c
uncurry ($) :: (b -> c, b) -> c
uncurry (flip ($)) :: (a, a -> c) -> c
-- uncurry (,) is an identity function for pairs
uncurry (,) :: (a, b) -> (a, b)
uncurry (,) (1,2) -- returns (1,2)
uncurry uncurry :: (a -> b -> c, (a, b)) -> c
uncurry uncurry ((+), (2, 3)) -- returns 5
-- curry . uncurry and uncurry . curry are identity functions
curry . uncurry :: (a -> b -> c) -> (a -> b -> c)
(curry . uncurry) (+) 2 3 -- returns 5
uncurry . curry :: ((a, b) -> c) -> ((a, b) -> c)
(uncurry . curry) fst (2,3) -- returns 2
-- pair -> triple
uncurry (,,) :: (a, b) -> c -> (a, b, c)
uncurry (,,) (1,2) 3 -- returns (1,2,3)