I am new to the language and attempting to model tables in OCaml. My current implementation (an object with 1 attr, a list of records) seems to meet my criteria but is not sufficient for reasoning about empty tables, as OCaml does not seem to let me define record types with no fields or just perform top level checks.
My table encoding
(* table *)
class type table_templ = object
method columns: 'a list
method add_rows: 'a list -> 'a list
end;;
class ['a] table = object
val mutable columns : 'a list = []
method columns : 'a list = columns
method add_rows : 'a list -> 'a list = fun rows ->
columns <- rows @ columns;
columns
end;;
Working example
type student =
{
name: string option;
age: int option;
favourite_color: string option;
}
let bob = {name = Some "Bob"; age = Some 12; favourite_color = Some "blue";}
let alice = {name = Some "Alice"; age = Some 17; favourite_color = Some "green";}
let eve = {name = Some "Eve"; age = Some 13; favourite_color = Some "red";}
let e = new table;;
e#add_rows [bob; alice; eve];;
Issue with empty tables
type empty = { };;
let empty_record_instance: empty = { };;
let empty_table = new table;;
empty_table#add_rows [empty_record_instance];;
empty_table#columns
I would appreciate any suggestions around making this approach work but I am also open to alternative ideas for encoding tables that already fit the language’s type system and my criteria.
I think I already tried that but was unable to extend the empty table with a new schema later on. Is this is even a behaviour I would be able to achieve if empty records were possible?
I am not sure what you mean by expanding the schema. Are you sure it is possible even with non-empty record ?
It sounds like something that would require subtyping, that is that if you have
type a = {x : float}
type b = {x: float; y: float}
then a value of type b can also be used as if it was a value of type a.
OCaml does not have for records because it has a performance cost, and you do not need it all the time. If you want that behavior you need to use objects, which I believe support empty objects: