开发者

Does F# iterate through tuples from back to front?

I've created a little tuple of langauges and when using it in the interactive window they are listed in reverse. Is this normal F# bahavior?

let languages = ("English", "开发者_JAVA技巧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"


You're creating three variables, at the same time, with independant values. Order is not relevant here. F# interactive could print the values in any order.

What is important is order evaluation in your code, and the spec says it's from left to right when you're calling a function or constructor, creating a record, and so on.

> (printfn "a", printfn "b");;
a
b


That is also how FSI prints tuples when I decompose them them on my machine.

eg:

let x, y = ("a", "b");;

val y : string = "b"
val x : string = "a"

It's a little weird that it prints in "reverse", but I'm not sure that I would call it F# behavior as much as it is FSI behavior or pretty print behavior.

If you're want all the details, you can always have a look at the source code:

http://fsharppowerpack.codeplex.com/


I'm not sure if there is a connection, but wrapping F# expressions in Quotations can give you insight into the semantics of the language, and you can see in the following that the named values are indeed bound in reverse order like shown in 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>)))))"

Note that this is still consistent with @Laurent's answer, which asserts that argument expressions in tuple construction are evaluated from left to right. In the following example, see how the result of the tuple construction is bound to an intermediate named value, which is then deconstructed using side-effects free TupleGet expressions.

> <@ 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>))))"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜