progress
This commit is contained in:
parent
33c156fc5c
commit
afd78c3b3e
5 changed files with 54 additions and 8 deletions
|
|
@ -110,9 +110,7 @@ export const mergeSubstitutions = (m1, m2) => {
|
||||||
let d;
|
let d;
|
||||||
// notice we swap m2 and m1, so the rewriting can happen both ways:
|
// notice we swap m2 and m1, so the rewriting can happen both ways:
|
||||||
[stable, m2, m1, d] = mergeOneWay(m1, m2);
|
[stable, m2, m1, d] = mergeOneWay(m1, m2);
|
||||||
if (!stable) {
|
deletedTypeVars = deletedTypeVars.union(d);
|
||||||
deletedTypeVars = deletedTypeVars.union(d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return [new Map([...m1, ...m2]), deletedTypeVars];
|
return [new Map([...m1, ...m2]), deletedTypeVars];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { Bool, Int } from "../primitives/symbols.js";
|
||||||
import { lsType } from "../structures/list_common.js";
|
import { lsType } from "../structures/list_common.js";
|
||||||
import { fnType } from "../metacircular.js";
|
import { fnType } from "../metacircular.js";
|
||||||
import { assign, makeGeneric, mergeSubstitutions, unify } from "./generics.js";
|
import { assign, makeGeneric, mergeSubstitutions, unify } from "./generics.js";
|
||||||
import { select } from "@inquirer/prompts";
|
|
||||||
|
|
||||||
// a -> Int
|
// a -> Int
|
||||||
const a_to_Int = makeGeneric(a => fnType({in: a, out: Int}));
|
const a_to_Int = makeGeneric(a => fnType({in: a, out: Int}));
|
||||||
|
|
|
||||||
2
main.js
2
main.js
|
|
@ -131,7 +131,7 @@ const makeChoice = ([i, t]) => {
|
||||||
return {
|
return {
|
||||||
value: {i, t: t[0]},
|
value: {i, t: t[0]},
|
||||||
name: pretty(i),
|
name: pretty(i),
|
||||||
description: `${pretty(i)} :: ${pretty(t[0])}`,
|
description: ` :: ${pretty(t[0])}`,
|
||||||
short: `${pretty(i)} :: ${pretty(t[0])}`,
|
short: `${pretty(i)} :: ${pretty(t[0])}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
progress.txt
50
progress.txt
|
|
@ -10,8 +10,56 @@ status:
|
||||||
2) experimental implementation of polymorphic types and type inferencing
|
2) experimental implementation of polymorphic types and type inferencing
|
||||||
values currently treated as white-box, hardcoded generic types (e.g., list, function) in type inferencing algorithm
|
values currently treated as white-box, hardcoded generic types (e.g., list, function) in type inferencing algorithm
|
||||||
|
|
||||||
todo:
|
wip:
|
||||||
- interfaces via typeclasses?
|
- interfaces via typeclasses?
|
||||||
|
|
||||||
|
- revise the way types are encoded
|
||||||
|
we need only one 'type of type' (called 'kind' in Haskell), and we can call it 'Type'.
|
||||||
|
types explicitly contain their underlying types. the type inferencing algorithm needs this information.
|
||||||
|
|
||||||
|
Int
|
||||||
|
{ symbol: Int, params: [] }
|
||||||
|
|
||||||
|
[Int]
|
||||||
|
{ symbol: List, params: [{ symbol: Int, params: [] }] }
|
||||||
|
|
||||||
|
[[Int]]
|
||||||
|
{ symbol: List,
|
||||||
|
params: [{ symbol: List, params: [{symbol: Int, params: []}]}]}
|
||||||
|
|
||||||
|
Int -> Bool
|
||||||
|
{ symbol: Function, params: [
|
||||||
|
{ symbol: Int, params: [] },
|
||||||
|
{ symbol: Bool, params: [] },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Int | Bool
|
||||||
|
{ symbol: Sum, params: [
|
||||||
|
{ symbol: Int, params: [] },
|
||||||
|
{ symbol: Bool, params: [] },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
(Int, Bool)
|
||||||
|
{ symbol: Product, params: [
|
||||||
|
{ symbol: Int, params: [] },
|
||||||
|
{ symbol: Bool, params: [] },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2D <-- custom nominal type! maybe it contains two Doubles, but we don't expose this
|
||||||
|
{ symbol: Point2D, params: [] }
|
||||||
|
|
||||||
|
Type constructors are just functions that return a 'Type'.
|
||||||
|
For instance:
|
||||||
|
lsType :: Type -> Type
|
||||||
|
fnType :: Type -> Type -> Type
|
||||||
|
|
||||||
|
The sad(?) part about all of this, is that I'm converging with Haskell/Lean.
|
||||||
|
|
||||||
|
- treat all values as polymorphic? (non-polymorphic values simply have empty set of type variables)
|
||||||
|
|
||||||
|
todo:
|
||||||
- type inferencing can be reduced to finding a graph isomorphism?
|
- type inferencing can be reduced to finding a graph isomorphism?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,14 @@ const squareFnType = makeGeneric(a =>
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// should be: Int -> Int
|
console.log("should be: Int -> Int");
|
||||||
console.log(assign(squareFnType, makeGeneric(() => numDictType(Int))));
|
console.log(assign(squareFnType, makeGeneric(() => numDictType(Int))));
|
||||||
|
|
||||||
// should be: Double -> Double
|
console.log("should be: Double -> Double");
|
||||||
console.log(assign(squareFnType, makeGeneric(() => numDictType(Double))));
|
console.log(assign(squareFnType, makeGeneric(() => numDictType(Double))));
|
||||||
|
|
||||||
// to call 'square' we need:
|
// to call 'square' we need:
|
||||||
// - access to a mapping from types to their typeclass instantiation
|
// - access to a mapping from types to their typeclass instantiation
|
||||||
// - to know that our argument is 'Int'
|
// - to know that our argument is 'Int'
|
||||||
|
console.log("");
|
||||||
console.log(square(NumInstances.get(Int))(42n)); // 1764n
|
console.log(square(NumInstances.get(Int))(42n)); // 1764n
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue