Haskell is a purely functional language. However side-effects are (almost by definition) difficult to incorporate into a functional language. This is an important problem since I/O is a very important side-effect for most computer programs. Haskell's method of incorporating side-effects is to use monads.
One of the simplest ways to get a monad is from a pair of adjoint functors.
For more on monads see:
(1) Embûches tissues blog: Monads in Mathematics 1: examples
(2) A series of lectures on youtube by TheCatsters:
Pairs of adjoint functors are fairly common and I've found they provide a useful way for seeing part of the "big-picture" in many different branches of mathematics.
Here is one of several introductions to pairs of adjoint functors from the Concrete Nonsense blog.