Состав кортежей и функций - PullRequest
6 голосов
/ 25 января 2012

Есть ли лучший способ выразить (\(a, b) -> a < b) с помощью композиции функций? Я чувствую, что что-то упустил, и эксперимент с curry только смутил меня больше.

Ответы [ 2 ]

12 голосов
/ 25 января 2012

curry - неправильная вещь для использования здесь;он превращает функцию, работающую с кортежами, в функцию с карри.Вы хотите противоположное, а именно uncurry:

uncurry :: (a -> b -> c) -> (a, b) -> c

В этом случае это uncurry (<).

(Еще один полезный источник для комбинаторов, полезных при написаниифункции для кортежей Control.Arrow, поскольку (->) является экземпляром Arrow, вы можете прочитать a b c как b -> c.)

1 голос
/ 20 февраля 2015

Просмотр типов - лучший способ в Хаскеле понять, что делает любая функция:

curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c

curry: функция пары → функция карри (это карри функция).

uncurry: функция карри → функция пары.

На вики-странице Haskell о карри в конце страницы есть небольшие упражнения:

  • Упростить curry id
  • Упрощение uncurry const
  • Экспресс snd с использованием curry или uncurry и другими базовыми функциями Prelude и без лямбды
  • Напишите функцию \(x,y) -> (y,x) без лямбды и только с функциями Prelude

Попытайтесь выполнить эти упражнения прямо сейчас, они дадут вам исчерпывающее представление о системе типов и применении функций на 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)
...