The answer is that types can tell you what your code does. Even nontrivial functions
can often have types that fit on a single line (and that are quite easy to read).
For example, given a function `typecheck`, you could try figure out what it returns by reading
the code, or by meditating on its name. Or, you could read its type:
```Haskell
typecheck :: Expr -> Either Error Type
```
This can be read "given an expression, `typecheck` returns either an error or a type".
Now you know what to expect when calling the function, what arguments it needs,
and you have some idea of what it does. You get all this without ever looking
at the code. As another example, the function `partition` has the following type:
```Haskell
partition :: (a -> Bool) -> [a] -> ([a], [a])
```
This one reads, "given a function that returns true or false, and a list, `partition` returns two lists".
It's not too hard to infer that `partition` divides the given list into two, one list
for items that made the input function true, and one for those that made it false. I say this
without having read a word of `partition`'s documentation, and having never seen its code.
The type is enough to convey that information.
There's more. Types, when viewed in this way, don't just help you understand code you already
have. They can also be used to _find_ code that does what you want. This is the idea behind
[Hoogle](https://hoogle.haskell.org/). Here's an example.
Suppose I have a list of people's middle names. A middle name is just a string (`String` in Haskell).
Not everyone has a middle name, though. To represent a value that may or may not be present,
we can use the `Maybe` type constructor. A list of people's middle names, then, would have
the type `[Maybe String]`, a list of (potentially absent) strings. Now, suppose I wanted to take
this list, and filter out all of the absent middle names, resulting in just a list of strings, `[String]`.
Do I have to do this myself, or is there a function for it? I put a type signature into Hoogle:
```Haskell
[Maybe String] -> [String]
```
Hoogle responds with a function that fits the search, in the `Data.Maybe` module:
```Haskell
catMaybes : [Maybe a] -> [a]
```
Looks like I don't have to implement it myself after all! When working with Haskell,
I consult Hoogle a lot of figure out the names of existing functions that match my needs.
I singled out Haskell in this section, but types in a variety of other languages
make for great documentation. When I wrote Rust code, the types were very useful to
understanding how to use a crate; check out the
[documentation page for `Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html), for instance.
Documentation of Elm packages always lists functions' types (see [documentation for `Parser`](https://package.elm-lang.org/packages/elm/parser/latest/Parser), for example). Even C++ type signatures
listed by Doxygen can be quite useful; I, for one, got a lot out of the [LLVM documentation](https://llvm.org/doxygen/classllvm_1_1IRBuilderBase.html).