我创建了一些语言元组,当在交互式窗口中使用它们时,它们反向列出。这是正常的F#行为吗?
let languages = ("English", "Spanish", "Italian")
let x, y, z = languages
val languages : string * string * string = ("English", "Spanish", "Italian")
val z : string = "Italian"
val y : string = "Spanish"
val x : string = "English"
答案 0 :(得分:4)
您正在创建三个变量,同时具有独立的值。订单与此无关。 F#interactive可以按任何顺序打印值。
重要的是代码中的订单评估,spec在调用函数或构造函数,创建记录等时从左到右说明。
> (printfn "a", printfn "b");;
a
b
答案 1 :(得分:2)
这也是FSI在我的机器上分解它们时打印元组的方式。
例如:
让x,y =(“a”,“b”);;
val y : string = "b"
val x : string = "a"
它以“反向”打印有点奇怪,但我不确定我会把它称为F#行为,就像FSI行为或漂亮的打印行为一样。
如果您需要所有详细信息,可以随时查看源代码:
答案 2 :(得分:2)
我不确定是否存在连接,但在Quotations中包装F#表达式可以让您深入了解语言的语义,并且您可以在下面看到命名值确实以相反的顺序绑定,如图所示在FSI:
> <@ let languages = ("English", "Spanish", "Italian") in let x, y, z = languages in () @> |> string;;
val it : string =
"Let (languages,
NewTuple (Value ("English"), Value ("Spanish"), Value ("Italian")),
Let (z, TupleGet (languages, 2),
Let (y, TupleGet (languages, 1),
Let (x, TupleGet (languages, 0), Value (<null>)))))"
请注意,这仍然与@Laurent的答案一致,该答案断言元组构造中的参数表达式是从左到右进行评估的。在下面的示例中,查看元组构造的结果如何绑定到中间命名值,然后使用无副作用的TupleGet表达式对其进行解构。
> <@ let x,y = (stdin.Read(), stdin.ReadLine()) in () @> |> string;;
val it : string =
"Let (patternInput,
NewTuple (Call (Some (Call (None, System.IO.TextReader ConsoleIn[Object](),
[])), Int32 Read(), []),
Call (Some (Call (None, System.IO.TextReader ConsoleIn[Object](),
[])), System.String ReadLine(), [])),
Let (y, TupleGet (patternInput, 1),
Let (x, TupleGet (patternInput, 0), Value (<null>))))"