Standard ML

236319 Spring 2024, Prof. Lorenz


Standard ML

Functions


Side note - operators

A function of two arguments can be treated as an infix operator:

fun d (x,y) = Math.sqrt (x*x + y*y);

Convert to an infix operator using the infix operator:

infix d;

3.0 d 4.0;

1.0 d 3.0 d 2.0 d 5.0;

operators

The infix declaration can come before the function definition:

infix d;
fun (x d y) = Math.sqrt (x*x + y*y);

To treat an operator as a prefix function use the op keyword:

op d (1.0,3.0);

Curried functions

Curry = Haskell Curry (1900-1982), who invented the “trick”

Any function of two arguments $(\alpha * \beta)\rightarrow \gamma$ can be expressed as a curried function of one argument $\alpha\rightarrow (\beta \rightarrow \gamma)$

fun prefix (pre, post) = pre ^ post;

The curried version

fun prefix pre = fn post => pre^post;

Reminder: -> is right associative

val prefix = fn : string -> string -> string
(*is equivalent to*)
val prefix = fn : string -> (string -> string)

partial application

AKA - Partial Evaluation

You don’t have to provide subsequent arguments:

prefix "Dr. ";

it "Watson";

As always, functions are values:

val doctorify = prefix "Dr. ";

doctorify "Jekyll";

currying - syntactic sugar

fun prefix pre post = pre ^ post;

is equivalent to:

fun prefix pre = fn post => pre ^ post;

Invoking a function

(prefix "Dr. ") "Watson";

prefix "Dr. " "Watson";

The rule is:

  • a function invocation F E1 E2 ... En
  • abbreviates (...((F E1) E2)...) En

Example of partial application

Applying infix operator only to one operand

fun add5 y = op+ (5, y);

add5 2;

fun mul5 y = op* (5, y);

Example of partial application

Now, generalize the operator and operand

fun something5 (f:int*int->int) y = f (5, y);

val add5 = something5 op+;

fun intsec x (f:int*int->int) y = f (x, y);

Recursive curried functions

fun times n m =
    if m=0 then 0
    else n + times n (m-1);

times 4 5;

val times_4 = times 4;

times_4 8;

Function composition operator

infix o;
fun (f o g) x = f (g x);

Math.sqrt o Math.sqrt;

it (16.0);

(fn x => x - ord #"0") o ord;

it #"1";

Questions from exams

What will be printed?

fun f1 a b = f1 a b;

What will be printed?

fun f2 g x = g (f2 g) x;

What will be printed?

fun f3 x y z = (x, x (y), y (z));

What will be printed?

fun f4 f = f f4;