The numerical operators
/ behave largely as you'd expect. (Division works only on fractional numbers to avoid rounding issues – integer division must be done with
div). More unusual are Haskell's three exponentiation operators:
4^5 ≡ (4*4)*(4*4)*4
^^ does the same in the positive case, but also works for negative exponents. E.g.
3^^(-2) ≡ 1 / (2*2)
^, this requires a fractional base type (i.e.
4^^5 :: Int will not work, only
4^5 :: Int or
4^^5 :: Rational).
** implements real-number exponentiation. This works for very general arguments, but is more computionally expensive than
^^, and generally incurs small floating-point errors.
2**pi ≡ exp (pi * log 2)
There are two concatenation operators:
: (pronounced cons) prepends a single argument before a list. This operator is actually a constructor and can thus also be used to pattern match (“inverse construct”) a list.
++ concatenates entire lists.
[1,2] ++ [3,4] ≡ 1 : 2 : [3,4] ≡ 1 : [2,3,4] ≡ [1,2,3,4]
!! is an indexing operator.
[0, 10, 20, 30, 40] !! 3 ≡ 30
Note that indexing lists is inefficient (complexity O(n) instead of O(1) for arrays or O(log n) for maps); it's generally preferred in Haskell to deconstruct lists by folding ot pattern matching instead of indexing.
$ is a function application operator.
f $ x ≡ f x ≡ f(x) -- disapproved style
This operator is mostly used to avoid parentheses. It also has a strict version
$!, which forces the argument to be evaluated before applying the function.
. composes functions.
(f . g) x ≡ f (g x) ≡ f $ g x
>> sequences monadic actions. E.g.
writeFile "foo.txt" "bla" >> putStrLn "Done." will first write to a file, then print a message to the screen.
>>= does the same, while also accepting an argument to be passed from the first action to the following.
readLn >>= \x -> print (x^2) will wait for the user to input a number, then output the square of that number to the screen.