There are just a few tiny pieces missing from the puzzle: the functor and monad laws. They're pretty straight-forward - one would think they're common sense.
For functor, there is the mapping with identity law:
functor.map({ $0 }) == functor
which says that mapping the identity function over a functor results with a value equal to the one we started with
and the law for compositionality
functor.map({ f2(f1($0)) }) == functor.map(f1).map(f2)
which states that mapping a composite function yields the same result as mapping the first function then mapping the second function onto the result of the first map.
For monad, there are 3 additional laws (left identity, right identity and associativity).