63 lines
1.5 KiB
JavaScript
63 lines
1.5 KiB
JavaScript
import { typedFnType } from "./types.js";
|
|
import { Char, GenericType, Type } from "../primitives/types.js";
|
|
import { Int } from "../primitives/types.js";
|
|
import { makeGeneric } from "../generics/generics.js";
|
|
import { lsType } from "./types.js";
|
|
import { Typed } from "../typed.js"
|
|
|
|
// 'normal' implementation
|
|
const emptyList = {l:[]};
|
|
const emptyListType = makeGeneric(a => lsType(a));
|
|
const get = ls => i => ls.l[i];
|
|
const put = ls => i => elem => ({l: ls.l.with(Number(i), elem)});
|
|
const push = ls => elem => ({l:ls.l.concat([elem])});
|
|
|
|
export const String = lsType(Char); // alias
|
|
export const Module = lsType(Typed);
|
|
|
|
export const ModuleList = {l:[
|
|
// Type -> Type
|
|
...typedFnType(lsType, fnType =>
|
|
fnType
|
|
/* in */ (Type)
|
|
/* out */ (Type)
|
|
),
|
|
|
|
// [a]
|
|
{i: emptyList, t: emptyListType},
|
|
{i: emptyListType, t: GenericType},
|
|
|
|
// [a] -> Int -> a
|
|
...typedFnType(get, fnType =>
|
|
makeGeneric(a =>
|
|
fnType
|
|
/* in */ (lsType(a))
|
|
/* out */ (fnType
|
|
/* in */ (Int)
|
|
/* out */ (a)
|
|
)), GenericType),
|
|
|
|
// [a] -> Int -> a -> [a]
|
|
...typedFnType(put, fnType =>
|
|
makeGeneric(a =>
|
|
fnType
|
|
/* in */ (lsType(a))
|
|
/* out */ (fnType
|
|
/* in */ (Int)
|
|
/* out */ (fnType
|
|
/* in */ (a)
|
|
/* out */ (lsType(a))
|
|
)
|
|
)), GenericType),
|
|
|
|
// [a] -> a -> [a]
|
|
...typedFnType(push, fnType =>
|
|
makeGeneric(a =>
|
|
fnType
|
|
(lsType(a))
|
|
(fnType
|
|
(a)
|
|
(lsType(a))
|
|
)
|
|
), GenericType),
|
|
]};
|