The components of a [[Functions|function]] definition:
- [[Type Signature|type signature]] (optional)
- 1 or more "implementations" of the type signature, each with
  - function name
  - 0 or more arguments
  - return expression

### Name
function names can contain any alphanumeric character, `_`, `'` but the first character must be a lowercase alpha or `_`.

### Arguments
Arguments are space-separated variable names between the function name and `=`.


For example, the first [[Int]] argument is bound to `a`, the second to `b`.
```haskell
add :: Int -> Int -> Int
add a b = -- ...
```

### Body
The expression returned by the function.

For example `a + b` is the body in:
```haskell
add a b = a + b
```

### Examples

A constant (function with 0 arguments)
```haskell
a :: String
a = ""
```

A function with a `String` argument, returning a `String`. The `String` argument is bound to `s` in the return expression `s <> ""`.
```haskell
a :: String -> String
a s = s <> "."
```

> [!tip]
> The simpler language "String to String" is often used instead of ".. with a String argument, returning a String."
> 
> You can replace the function arrow `->` with the word "to"; For example `f :: a -> b -> c` is said as "f is a to b to c."

An implementation of fizzbuzz of type `Int` to `Maybe String`.

The body uses [[let .. in ..]] to define 2 helper functions:
- `divisible :: Int -> Boolean`
- `go :: Maybe String`

Returns `go`.
```haskell
fizzBuzz :: Int -> Maybe String
fizzBuzz n = 
  let
    divisible a = n `mod` a == 0
    go
      | divisible 2 && divisible 5 = Just "fizzbuzz"
      | divisible 2 = Just "fizz"
      | divisible 5 = Just "buzz"
      | otherwise = Nothing
  in
    go
```
