Functions
Because functions are values, there are also functions that operate on them:
($) :: (a -> <c> b) -> a -> <c> b (Prelude)
Function application. f $ x is equivalent with f x. The function has two uses.
First is to remove parentheses from deeply nested expressions:
f (g (h x)) == f $ g $ h x
The second use is with higher order functions:
map ($ parameter) functions
(.) :: (a -> <c> b) -> (d -> <c> a) -> d -> <c> b (Prelude)
Composes two functions
(f . g) x = f (g x)
Currying and partial application
Every SCL function is curried: a function that takes two arguments is actually a function
that takes one argument and returns another function expecting the second argument. The
types a -> b -> c and a -> (b -> c) are identical — -> is right-associative.
This means you can supply fewer arguments than the function expects. The result is a
partial application — a new function waiting for the remaining arguments:
add :: Integer -> Integer -> Integer
add x y = x + y
addFive :: Integer -> Integer
addFive = add 5 // partial application; addFive y = add 5 y
> map addFive [1,2,3]
[6, 7, 8]
Operators can also be partially applied by enclosing them in parentheses with one argument:
> map (+ 1) [1,2,3]
[2, 3, 4]
> filter (> 0) [-1, 2, -3, 4]
[2, 4]
The $ operator — low-precedence application
$ is the function application operator with the lowest precedence of all operators
(right-associative). It lets you eliminate a pair of parentheses by treating everything
to its right as the argument:
f $ g x // same as f (g x)
print $ show $ 1 + 2 // print (show (1 + 2))
Without $:
print (show (1 + 2))
The . operator — function composition
. composes two functions: (f . g) x = f (g x). The right-hand function is applied
first, its result is passed to the left-hand function.
> (negate . abs) (-5)
-5
> map (show . (* 2)) [1,2,3]
["2", "4", "6"]
Important: a space is required between identifiers and . when the identifier ends
in a letter, otherwise the compiler reads it as module-qualified access:
show . sum // correct: composition
show.sum // ERROR: tries to access `sum` in module `show`
Backtick infix syntax
Any two-argument function can be used as an infix operator by surrounding it with
backticks:
10 `div` 3 // same as div 10 3
"hello" `isPrefixOf` "hello world"
The flip function
flip swaps the first two arguments of a function. It is useful when the natural argument
order does not match what a higher-order combinator expects:
flip :: (a -> b -> <d> c) -> b -> a -> <d> c (Prelude)
Flips the parameters of a binary function.
> flip div 2 10 // div 10 2 = 5
5
> map (flip splitString ";") lines // splitString line ";"
|