Functions and application

Contents
Define a function
Application is a space
Precedence
if is an expression

Define a function

A definition is a name, the arguments, an equals sign, and a body. No parentheses, no commas, no return keyword:

greet :: String -> String greet name = "Hello, " ++ name ++ "!" -- greet "Ada" == "Hello, Ada!"

The body is one expression. Where other languages need a block of statements, Haskell needs a let or a where to name the intermediate values.

Application is a space

Calling a function means writing it next to its argument. Juxtaposition binds tighter than any operator, so parentheses are needed around compound arguments:

show 42 -- "42" show (42 + 1) -- "43" max 3 9 -- 9 max 3 (min 9 4) -- 4

show turns a value into its textual form, and read goes the other way. The pair is how Haskell talks to the outside world without a formatting library.

Precedence

Arithmetic keeps the precedence you already know, and function application sits above all of it. The two rules that surprise newcomers are unary minus and the low precedence of $:

2 + 3 * 4 -- 14 negate 3 + 4 -- 1, application first putStrLn $ show (2 + 3) -- same as putStrLn (show (2 + 3))

$ is a function that applies what is on its left to what is on its right, and it has the lowest precedence. It removes a trailing pair of parentheses, nothing more.

if is an expression

if produces a value, so the else branch is mandatory. Both branches must have the same type:

sign :: Int -> String sign n = if n < 0 then "negative" else "not negative" label = sign 5 ++ " number"

Because if is an expression, an if without else is a type error, not a style problem. When a chain of conditions grows past two branches, guards read better, and lesson 10 covers them.

Next: Currying and partial application

Article author: Arthur Isaev

Related articles
Haskell
Haskell course: zero to hero in 50 lessons
What is Haskell and why it matters
Install the toolchain with GHCup
GHCi: the interactive shell
Your first program
Values with let and where
Types and type signatures
Functions and application
Currying and partial application
Operators, sections, and fixity
if, guards, and pattern guards
case expressions
Pattern matching
Tuples
Lists
Ranges and enumeration
List comprehensions
Recursion replaces loops
map, filter, and foldr
Lambdas and composition
Type classes
Parametric polymorphism
Maybe and null safety
Either and recoverable errors
data: product types
data: sum types
Records
newtype and type synonyms
Recursive data: binary trees
Functor
Applicative
Monad
do notation
IO and purity
Files and IO
Modules and imports
Cabal projects
Dependencies
Testing with HUnit
Property testing with QuickCheck
Laziness and infinite lists
Strictness and space leaks
Folds
Monoids
Traversable
Monad transformers
Errors and exceptions
Concurrency
Parsing with Megaparsec
Capstone: a todo CLI
Hero roadmap: the whole course on one page

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: