Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read "Num (a -> b -> a) => a -> [b] -> a" definition

Tags:

haskell

I'm trying to get my head around Haskell function definitions. I took foldl function with it's definition being

:t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

Now the first argument is a function, so if I pass it, here's what's left:

:t foldl (+)
foldl (+) :: Num b => b -> [b] -> b

which I read as "a function that takes a numeric value and returns function that takes an array".

Now, is first argument really a function? Can it be read as

foldl :: a -> b -> a -> a -> [b] -> a

instead?

I tried passing just one numeric value, and here's what I've got:

foldl 4 :: Num (a -> b -> a) => a -> [b] -> a

And the question is.. How do you read this? I do not understand what I've got.

like image 208
Alehar Avatar asked Oct 07 '13 09:10

Alehar


2 Answers

The first argument is a function and hence it cannot be read as: foldl :: a -> b -> a -> a -> [b] -> a. Because the -> is right associative which means a -> b -> c is a -> (b -> c) and that is different from (a -> b) -> c

like image 113
Ankur Avatar answered Sep 20 '22 19:09

Ankur


The 'Num' became mixed up in this is because you passed (+) to foldl. So you created a function with signature

foldl (+) :: Num b => b -> [b] -> b

Which is a function which takes a Numeric and a list of Numerics and returns a Numeric.

Num b => b 

does not mean "A function that that returns a numeric - that is what it would mean in Scala. Num b means that all instances of b in the rest of this signature are Numeric. It's how a type annotation is done in Haskell.

foldl :: (a -> b -> a) -> a -> [b] -> a

Indicates a function which takes 3 arguments (one of which is a function ) and returns a value of the same type as the second argument. Running through the signature...

  1. The first argument is a function which itself takes two arguments and returns a value of the same type as the first argument. It is in brackets to show that it is just one argument and a function - the thing within brackets is its function signature. Let's call this function func
  2. The second argument can be anything as long as it is the same type as the first argument taken by func.
  3. The third argument has to be a sequence of the same type as the second argument taken by func
  4. The result has to be of the same type as the second argument (and the first argument taken by func).

Those are the only expectations foldl has of the arguments. We see a and b in the signature because we can have different types as the first and second arguments to func, but a and b can be of any type including both being the same type. But when you pass a function to foldl, creating a new function which applies func to the remaining arguments, you add the type expectations of whatever func is. Since you passed in a numeric function, that type annotation is added to the resulting signature. And since + expects both arguments to be numeric, we only see one type variable in the signature (just b, not a and b).

like image 27
itsbruce Avatar answered Sep 21 '22 19:09

itsbruce