Armed with our knowledge about integers and reals and the useful
``pattern matching'' mechanism of Standard ML we are now able to
implement a simple formula. A Reverend
Zeller discovered a formula which calculates the day of the week for a
given date. If *d* and *m* denote day and month and *y* and *c*
denote year and century with each month decremented by two (January
and February becoming November and December of the previous year) then
the day of the week can be calculated according to the following
formula.

(floor (2.61*m* - 0.2) + *d* + *y* + *y* ÷
4 + *c* ÷
4 - 2*c*) mod 7

This is simple to encode as a Standard ML function, zc, with a four-tuple as its argument if we know where to obtain the conversion functions in the Standard ML library. We will bind these to concise identifier names for ease of use. We choose the identifier floor for the real-to-integer function and real for the integer-to-real function. Note the potential for confusion because the name real is simultaneously the name of a function and the name of a type. Standard ML maintains different name spaces for these.

floor = Real.floorvalreal = Real.fromIntvalzc =val(d, m, y, c) => (floor (2.61 * real (m) - 0.2) + d + y + y div 4 + c div 4 - 2 * c) mod 7;fn

Now we may use the pattern matching mechanism of Standard ML to perform the adjustment required for the formula to calculate the days correctly.

Although the zeller function correctly calculates days of the week its construction is somewhat untidy since the floor, real and zc functions have the same status as the zeller function although they were intended to be only sub-components. We require a language construct which will bundle the four functions together, making the inferior ones invisible. In Standard ML thezeller =val(d, 1, y) => zc (d, 11, (y-1) mod 100, (y-1) div 100) | (d, 2, y) => zc (d, 12, (y-1) mod 100, (y-1) div 100) | (d, m, y) => zc (d, m - 2, y mod 100, y div 100);fn

Here we have three functions declared between the keywordlocalfloor = Real.floorvalreal = Real.fromIntvalzc =val(d, m, y, c) => (floor (2.61 * real (m) - 0.2) + d + y + y div 4 + c div 4 - 2 * c) mod 7fninzeller =val(d, 1, y) => zc (d, 11, (y-1) mod 100, (y-1) div 100) | (d, 2, y) => zc (d, 12, (y-1) mod 100, (y-1) div 100) | (d, m, y) => zc (d, m - 2, y mod 100, y div 100)fn;end