sml语法很难查找文档

时间:2011-10-25 05:15:00

标签: sml smlnj ml

我正在尝试使用以下代码“模拟”传递值结果函数,但似乎存在语法错误。我一直在浏览sml教程,但我很难搞清楚为什么这不起作用

1 val x = ref 0;
2 fun p(y': int ref)=
3 let
4   val y = !y'
5     in
6         let
7             y = 1
8             in
9                 let x := 0 
10                 in
11                 y' := y
12                 end
13         end  
14 end     
15 p(x)

2 个答案:

答案 0 :(得分:3)

let <decs> in <exp>中,<decs>需要是一个或多个声明。

在你的情况下,在第7行你做y = 1 - 注意,这不是一个分配,而是一个比较。也就是说,在C ++中,它等同于执行y == 1。您不能分配给非ref变量。 (通常,您希望尽可能避免使用ref变量。) 您可以在其位置val y = 1进行操作,在这种情况下,您可以使用y的名称创建一个新值,该值隐藏旧的y(但不会更改它;您创建的是新价值)。

同样,在第9行,你做x := 0,它不是一个声明,而是一个表达式,它将值0赋给参考值x,然后返回单位

此外,您可以在let语句中执行多个声明,因此您不需要执行嵌套。

最后,你在顶层写p(x)。如果前面的声明以分号结尾,则只能在顶层上编写表达式;否则它认为它是声明的一部分。那是

val a = 5
6

被解释为

val a = 5 6

简而言之,您可以将其重写为:

val x = ref 0;

fun p(y': int ref)=
let
  val y = !y' (* this line might as well be deleted. *)
  val y = 1
in
  x := 0;
  y' := y
end;

p(x)

或者,更短的版本,因为SML具有良好的类型推断:

val x = ref 0;

fun p y' = (x := 0; y' := 1);

p x
但是,我会这样说;如果你来自C ++或类似的语言,可能很容易使用'a ref,但你经常会发现,最小化它们的使用往往会导致SML中的代码更清晰。 (和其他功能语言。)

答案 1 :(得分:2)

let y = 1 ...错了。 let x := 0也是如此。在let ... in内,您需要valfun声明。

您似乎对SML有一些误解。 let用于在范围中声明新的局部变量。您尝试在内部作用域中声明一个名为y的变量,这很奇怪,该变量会隐藏您在直接外部作用域中的y中声明的let。你要么意味着两件事之一:

  1. 更改外部作用域中定义的“y”变量的值。这是不可能的。您无法在ML
  2. 中更改变量的值
  3. 您想要声明一个名为“y”的新的无关变量,并隐藏此范围内的前一个“y”;在这种情况下,您将使用let var y = 1 in ...
  4. 另外,你有let x := 0这很奇怪。 x := 0本身就是一个有效的表达式。它更改x指向的引用中包含的值。您不需要let。由于x := 0仅针对副作用进行评估,并且返回类型unit(即没有用),您可能会熟悉;运算符,您可以使用该运算符将一串串联起来评价最后一个结果的副作用“陈述”:x := 0; y' := y