I m new in haskell's world and I m having some troubles with function signatures :
What does it mean in simple worlds :
add:: Integer -> Integer -> Integer
Does it mean that the two first parameters are Integer
and the returned value is Integer
too ?
Can you explain me, the aim of using arrows to determine a type of parameter or at least give me a brief explanation about this function signature ?
From HaskellWiki. A type signature is a line like. inc :: Num a => a -> a. that tells, what is the type of a variable. In the example inc is the variable, Num a => is the context and a -> a is its type, namely a function type with the kind * -> * .
A function signature (or type signature, or method signature) defines input and output of functions or methods. A signature can include: parameters and their types. a return value and type. exceptions that might be thrown or passed back.
In b Bool , b stands for a parametrized type that takes one type parameter (in Haskell parlance, b is a type constructor of kind * -> * ), such as Maybe , IO or [] . So a function of type a -> b Bool could for example take an Int and produce a Maybe Bool , IO Bool , [Bool] etc.
Functions can also be passed as arguments or returned (as we have seen). Their types are given in the type signature. *Main> :t map map :: (a -> b) -> [a] -> [b] *Main> :t filter filter :: (a -> Bool) -> [a] -> [a] flip_args :: (a -> b -> c) -> b -> a -> c flip_args f x y = f y x.
Colloquially we may indeed refer to add
as a function that takes two Integer
s and produces an Integer
. However to understand the notation, you need to understand that technically there's no such thing as a function that takes two arguments in Haskell.
Rather every function takes exactly one argument and the type of a function is written a -> r
where a
is the type of the argument and r
is the type of the result. The function arrow is right-associative, which means that the type a -> (b -> c)
can be written without parentheses as a -> b -> c
.
So Integer -> Integer -> Integer
is the same as Integer -> (Integer -> Integer)
, which tells us that add
is a function that takes an Integer
and produces another function of type Integer -> Integer
. This is known as currying and is the usual way to "encode" multi-argument functions in Haskell.
To call such a curried function, we can write add 1 2
, which, because function application is left associative, is the same as (add 1) 2
, first calling add 1
to get a function of type Integer -> Integer
and then applying that function to the argument 2
.
As a simple mental model - yes, the thing after the last arrow is a return type, and everything else are parameters.
Signatures for 2-and-more-ary functions look this way because they are actually unary functions returning another 1-and-more-ary function.
In your case
add :: Integer -> (Integer -> Integer)
Passing add
an argument gives
add 3 :: (Integer -> Integer)
And add 3 4
, therefore is just Integer
type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With