Stringification with multimethods and traits
This example shows how JSOS enables you to easily create extensible functions and types.
First, we will create a multimethod for converting things to strings and a
Stringifyable trait that signals that a type can be turned into a string.
Then we will add a new type that implements stringification by extending the previously written code.
You can find the full example code in the git repository of JSOS.
Creating the trait and multimethod
First, lets create a trait that represents when a type can be stringified, and a multimethod that can do the stringification.
/* ------------------------------------------------------- stringification.js */
import { Trait, TraitItem, Generic, TAny } from "@fed1/jsos";
export const { stringify } = Generic;
export const { IStringifyable } = Trait(
[stringify, TAny] // describes a method's expected signature
);
Creating our own type
Now we can create our own type and make it IStringifyable by implementing
stringify for the trait.
/* --------------------------------------------------------------- my-type.js */
import { Type, Struct, def, JSString, JSNumber } from "@fed1/jsos";
import { IStringifyable, stringify } from "./stringification.js";
// 'Type' creates new abstract types
export const { TMyAbstractType } = Type;
// 'Struct' creates new concrete types
export const { MyType } = Struct({
name: JSString.where(s => s.length > 0), // creates a dependent type
id: JSNumber.where(n => n > 0)
})(TMyAbstractType); // subtype
// Add another constructor for convenience
def(MyType.new, [JSString, JSNumber], (name, id) => ({name, id}));
// Make our type an IStringifyable
MyType.implement(IStringifyable, [
def(stringify, [TMyAbstractType], t => `Name: ${ t.name }, ID: ${ t.id }`)
]);
Using our extensible stringification capabilities for logging
Then we can create a multimethod for logging stuff that can print any object
whose type implements IStringifyable to the console.
/* --------------------------------------------------------------- logging.js */
import { Generic, def } from "@fed1/jsos";
import { IStringifyable, stringify } from "./stringification.js";
export const { log } = Generic;
def(log, [IStringifyable], s => console.log(stringify(s)));
Finally, we can use the new log multimethod.
/* ----------------------------------------------------------------- index.js */
import { log } from "./logging.js";
import { MyType } from "./my-type.js";
log(MyType.new("John", 21)); // Name: John, ID: 21
Note: JSOS already comes with a built-in
stringifymultimethod.
