I noticed that the following code gives an error when you try to compile it:
let xx =
seq {
let! i = [ 1; 2 ]
let! j = [ 3; 4 ]
yield (i,j)
}
The error this gives is "error FS0795: The use of 'let! x = coll' in sequence expressions is no longer permitted. Use 'for x in coll' instead." This message is of course clear and demonstrates how to fix it; the fixed code would be:
let xx =
seq {
for i in [ 1; 2 ] do
for j in [ 3; 4 ] do
yield (i,j)
}
My question is not how to fix this however, but why the "let!" is not allowed in sequence expressions in the first place? I can see how the fact that let! iterates over an expression may come as a surprise to some, but that shouldn't be enough to disallow the construct. I also see how "for" is more powerful here, as the version with "let!" bakes in the scope of the iteration as "until the end of the sequence expression".
However, being able to iterate over a sequence without having to indent code was exactly what I was looking for (for traversing tree structures). I assume that to obtain this semantic I will have to make a new expression builder that acts mostly like the "seq" expression builder, but does allow "let!" for iteration, isn't it?
Added, based on Brian's comment below, providing the solution to my underlying problem:
I didn't realize the indentation in the for blocks isn't needed, and the second sample can be re-written as:
let xx =
seq {
for i in [ 1; 2 ] do
for j in [ 3; 4 ] do
yield (i,j)
}
... which gets rid of the ever-increasing indentation when traversing a tree structure. The syntax even allows additional statements in between for statements without requiring extra indentation, as in:
let yy =
seq {
for i in [ 1; 2 ] do
let i42 = i+42
for j in [ 3; 4 ] do
yield (i42,j)
}
Now, if only I could figure out why I thought these statements would require indentation...
let!in async bindings - we have identical syntax doing completely different things? - John Palmer