问题
Is there a better way to express (\(a, b) -> a < b)
with function composition? I feel like I'm missing something and experimenting with curry
only confused me more.
回答1:
curry
is the wrong thing to use here; it turns a function operating on tuples into a curried function. You want the opposite, which is uncurry:
uncurry :: (a -> b -> c) -> (a, b) -> c
In this case, it's uncurry (<)
.
(Another useful source for combinators useful in writing functions on tuples is Control.Arrow; since (->)
is an instance of Arrow
, you can read a b c
as b -> c
.)
回答2:
Looking at the types is the best way in Haskell to get the first idea, what any function does:
curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c
curry
: function of pair → curried function (it curries a function).
uncurry
: curried function → function of pair.
Haskell Wiki page on currying has small exercises at the end of the page:
- Simplify
curry id
- Simplify
uncurry const
- Express
snd
usingcurry
oruncurry
and other basic Prelude functions and without lambdas- Write the function
\(x,y) -> (y,x)
without lambda and with only Prelude functionsTry to solve these exercises right now, they will give you a massive insight into Haskell type system and function application.
There are several interesting applications of uncurry
, try to pass different arguments to functions below and see what they do:
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)
来源:https://stackoverflow.com/questions/8993285/tuple-and-function-composition