F# 中的加法类型 (+)

发布于 2024-11-14 17:01:09 字数 684 浏览 3 评论 0原文

我刚刚了解到 OCAML 必须有一个 . 后缀才能进行浮点运算。例如 3。 +。 4. 等于 7.(浮点数)。但是,F# 以相同的方式处理浮点和整数算术,因此 3 + 4 (int) 和 3. + 4.(浮动)有效。

F# 将 + 自然地分配给 int,因此 let add ab = a + b 的类型为 int ->整数-> int。事实上,(+) 给了我val it:(int -> int -> int) =

这导致了以下序列,我认为这是非常违反直觉的:

> 3. + 4.;;
val it : float = 7.0
> (+);;
val it : (int -> int -> int) = <fun:it@8-2>

所以我的问题是:“重载”是由编译器中的特殊机制/情况完成的还是这是一个语言范围的事情所以我可能可以定义一个名为 add (或其他任何东西)的函数,它有一个整数定义和一个浮点数(或任何其他类型)定义。

I just learned that OCAML have to have a . postfix for doing float arithmetic. An example would be 3. +. 4. which equals 7. (float). However, F# handles float and integer arithmetic in the same way, so both 3 + 4 (int) and 3. + 4. (float) works.

F# have + naturally assigned to int so let add a b = a + b is of type int -> int -> int. And indeed (+) gives me val it : (int -> int -> int) = <fun:it@6-1>.

That leads to the following sequence which I think quite counter-intuitive:

> 3. + 4.;;
val it : float = 7.0
> (+);;
val it : (int -> int -> int) = <fun:it@8-2>

So my question is: Is the "overloading" done by a special mechanism/case in the compiler or is this a language-wide thing so I potentially can define a function called add (or anything else) which have a one definition for integers and one for floats (or any other type.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

子栖 2024-11-21 17:01:09

简而言之,F# 通过 inline 关键字和“静态成员约束”具有临时重载机制。还有一些特定于内置数学运算符的进一步魔法,它神奇地假定类型 int 不存在其他约束。 (+) 是所有 F# 中最特殊/最神奇的东西,因此它并不能很好地介绍语言/类型系统。

一般来说,“重载”对于静态类型、类型推断的语言来说是很困难的。 F# 在这里的选择非常务实。 OCaml 做了一件不同的、简单的、务实的事情(没有重载)。 Haskell 做了一件不同的、复杂但优雅的事情(类型类)。它们都是语言/库设计领域中有些合理的观点。

Briefly, F# has an ad-hoc-overloading mechanism via the inline keyword and "static member constraints". There is some further magic specific to the built-in math operators, which magically assumes type int the absence of other constraints. (+) is just about the most special/magical thing in all of F#, so it does not make for a nice introduction to the language/type system.

In general, "overloading" is difficult for statically-typed, type-inferred languages. F#'s choices here are very pragmatic. OCaml does a different, simple, pragmatic thing (no overloading). Haskell does a different, complex-but-elegant thing (type classes). They're all somewhat reasonable points in the language/library design space.

握住我的手 2024-11-21 17:01:09

重载函数(和运算符)必须在 F# 中标记为内联。这是因为它们依赖于显式成员约束。这些约束在编译时得到解决。函数 let inline add ab = a + b 的类型为 'a ->; 'b-> 'c(需要成员 (+)),其中 + 是静态函数/运算符。在 C# 中你不能这样做;它没有静态成员约束。

let inline add a b = a + b
add 1 2 //works
add 1.0 2.0 //also works

Overloaded functions (and operators) must be marked inline in F#. This is because they depend on explicit member constraints. Those constraints are resolved at compile time. A function let inline add a b = a + b has the type 'a -> 'b -> 'c (requires member (+)) where + is a static function/operator. You can't do this in C#; it doesn't have static member constraints.

let inline add a b = a + b
add 1 2 //works
add 1.0 2.0 //also works
心在旅行 2024-11-21 17:01:09

除了布莱恩的回答和链接:

https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs

我在代码中找到了一些定义

let inline (+) (x:int) (y:int) = (# "add" x y : int #)

let inline (+) (x: ^T) (y: ^U) : ^V = 
     AdditionDynamic<(^T),(^U),(^V)>  x y 
     when ^T : int32       and ^U : int32      = (# "add" x y : int32 #)
     when ^T : float       and ^U : float      = (# "add" x y : float #)
     when ^T : float32     and ^U : float32    = (# "add" x y : float32 #)
     ...

AdditionDynamic 在这里定义(大量静态内容和 CIL):
https://github.com /fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs#L2374

有趣的东西:

(# "add" 1 2 : int32 #)

有效,并给出 3 作为输出(警告说你不应该这样做。)

In addition to Brian´s answer and link:

https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs

I found some definitions in the code:

let inline (+) (x:int) (y:int) = (# "add" x y : int #)

and

let inline (+) (x: ^T) (y: ^U) : ^V = 
     AdditionDynamic<(^T),(^U),(^V)>  x y 
     when ^T : int32       and ^U : int32      = (# "add" x y : int32 #)
     when ^T : float       and ^U : float      = (# "add" x y : float #)
     when ^T : float32     and ^U : float32    = (# "add" x y : float32 #)
     ...

And the AdditionDynamic is defined here (loads of static stuff and CIL):
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs#L2374

Fun stuff:

(# "add" 1 2 : int32 #)

works, and gives 3 as output (with a warning saying you shouldn't do this.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文