When it comes to functions, there&#x27;s ad hoc polymorphism, and there&#x27;s parametric polymorphism.<p>Parametric polymorphism is when you can define a function without knowing the precise type of its parameters. However, this limits what you can actually do with the parameters.<p>For instance, a function concat([a], [a]) -&gt; [a] which takes two lists containing items of type &quot;a&quot; knows enough about the type of its parameters (they&#x27;re lists) to do its job, but it doesn&#x27;t know everything about them. This is the type of polymorphism OCaml supports. Think of it as &quot;one implementation, many types&quot;. That&#x27;s why OCaml has more than one print function, and why it has integer and floating point versions of operators like + and *.<p>Ad hoc polymorphism is when you can define implementations for a single function for whatever types you like. So you can implement add(Int, Int) -&gt; Int, as well as add(Float, Float) -&gt; Float. So this is &quot;many implementations, many types.&quot; Haskell supports a version of this through typeclasses. OCaml doesn&#x27;t currently support it, but the new &quot;modular implicits&quot; feature, as I understand it, will provide largely the same functionality.