OCaml : why comparison operator are type agnostic, whereas arithmetic ones are not?

人盡茶涼 提交于 2019-12-04 00:59:41

问题


I am wondering why < operator supports int, string, bool, or float, whereas + only support int.

Could OCaml recognize the underlying arithmetic to use ? What makes comparison operator different from arithmetic ones ? Is it the same for other FP language ?


回答1:


Comparison operators are special in OCaml. They are able to compare records, variant types, lists and other data structures recursively.

They by-pass a type system (hope I formulated it correct), and have a special support in runtime. I would recommend to read this post about OCaml polymorphic comparison.

Comparison operators <, >, <>, = have the same signature:

'a -> 'a -> bool

And they always return bool regardless of type of input arguments. So, these operators may have polymorphic behavior and don't require additional support by type system for type inference:

The type of the function less

let less a b = a < b

is automatically deducted to

val less : 'a -> 'a -> bool = <fun>

At the same time, return type of arithmetic operators depends on type of arguments:

# let plus a b = a + b;;
val plus : int -> int -> int = <fun>

See, you can't automatically inference type of a + b expression in case of polymorphic + operator. Type system should be extended to support this.

F#

# let plus a b = a + b
val plus : a:int -> b:int -> int

It is deducted to int by default. To be able to write plus function for floats, you need to add explicit type annotation to at least one of input argument:

# let plus (a:fl­oat) b = a + b
val plus : a:float -> b:float -> float

If you add inline you can get even more:

# let inline plus a b = a + b
val inline plus :
  a: ^a -> b: ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

This version will work for both int and float (and any other type(-combination) that has a static member (+))

Haskell

# let plus a b = a + b
plus :: Num a => a -> a -> a

Return and argument types of plus function are automatically inferred to any type of Num type class. It means that plus is truly polymorphic and can be used with ints, floats and other numeric types.

OCaml

So, it can be yet another special case (like in F#), or full-featured solution like Haskell's type classes. I vote for the latter.

There is a fork of OCaml that addresses this problem by extending it with modular implicits.




回答2:


There is not, at the moment, a notion of "a bit polymorphic" in OCaml (the technical name is "ad-hoc polymorphism"). You can't say "I accept integers and floats but not the rest".

You can say, however "I accept everything", just like the comparison operator (the technical name is "parametric polymorphism"). Do note however than they are lying a bit about that: you can't compare functions, even if the type system can't catch it.

See this answer for details.



来源:https://stackoverflow.com/questions/33413163/ocaml-why-comparison-operator-are-type-agnostic-whereas-arithmetic-ones-are-n

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!