So I was trying to do something in a trivial case akin to this
type foo = {
bar: int;
baz: int list;
}
let defaults = {baz = []}
let my_foo : foo = {defaults with bar = 0}
Which gives me this error: Some record fields are undefined: bar. Where I expected no compiler error & my_foo would be {bar = 0; baz = []} with a handwaving 'a somewhere in default’s type signature.
So my question is: Is there a way to have partial/extensible records to handle default field values for records while requiring other fields always be set, bar in this case? What is the normal pattern for folks to handle this? It seems I could do it with the object system requiring arguments in the constructor, but this seems like the wrong tool for the job. Maybe I could create some factory function like let mk_foo ~bar ?(baz = []) () = {bar; baz} with field punning?
In Elm & PureScript there are extensible records that one can ergonomically use, but that doesn’t seem to be the case in OCaml. The follow up question if this isn’t the case then becomes: why can’t I do this?
No, every field in a record must be specified in order to create a record value. Partial or extensible records are not supported as a basic construction of the language.
My understanding is that all known approaches to implementing extensible records in the context of strict functional languages come with tradeoffs in terms of complexity and performance. So far, these tradeoffs have never been considered justified for a feature of debatable utility.
Note that extensible records were removed from Elm precisely for reasons of complexity and performance: news/compilers-as-assistants.
You can do something close to what you want with first-class modules:
module type Foo = sig
val bar : int
val baz : int list
end
module Defaults = struct
let baz = []
end
type foo = (module Foo)
let my_foo : foo = (module struct include Defaults let bar = 0 end)
The syntax is very heavy but I think it matches your requirements. You can even override the defaults by re-defining the value after the include.