February 3rd, 2005

  • evan

functional pattern

I'm looking for a functional design pattern of sorts. It comes up when processing input piecemeal.

Suppose I'm expecting input of this form:
A foo
B bar
C baz

and I'd like to read it into a record like { a: string; b: string; c: string }.
The best functional way I can think of doing this is like this:
let rec fold rec =
    let key, val = read_pair () in
    match key with
    | "A" -> fold { rec with a = val }
    | "B" -> fold { rec with b = val }
    | "C" -> fold { rec with c = val }
  with End_of_input -> rec
fold empty_record

This is ok, but the "empty_record" bit is a hack; I want it to be an error for any of A, B, or C to not be present, and here they just keep the fields' default values (whatever was in empty_record).

One solution it to change the record into using option types ({ a: string option; etc. }) but like I said, it's an error any of the fields to be left undefined and the rest of the code (which consumes the record) shouldn't need to deconstruct the options into their values.

What's a good way to do this? I'm tempted to just use mutable fields on the record, but that's also hacky.