Las*_*olt 13 f# ocaml types inline
我刚刚了解到OCAML必须有一个.
用于执行浮点运算的后缀.一个例子是3. +. 4.
equals 7.
(float).但是,F#以相同的方式处理浮点和整数运算,因此3 + 4
(int)和3. + 4.
(float)都有效.
F#+
自然分配给int,因此let add a b = a + b
属于类型int -> int -> int
.确实(+)
给了我val it : (int -> int -> int) = <fun:it@6-1>
.
这导致了以下序列,我认为这非常违反直觉:
> 3. + 4.;;
val it : float = 7.0
> (+);;
val it : (int -> int -> int) = <fun:it@8-2>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是: "重载"是否由编译器中的特殊机制/案例完成,或者这是一个语言范围的事情所以我可能可以定义一个名为add
(或其他任何)的函数,它具有一个整数和一个定义浮子(或任何其他类型).
Bri*_*ian 12
简而言之,F#通过inline
关键字和"静态成员约束" 具有ad-hoc重载机制.内置数学运算符还有一些特殊的魔力,它神奇地假定类型int
没有其他约束. (+)
在所有F#中,它只是最特殊/最神奇的东西,因此它不能很好地介绍语言/类型系统.
通常,对于静态类型的类型推断语言来说,"重载"是困难的.F#在这里的选择非常务实.OCaml做了一个不同的,简单的,实用的东西(没有重载).Haskell做了一个不同的,复杂但优雅的东西(类型类).它们在语言/库设计领域都是有点合理的.
必须inline
在F#中标记重载的函数(和运算符).这是因为它们依赖于显式成员约束.这些约束在编译时解决.的函数let inline add a b = a + b
的类型为'a -> 'b -> 'c (requires member (+))
,其中+
是静态函数/操作者.你不能用C#做到这一点; 它没有静态成员约束.
let inline add a b = a + b
add 1 2 //works
add 1.0 2.0 //also works
Run Code Online (Sandbox Code Playgroud)