OCaml 中的一元减号和浮点数

发布于 2024-12-28 18:24:56 字数 579 浏览 0 评论 0原文

我想在我的程序中拥有一个复数向量,所以我写了这样的:

[|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|]

这里 pt 是一个 float ->; 类型的函数。浮动->复杂.t。但是ocaml拒绝编译这个说法:

Characters 12-14:
  [|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|];;
              ^^
Error: This expression has type float -> float -> Complex.t
       but an expression was expected of type int

我在这里想做的是(显然)包含实部为-4、虚部为1的复数。但是ocaml 将我想要的一元减号视为 int 类型的函数 -> int ->int。

我应该写什么来做我想做的事?

I wanted to have a vector of complex numbers in my program, so I wrote this:

[|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|]

Here pt is a function of type float -> float -> Complex.t. But ocaml refused to compile this saying:

Characters 12-14:
  [|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|];;
              ^^
Error: This expression has type float -> float -> Complex.t
       but an expression was expected of type int

What I wanted to do here is (obviously) include the complex number whose real part is -4 and whose imaginary part is 1. But ocaml treated what I intended to be an unary minus as a function of type int -> int ->int.

What should I write to do what I wanted to?

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

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

发布评论

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

评论(1

卸妝后依然美 2025-01-04 18:24:56

这就是我的想法(在阅读文档和实验之后)。确实有四个完全不同的运算符:

-    Integer subtraction        int -> int -> int
-.   Floating subtraction       float -> float -> float
~-   Integer unary negation     int -> int
~-.  Floating unary negation    float -> float

如果每个人都使用这些运算符,事情就会很清楚,但不幸的是,这也是一个非常笨拙的表示法。根据我的经验,~-~-. 运算符很少使用。 OCaml 语法被指定为允许您将减法运算符用作一元否定运算符,就像许多其他语言一样。如果这样做,您通常必须使用额外的括号。如果您愿意使用特定的一元运算符,则不需要括号。

即,您可以编写(如 pad 编辑的答案中所示):

[|pt 0. 0.; pt ~-.4. 1.; pt ~-.7. ~-.2.; pt 4. 5.; pt 1. 1.|]

或者您可以编写:

[|pt 0. 0.; pt (-.4.) 1.; pt (-.7.) (-.2.); pt 4. 5.; pt 1. 1.|]

还有一个额外的令人困惑的因素,即指定 OCaml 词法分析器允许您对一元使用整数减法运算符当您将其与浮动常量一起使用时,会产生否定。同样,这使得符号更像其他语言。由于它本质上是一个二元运算符,因此这里也需要括号。

这意味着您可以编写:

[|pt 0. 0.; pt (-4.) 1.; pt (-7.) (-2.); pt 4. 5.; pt 1. 1.|]

此表示法仅适用于负浮点常量。其他两个符号适用于您可能想要否定的任何表达式。

# (-) ;;
- : int -> int -> int = <fun>
# (-.) ;;
- : float -> float -> float = <fun>
# (~-) ;;
- : int -> int = <fun>
# (~-.) ;;
- : float -> float = <fun>

# let f x = x +. 2.0;;
val f : float -> float = <fun>

# f ~-.5.;;
- : float = -3.

# f -.5.;;
Characters 0-1:
  f -.5.;;
  ^
Error: This expression has type float -> float
       but an expression was expected of type float
# f (-.5.);;
- : float = -3.

# f -5.;;
  ^
Error: This expression has type float -> float
       but an expression was expected of type int
# f (-5.);;
- : float = -3.

Here's how I think it goes (after reading docs and experimenting). There really are four completely different operators:

-    Integer subtraction        int -> int -> int
-.   Floating subtraction       float -> float -> float
~-   Integer unary negation     int -> int
~-.  Floating unary negation    float -> float

If everybody used these operators, things would be clear, but unfortunately it's also a pretty clumsy notation. In my experience the ~- and ~-. operators are rarely used. The OCaml grammar is specified to let you use the subtraction operators as unary negation operators, as in many other languages. If you do that, you often have to use extra parentheses. If you're willing to use the specific unary operators, you don't need the parentheses.

I.e., you can write (as in pad's edited answer):

[|pt 0. 0.; pt ~-.4. 1.; pt ~-.7. ~-.2.; pt 4. 5.; pt 1. 1.|]

Or you can write:

[|pt 0. 0.; pt (-.4.) 1.; pt (-.7.) (-.2.); pt 4. 5.; pt 1. 1.|]

There's also one extra confusing factor, which is that the OCaml lexer is specified to let you use the integer subtraction operator for unary negation when you use it with a floating constant. Again, this makes the notation more like other languages. Since it's fundamentally a binary operator, you need the parentheses here too.

This means you can write:

[|pt 0. 0.; pt (-4.) 1.; pt (-7.) (-2.); pt 4. 5.; pt 1. 1.|]

This notation only works for negative floating constants. The other two notations work for any expression you might want to negate.

# (-) ;;
- : int -> int -> int = <fun>
# (-.) ;;
- : float -> float -> float = <fun>
# (~-) ;;
- : int -> int = <fun>
# (~-.) ;;
- : float -> float = <fun>

# let f x = x +. 2.0;;
val f : float -> float = <fun>

# f ~-.5.;;
- : float = -3.

# f -.5.;;
Characters 0-1:
  f -.5.;;
  ^
Error: This expression has type float -> float
       but an expression was expected of type float
# f (-.5.);;
- : float = -3.

# f -5.;;
  ^
Error: This expression has type float -> float
       but an expression was expected of type int
# f (-5.);;
- : float = -3.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文