protocols, functors and type classes