Function declarations in Haskell rely less on parentheses and more on whitespace relative to many other languages.
Here we define a function which returns a number that is one greater than its argument.
A basic function definition begins with:
- the name of the function (in this case,
next), followed by a space;
- the parameters (here just one parameter,
Function and parameter names begin with lowercase letters.
= x + 1next x
If there is more than one parameter, they are separated with whitespace. This hypotenuse function requires two arguments,
= sqrt (x^2 + y^2)hypotenuse x y
In many cases, annotating a function definition with its type is unnecessary. In
greet, the compiler can infer that since we are concatenating the argument called
name with a string, then the type of
name must be
String and the result returned from the function is also a
= "hello" ++ " " ++ namegreet name
But explicit type annotations are often useful.
- The function name is followed by
- the type of each parameter is given followed by an arrow;
- the final type is the return type.
greet2 takes one
String argument, referred to in the function definition by the parameter
name, and returns one
Type names always begin with an uppercase letter.
greet2 :: String -> String = "hello" ++ " " ++ namegreet2 name
Functions can return multiple values. The
greetNext function returns a tuple of two values:
greet (show (next x))
= (next x, greet (show (next x)))greetNext x
Pattern matching is another useful way to define functions. Here we define a function called
hello that has three cases:
- the first applies only when the argument is
- the second when the argument is
- the third is a fallback that matches anything else.
hello :: String -> String "Olafur" = "hello, Olafur!" hello "Rocamadour" = "hey!" hello = greet xhello x
= main do
show function converts values that are not strings into strings that we can print to the screen or otherwise use in string-manipulating functions.
putStrLn (show (next 4)) putStrLn (show (next (next 4))) putStrLn (show (hypotenuse 3 4))
greet2 already return
String values, we do not need to use
putStrLn (greet "world") putStrLn (greet2 "world")
We can treat the result from
greetNext as a single value.
putStrLn (show (greetNext 7))
Or we can immediately destructure it and give names (
y) to its two constituent parts.
let (x, y) = greetNext 7 putStrLn (show x) putStrLn y putStrLn (hello "Olafur") putStrLn (hello "Rocamadour") putStrLn (hello "Jane")
$ runhaskell functions.hs 5 6 5.0 hello world hello world (8,"hello 8") 8 hello 8 hello, Olafur! hey!hello Jane