Composite Types (Structs)
Constructors
In JSOS, structs have a constructor property .new
. This is actually not just
a regular function, it's a multimethod! This means that, just like with all
other multimethods, you can define new methods on it:
import { Type, Struct, isA, def, JSNumber, JSString } from "@fed1/jsos";
const { MyAbstractType } = Type;
const { MyType } = Struct({
name: JSString,
id: JSNumber
}, [MyAbstractType]);
def(MyType.new, [JSString, JSNumber], (name, id) => MyType.new({name, id}));
const mct = MyType.new("Foo", 1);
Each custom constructor method should return with a call to the default constructor, which expects a regular JSObject containing all the properties required by the struct.
Parameterization
The types created using Struct
or MStruct
can have type parameters as well.
This allows for a version of generic programming.
Both Struct
and MStruct
can be called as functions to supply the root types
of the to-be-created parameterized struct.
When you specify root types, you are required to supply the struct's schema wrapped in a function instead of as a regular object.
This wrapper function is then given the actual types that are supplied to be used in place of the root types. The supplied types need to be either the root type itself or subtypes of the root type, and they need to be in the same order as the specified root types.
Here's an example of how to define and use parametric types:
import { Type, Struct, TNumber, TReal } from "@fed1/jsos";
const { MyType } = Type;
const { ParaStruct } = Struct(TNumber)(T => ({
x: T,
y: T
}))(MyType);
const psReal = ParaStruct(TReal).new({
x: 5.5,
y: 2.3
});
When ParaStruct(TReal).new()
is called, the supplied function is given the
TReal
that is used as a replacement for the TNumber
used in the call to
Struct(TNumber)
. Functions given as an argument instead of a schema object
are expected to produce a schema object where all the parameters have been
inserted at the appropriate places.
What this means in the example above is that any type created with ParaStruct
must have x
and y
values that are some kind of number type.
The example only demonstrates this for one parameter, but any number of parameters can be specified for a struct.