Shayan C
Shayan C

Reputation: 1580

haskell functions declaration

I am having problem understanding signatures/arguments/inputs of Haskell functions. Before anyone complains, yes I have done my research but can not seem to find a good answer or explanation.

basically I have a function :

update :: Eq a => (a->b) -> b -> a -> (a->b)

How do I make sense of (a->b) -> b -> a -> (a->b)? I see it as taking an input of a function followed by 2 values and outputting a function??

I have 2 different functions which do same thing, one which uses 3 arguments and one with 4 but the header (arguments of function) is same.

(1)

update :: Eq a => (a->b) -> b -> a -> (a->b)
update s v x y = if x==y then v else s y

(2)

update :: Eq a => (a->b) -> b -> a -> (a->b)
update s v y = ss
  where ss x = if ( x == y )
                 then v
                 else s x

They both compute same thing but I do not understand why (1) uses 4 inputs "update s v x y" and (2) "update s v y" uses 3 inputs.

Any help will be greatly appreciated.

Upvotes: 2

Views: 231

Answers (1)

daniel gratzer
daniel gratzer

Reputation: 53871

Welcome to the wonderful world of currying.

Let's start with a simple function

allEq :: Int -> Int -> Int -> Bool
allEq x y z = x == y && y == z

Now in Haskell -> is right associative, so this is

allEq :: Int -> (Int -> (Int -> Bool)))
allEq x y z = x == y && y == z

allEq x y = \z -> x == y && y == z
allEq x = \y -> \z -> x == y && y == z
allEq = \x -> \y -> \z -> x == y && y == z

Now, in Haskell we know that we can "lift" an expression into a let or where binding without changing it.

 allEq x y = foo
   where foo z = x == y && y == z

And this is how we get to your function.

Upvotes: 6

Related Questions