0

我又带着一个基本问题回来了。!;)

我已经学习了一些 List 函数。“List.nth”就是其中之一。当我在 SML 命令窗口中使用此功能时,它工作正常。但是当在 Let..in..end 中使用时;块,它不起作用。

我希望,有人能够提供帮助。

let
  val actualDays = 0;

in
  actualDays = List.nth([10,20,31,50,45], 2);
  actualDays
end;

预期输出:

 val it = 31 : int

实际输出:

 val it = 0 : int

提前致谢!

4

2 回答 2

2

The reason that this does not work as you intend has nothing to do with the List.nth function or the fact that you're inside a let expression. The reason that this does not work as you intend is that = is the equality operator, not an assignment operator, in SML.

The only assignment operator in SML is the := operator and its left operand needs to be a ref, not a plain integer. So one way to fix your code would be to change actualDays to be an int ref rather than just an int and to use := instead of =. However mutating variables isn't very idiomatic in SML. A better solution would be to adjust your logic to not need any mutation - probably by using recursive functions or, depending on what exactly you're trying to do, higher order functions.

于 2013-01-20T12:41:17.313 回答
1

你需要放下你的“命令式思维”,而为“功能性思维”敞开心扉。例如

如前所述,除非它是引用,否则您不能重新分配变量。而且,如果您需要使用引用,那么无论如何您都可能做错了。在函数式编程中,您实际上是在进行名称绑定(有时也称为单一赋值),而不是变量赋值。将它们视为“不可变对象”。

让我们先看看你的代码

let
  val actualDays = 0;    
in
  actualDays = List.nth([10,20,31,50,45], 2);
  actualDays
end;

当你在部件中放入一系列表达式时in ... end,它实际上与 have 相同in ( expr_1; ... ; expr_n) end,请注意表示表达式序列的括号。一系列表达式从左到右计算每个表达式,忽略除最后一个表达式结果之外的所有表达式。因此它主要用于评估具有副作用的表达式

- (print "foo\n"; print "bar\n"; 3);
foo
bar
val it = 3 : int

在您的情况下,由于等号不是赋值运算符,而是比较运算符,因此您的第一个表达式将计算为一个布尔表达式,该表达式被“忽略”,因为它没有副作用,然后actualDays返回它的值是最后一个表达式。

修复示例的一种方法是声明actualDaysList.nth. 然后你的函数可以有两个参数,一个参数是你期望得到的元素,另一个参数可能是你不想查找的索引。

fun foo x i =
    let
      val actualDays = List.nth([10,20,31,50,45], i)
    in
      x = actualDays
    end

- foo 20 1;
val it = true : bool
- foo 50 3;
val it = true : bool

但是在这个特定的函数中,不需要 let 表达式,你也可以这样写

fun foo x i = x = List.nth([10,20,31,50,45], i)
于 2013-01-20T15:19:11.323 回答