A bit about Haskell Currying
Reading M. Lipovac “Study Haskell for Good!”, At first I did not understand how partial application differs from currying . Spent some time analyzing this issue and scribbled a "cheat sheet" on the topic.
In Haskell, functions without parameters are called definitions or names .
Functions cannot take more than one parameter. If a function takes several parameters, then in fact it is a function with one parameter and returns another function that also takes only one parameter and returns some result ( another function or a specific value ). if the function has the following signature:
then Haskell interprets it as follows:
Those. the func function takes an argument of type Int and returns a new function that takes the next argument - of type Double and returns another new function that takes an argument of type Char and returns a value of type Bool.
Converting a function from many arguments to a function that takes its arguments one at a time is called currying. Haskell automatically curries all functions that take more than one parameter. It is thanks to currying that partial application of functions becomes possible , as well as the creation of sections . In turn, partial application makes possible the existence of pointless notation .
Partial Application:
Sections:
Pointless notation:
ghci:
The following functions are defined in the standard Data.Tuple module:
The curry function converts a non-curried function to a curried function.
The uncurry function converts a curried function to an uncurried function.
In Haskell, functions without parameters are called definitions or names .
func :: String
func = "Haskell"
Functions cannot take more than one parameter. If a function takes several parameters, then in fact it is a function with one parameter and returns another function that also takes only one parameter and returns some result ( another function or a specific value ). if the function has the following signature:
func :: Int -> Double -> Char -> Bool
then Haskell interprets it as follows:
func :: Int -> (Double -> (Char -> Bool))
Those. the func function takes an argument of type Int and returns a new function that takes the next argument - of type Double and returns another new function that takes an argument of type Char and returns a value of type Bool.
Converting a function from many arguments to a function that takes its arguments one at a time is called currying. Haskell automatically curries all functions that take more than one parameter. It is thanks to currying that partial application of functions becomes possible , as well as the creation of sections . In turn, partial application makes possible the existence of pointless notation .
Note
There is no such thing as a partial use of a function in Haskell . There is an application of the function (without "partially"). If we say (for convenience of perception) that a functionf :: Int -> Int -> Int
has two arguments (which is technically not correct), then we can say the same (again for convenience of perception) thatf 5
this is a partially applied function (which is also not will be technically correct).
Example
func :: (Num a) => a -> a -> a -> a
func a b c d = a + b + c + d
ghci
Partial Application:
λ: let n = func 2 3
λ: let m = n 10
λ: let g = m 7
λ: g
22
Sections:
λ: let a = (/2)
λ: a 10
5.0
λ: let b = (15/)
λ: b 5
3.0
Pointless notation:
odd' :: Integral a => a -> Bool
odd' = odd
ghci:
λ: odd' 5
True
λ: odd' 4
False
Currying and Decarring
The following functions are defined in the standard Data.Tuple module:
curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c
The curry function converts a non-curried function to a curried function.
The uncurry function converts a curried function to an uncurried function.
Example
msg :: Int -> Bool -> String
msg n True = show $ n `div` 2
msg n _ = show $ n * 2
ghci
λ: let n = msg
λ: let m = uncurry n
λ: :t n
n :: Int -> Bool -> String
λ: :t m
m :: (Int, Bool) -> String
λ: n 5 True
"2"
λ: m (5,True)
"2"
λ: let k = curry m
λ: :t k
k :: Int -> Bool -> String
λ: k 5 True
"2"