19.10 Function application expression appexp atexp
Atomic expressions we have introduced so far are the smallest units of expressions that includes delimiters in their own syntax. Expressions are usually constructed by combining those atomic expressions with expression constructors. The most tightly connected expression constructor is function applications. Since SML# inherits the traditions of lambda calculus, the syntax of function applications is appexp atexp, which is just a sequence of function expression appexp and argument expression atexp. As seen in this syntax, function applications are left-associative. In the last example, #name f("joe", 21) is interpreted as ((#name f) ("joe", 21)) and therefore causes a type error.
# val f = fn x => fn y => fn z => (x,y,z);;
val f = fn : [’a. ’a -> [’b. ’b -> [’c. ’c -> ’a * ’b * ’c]]]
# f 1 2 (3,4);
val it = (1,2,(3,4)) : int * int * (int * int)
# fun f (x,y) = {name=x,age=y};
val f = fn : [’a, ’b. ’a * ’b -> age: ’b, name: ’a]
# #name (f ("joe", 21));
val it = "joe" : string
# #name f("joe", 21);
(interactive):5.0-5.6 Error:
(type inference 028) operator and operand don’t agree
operator domain: ’BCUJ#{name: ’BCUI}
operand: [’a, ’b. ’a * ’b -> {age: ’b, name: ’a}]