运算符操作数类型不匹配

operator operand type mismatch

我有这个代码片段

fun decrement_to_zero r = if !r < 0
                          then r := 0
                          else while !r >= 0 do r := !r - 1

来自本教程

https://learnxinyminutes.com/docs/standard-ml/

但是我得到这个错误:

stdIn:1.2-33.9 Error: operator and operand don't agree [literal]
  operator domain: int ref
  operand:         int
  in expression:
    decrement_to_zero 10

当我用

调用它时

- decrement_to_zero 10;

为什么?

Why?

如果您检查函数的类型签名,

- decrement_to_zero;
> val it = fn : int ref -> unit

您可以确认其输入类型与10 : int不一致。但是如果你创建一个 int ref,

- val foo = ref 10;
> val foo = ref 10 : int ref

并将其传递给您的函数,

- decrement_to_zero foo;
> val it = () : unit

您会看到引用已更新,但不会为零,

- foo;
> val it = ref ~1 : int ref

所以这个函数的名字选择和写的很糟糕。自从我最初编写该教程以来,似乎出现了很多错误。

尽管标准 ML 支持引用,但编写纯函数通常更为惯用。纯函数仅将值作为输入,将 returns 值作为输出,但不会影响函数外部的世界(例如引用 foo 在任何给定时间点指向的内容)。例如,

fun actually_decrement_to_zero n =
    if n > 0 then actually_decrement_to_zero (n-1) else n

并使用这个,

- actually_decrement_to_zero 10;
> val it = 0 : int

如您所见,结果直接来自函数,而不是通过引用间接产生。