Search code examples
polymorphismocamlinfix-operatoradhoc-polymorphism

Define polymorphic infix operator in ocaml


I need to create an operator - that given two strings returns the first string minus all the characters of the second string. For example: "abcd"-"ad"="bc".

While writing random code I noticed that if I assign a new function to the - operator I can't use it again with integers. For example:

# let (-) str1 str2 = (String.length str1) - (String.length str2);;
val ( - ) : string -> string -> int = <fun> 
# 1-2;;
Error: This expression has type int but an expression was expected of type
     string

I'd like to make it so that I can use the - operator between both integers and strings, is this possible in ocaml or do I've to create a custom operator?


Solution

  • OCaml does not support ad-hoc polymorphism, so a given name will have only one definition. If you give the name a new definition it will "shadow" the former, rendering it unusable unless you qualify it to specify which definition you want to use (as long as they're defined in separate modules). An operator is treated no different in this regard, it's just another name, which is why you have to use -. to subtract floats, while - is just for ints.

    Since - is defined in Pervasives, which is always opened, defining your own - operator in a separate module that's opened locally where you want to use it will give you a warning about shadowing, so you'll usually want to avoid overriding existing operators.

    Instead, I'd recommend just defining a different unused operator, like --:

    let (--) str1 str2 = (String.length str1) - (String.length str2);;
    

    You can define any custom operator according to the associativity and precedence of this table