## Monday, January 09, 2017

### [lvbetgkb] Right section of a function

A left section of a binary (two-argument) function is easy to write in Haskell using partial function application: just omit the last (right) argument.  A right section is a little bit more awkward, requiring backquotes, lambda, or `flip`.

```import Data.Function((&)); -- example binary function (not an operator) f2 :: a -> [a] -> [a]; f2 = (:); -- we will use the larger functions later f3 :: Int -> a -> [a] -> [a]; f3 _ = (:); f4 :: Bool -> Int -> a -> [a] -> [a]; f4 _ _ = (:); test :: [String]; test = map (\f -> f 'h') -- all of these evaluate 'h':("el"++"lo") yielding hello [ (`f2` ("el" ++ "lo")) -- backquotes (grave accents) are inline operator syntax. An inline operator followed by an argument, all surrounded by parentheses, is operator right section syntax: one is supposed to imagine a hole in front of the backquotes: (__ `f2` ("el" ++ "lo")) , (\arg1 -> f2 arg1 ("el" ++ "lo")) -- lambda syntax , (\arg1 -> f2 arg1 \$ "el" ++ "lo") , ((flip f2) ("el" ++ "lo")) , ((flip f2) \$ "el" ++ "lo") , (flip f2 \$ "el" ++ "lo") , (flip f2 ("el" ++ "lo")) -- It might be a little surprising that this one works, if one had thought of "flip" as a function taking only one argument, namely the function to be flipped. However, because of currying, it actually takes 3 arguments. flip :: (a -> b -> c) -> b -> a -> c. , ("el" ++ "lo" & flip f2) -- For these 3- and 4-argument cases, we would like to create a lambda on the penultimate argument. -- , (`f3 (2 + 3)` ("el" ++ "lo")) -- This does not work because the contents of the backquotes must be a binary function that is a single token, not an expression. , (let { t2 = f3 (2 + 3) } in (`t2` ("el" ++ "lo"))) , (\penultimate -> f3 (2 + 3) penultimate ("el" ++ "lo")) , (\penultimate -> f3 (2 + 3) penultimate \$ "el" ++ "lo") -- this wordy lambda syntax is one of the best in terms of low parenthesis count and avoiding deep parentheses nesting. , (flip (f3 (2 + 3)) ("el" ++ "lo")) -- similar to "a little surprising" above , (flip (f3 (2 + 3)) \$ "el" ++ "lo") , (flip (f3 \$ 2 + 3) \$ "el" ++ "lo") , ((flip \$ f3 (2 + 3)) \$ "el" ++ "lo") , ((flip \$ f3 \$ 2 + 3) \$ "el" ++ "lo") , ("el" ++ "lo" & (f3 (2 + 3) & flip)) , ("el" ++ "lo" & (2 + 3 & f3 & flip)) , (\penultimate -> f4 (not True) (2 + 3) penultimate ("el" ++ "lo")) , (\penultimate -> f4 (not True) (2 + 3) penultimate \$ "el" ++ "lo"), (let { t2 = f4 (not True) (2 + 3) } in (`t2` ("el" ++ "lo"))) , (flip (f4 (not True) (2 + 3)) ("el" ++ "lo")) , (flip (f4 (not True) (2 + 3)) \$ "el" ++ "lo") , ((flip \$ f4 (not True) (2 + 3)) \$ "el" ++ "lo") , ((flip \$ f4 (not True) \$ 2 + 3) \$ "el" ++ "lo") , ("el" ++ "lo" & (f4 (not True) (2 + 3) & flip)) , ("el" ++ "lo" & (2 + 3 & f4 (not True) & flip)) , ("el" ++ "lo" & (2 + 3 & (not True & f4) & flip)) ];```

`(\f -> f 'h')` could have been written `(\$ 'h')` , a right section itself, but we deliberately avoid being potentially obscure in the test harness.