Here’s one for immutable arrays, extrapolating from my topic examples and my previous comment (note that this uses TypeApplications
):
type This =
'{ "foo" := Char
, "bar" := Bool
, "baz" := Float
}
this :: SmallArrayRec _ -- Known to be equal to `This` based on type resolution
this = new
. cons @"baz" (5 :: Float)
. cons @"bar" True
. cons @"foo" 'a'
$ nil
result :: _ -- Known to be Bool based on type resolution
result = index @"bar" this
All of this is type-safe. The mutable counterpart works exactly the same and can be converted to and from the immutable variant through copying. Furthermore all of this can be implemented using newtypes, so under the hood either variant eagerly inlines to direct array access (so runtime performance shouldn’t be much different from regular records).
Ease of use suffers slightly because RecordWildCards
won’t magically work with this, but an extension to allow this could be added later if deemed worthy. Maintainance-wise, as stated, all functions can live in a separate module and all the datatype implementations don’t even need to be in base
, so the only thing to bikeshed here is type-level record notation.
Duplicate fields are supported with this by default, because symbols don’t have the same restrictions as regular record fields. Similarly there is nothing to overload in terms of notation: any characters can be used for nesting, dot is assumed because that’s what every other language uses.