In sml can I use a tuple in a let ? If so what would the syntax be?
I can require this as concentric pattern matches, but it seems there should be a less boilerplate way. In the let below, I'd like to bind v1 and v2 to the two values of the tuple returned from calling interpExp. Then I'd like to call interpExp with one of those values to get two more values.
fun performOp (e1,op,e2,table) =
let val (v1,t1) = interpExp(e1,table) (* interpExp returns 2-tuple, bind v1 and t2 to those two values *)
and val (v2,t2) = interpExp(e1,t1) (* use t1 which was bound on previous line *)
and val v3 = (case op of
Plus => v1 + v2
| Minus => v1 - v2
| Times => v1 * v2
| Div => v1 / v2)
in (v3,t2)
end
On further trial and error, it seems the second and third val are unnecessary, and thereafter it seems the v1 and v2 are not in scope for the next clause.
fun performOp (e1,op,e2,table) =
let val (v1,t1) = interpExp(e1,table)
and (v2,t2) = interpExp(e1,t1) (* oops t1, not in scope *)
and v3 = (case op of
Plus => v1 + v2
| Minus => v1 - v2
| Times => v1 * v2
| Div => v1 / v2)
in (v3,t2)
end
On further experimentation I've discovered yet another syntax, but I'm not sure what the difference is, i.e., using val rather than and in the let.
fun performOp (e1,op,e2,table) =
let val (v1,t1) = interpExp(e1,table)
val (v2,t2) = interpExp(e1,t1) (* oops t1, not in scope *)
val v3 = (case op of
Plus => v1 + v2
| Minus => v1 - v2
| Times => v1 * v2
| Div => v1 / v2)
in (v3,t2)
end