Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does function application with the $ operator curry in Haskell?

I am learning haskell and am a little confused how the function application operator $ curry's.

According to GHC the type of $ is

*Main>:t ($)
($) :: (a->b) -> a -> b

But I can type the following code

*Main>map ($ 2) [(*2), (+2), (/2)]
[4.0,4.0,1.0]

According to the signature of $ though I would assume I would need to use the flip function because the first parameter to $ is (a->b).

For example, I can't do the following

curry_test :: Integer -> String -> String
curry_test x y = (show x) ++ " " ++ y
*Main> let x = curry_test "123"
    Couldn't match expected type `Integer' with actual type `[Char]'
In the first argument of `curry_test', namely `"123"'
In the expression: curry_test "123"
In an equation for `x': x = curry_test "123"

But I can do

let x = curry_test 2
like image 260
user1840624 Avatar asked Jul 08 '13 15:07

user1840624


People also ask

What is the use of function currying?

Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.

What does the operator do in Haskell?

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).

Are curried functions closures?

Curried functions are constructed by chaining closures and immediately returning their inner functions simultaneously.


1 Answers

Infix operators have special rules. See this page: http://www.haskell.org/haskellwiki/Section_of_an_infix_operator

Basically, since $ is an infix operator, ($ 2) actually fixes 2 as the second argument of $, so it is equivalent to flip ($) 2.

The idea is to make partial application with operators more intuitive, so for example if you map (/ 2) over a list, you can imagine putting each element of the list in the "missing" spot on the left side of the division sign.

If you want to use your curry_test function this way, you could do

let x = (`curry_test` "123")
like image 117
Jeff Burka Avatar answered Oct 23 '22 16:10

Jeff Burka