Why does the exponential operator use float variables in OCaml?
为什么指数运算符在 OCaml 中使用浮点变量?
它不应该也允许 int 变量吗?
1 2 3
| # 3**3;;
Error : This expression has type int but an expression was expected of type
float |
作品:
1 2
| # 3.0**3.0;;
- : float = 27. |
- 即使它想允许 int 变量,它也不能允许,原因与在加法的情况下,为 int 和 float 有效定义的操作相同的原因,float 版本 +.不允许 int 参数。这是为了启用类型推断而进行的权衡。 Hindley-Milner 类型系统的扩展是必要的(并且已经设计了一些)以允许 5.0 + 5.0 和 5 + 5。 OCaml 的最短版本在实践中是可以接受的:对于最近的版本,您可以使用类似 Float.(5.0 + 5.0) 的东西。
-
看看这个类似的问题:stackoverflow.com/questions/16950687/...
因此,现有的答案涉及如何解决这个问题,但没有涉及为什么会这样。主要有两个原因:
1) OCaml 没有操作符别名。你不能有两个操作符做"同样的事情",但是不同的类型。这意味着只有一种数字、整数或浮点数(或其他一些表示)可以使用标准 ** 接口。
2) pow(),幂函数历来是在浮点数上定义的(例如,在标准 C 中)。
此外,对于解决该问题的另一种方法,如果您使用包含 OCaml 电池,则有一个为整数定义的 pow 函数。
你可以使用 int
- 我对 Ocaml 有点陌生......你能解释一下这部分吗? |> int_of_float 我不知道它为什么在那里,或者它做什么。谢谢。
-
哦,好的,刚知道...但为什么会出错? # let int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float;;让 int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float;;错误:未绑定值|>
-
@SadSeven |> 运算符包含在 Core 等库中。自 v. 4.01 起,它也直接包含在语言中。
-
@Beno?t Guédas 我很困惑......我必须包括图书馆吗?我有旧版本的口译员吗?如何修复错误?
-
@SadServen 要知道您的版本,只需输入 ocaml -version。你不需要这个运算符,你可以简单地写 let int_exp x y = int_of_float ((float_of_int x) ** (float_of_int y))
-
@SadSeven Benoit 的评论都是正确的。 realworldocaml.org 是您真正开始学习 OCaml 的地方
有一个类似的问题:OCaml 中的整数取幂
这是整数取幂的一种可能的尾递归实现:
1 2 3 4 5 6 7 8 9 10 11 12
| let is_even n =
n mod 2 = 0
(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
if exponent < 0 then invalid_arg"exponent can not be negative" else
let rec aux accumulator base = function
| 0 -> accumulator
| 1 -> base * accumulator
| e when is_even e -> aux accumulator (base * base ) (e / 2)
| e -> aux (base * accumulator ) (base * base ) ((e - 1) / 2) in
aux 1 base exponent |