Is a section the result of currying?

ε祈祈猫儿з 提交于 2019-12-04 05:47:11

问题


In Programming in Haskell by Hutton

In general, if # is an operator, then expressions of the form (#), (x #), and (# y) for arguments x and y are called sections, whose meaning as functions can be formalised using lambda expressions as follows:

(#)   =   \x  ->  (\y ->  x   #   y)
(x    #)  =   \y  ->  x   #   y
(#    y)  =   \x  ->  x   #   y

What are the difference and relation between "section" and "currying"?

Is a section the result of applying the currying operation to a multi-argument function?

Thanks.


回答1:


Left sections and right sections are syntactical devices for partially applying an infix operator to a single argument (see also chepner's answer). For the sake of accuracy, we should note that currying is not the same thing as partial application:

  • Currying is converting a function that takes N arguments into a function that takes a single argument and returns a function that takes N-1 arguments.

  • Partial application is making a function that takes N-1 arguments out of a function that takes N arguments by supplying one of the arguments.

In Haskell, it happens that everything is curried; all functions take just one argument (even uncurried functions in Haskell take a tuple, which is, strictly speaking, a single argument -- you might want to play with the curry and uncurry functions to see how that works). Still, we very often think informally of functions that return functions as functions of multiple arguments. From that vantage point, a nice consequence of currying by default is that partial application of a function to its first argument becomes trivial: while, for instance, elem takes a value and a container and tests if the value is an element of the contaier, elem "apple" takes a container (of strings) and tests if "apple" is an element of it.

As for operators, when we write, for instance...

5 / 2

... we are applying the operator / to the arguments 5 and 2. The operator can also be used in prefix form, rather than infix:

(/) 5 2

In prefix form, the operator can be partially applied in the usual way:

(/) 5

That, however, arguably looks a little awkward -- after all, 5 here is the numerator, and not the denominator. I'd say left section syntax is easier on the eye in this case:

(5 /)

Furthermore, partial application to the second argument is not quite as straightforward to write, requiring a lambda, or flip. In the case of operators, a right section can help with that:

(/ 2)

Note that sections also work with functions made into operators through backtick syntax, so this...

(`elem` ["apple", "grape", "orange"])

... takes a string and tests whether it can be found in ["apple", "grape", "orange"].




回答2:


A section is just special syntax for applying an infix operator to a single argument. (# y) is the more useful of the two, as (x #) is equivalent to (#) x (which is just applying the infix operator as a function to a single argument in the usual fashion).




回答3:


curry f x y = f (x,y). uncurry g (x,y) = g x y.

(+ 3) 4 = (+) 4 3 = 4 + 3. (4 +) 3 = (+) 4 3 = 4 + 3.

A section is a result of partial application of a curried function: (+ 3) = flip (+) 3, (4 +) = (+) 4.

A curried function (like g or (+)) expects its arguments one at a time. An uncurried function (like f) expects its arguments in a tuple.

To partially apply an uncurried function we have first to turn it into a curried function, with curry. To partially apply a curried function we don't need to do anything, just apply it to an argument.

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

 x :: a
 g :: a -> (b -> c)       
--------------------
 g    x ::  b -> c  

 x       ::  a
 f       :: (a, b)   -> c
---------------------------
 curry f ::  a -> (b -> c)
 curry f     x ::  b -> c


来源:https://stackoverflow.com/questions/57019292/is-a-section-the-result-of-currying

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!