0

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.

Tim
  • 1
  • 141
  • 372
  • 590
  • 3
    A section is exactly what the quoted paragraph says it is. What does this have to do with currying? – melpomene Jul 13 '19 at 12:53
  • Imagine a language with functions in infix notation. A binary function could look like `(2)sub(3)` - yes, it hurts my eyes, too. The left/right section would be `(2)sub`/`sub(3)`. Obviously, this doesn't work with multi-argument functions. The only relation between currying and sections a can see is that you need curried functions to express operator sections with them. –  Jul 13 '19 at 13:47
  • In the sense that sections allow partial application of an infix operator analogous to prefix notation, yes. – chepner Jul 13 '19 at 14:30

3 Answers3

5

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).

duplode
  • 33,731
  • 7
  • 79
  • 150
chepner
  • 497,756
  • 71
  • 530
  • 681
  • `(#)` is also a section. – melpomene Jul 13 '19 at 13:46
  • 3
    @melpomene Strictly speaking, I don't think it is. [Section 3.5 of the Report](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5) only talks about left sections and right sections; the `(#)` syntax is mentioned separately in [section 3.2](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-240003.2). – duplode Jul 13 '19 at 13:50
  • Huh. You're clearly right, yet the Hutton book gives a different definition. And I vaguely remember seeing this elsewhere, I just can't remember where. – melpomene Jul 13 '19 at 13:56
  • @melpomene You have brought it back to my mind: section 4.2 of [*A History of Haskell: Being Lazy With Class*](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf) does refer to `(#)` as a section, the unifying theme being making infix operators first class. We might say that, independently of how the Report names things, it is no coincidence that the syntax is nearly the same in either case. – duplode Jul 13 '19 at 14:22
  • 2
    I once asked [where the term "section" came from](https://stackoverflow.com/q/40536569/1126841), and there didn't seem to be a clear source. It wouldn't surprise me if there is no strict definition; intuitively, I think of it as partial application for infix operators, with `(#)` looking like, but not necessarily related to, sections. One might argue that an operator "applied" to zero arguments evaluates to the "underlying" function. – chepner Jul 13 '19 at 14:29
  • Thanks. 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? – Tim Jul 13 '19 at 14:30
  • 1
    Kind of. An infix operator is just a syntactic nicety; it's curried just like any other function, but you write its application in a different form. To drag backquotes into this (where `plus 3 5` and ``3 `plus` 5`` are equivalent), sections let you write `(3 +)` just as you can write `plus 3`. You can also write `(+ 5)` where there is no direct equivalent using prefix notation, without using `flip`. `(+ 5)` is the same as `flip plus 5`. – chepner Jul 13 '19 at 14:33
  • 1
    @Tim Why did you post this comment? It's just a repeat of your question. – melpomene Jul 13 '19 at 16:37
2

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
Will Ness
  • 70,110
  • 9
  • 98
  • 181
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"].

duplode
  • 33,731
  • 7
  • 79
  • 150