diff options
| -rw-r--r-- | examples/file.ts | 13 | ||||
| -rw-r--r-- | src/eval-env/builtins.ts | 18 | ||||
| -rw-r--r-- | stdlib/effect.ts | 2 | ||||
| -rw-r--r-- | stdlib/exception.ts | 4 | ||||
| -rw-r--r-- | stdlib/util.ts | 9 |
5 files changed, 26 insertions, 20 deletions
diff --git a/examples/file.ts b/examples/file.ts index 2cc2b7a..5af04da 100644 --- a/examples/file.ts +++ b/examples/file.ts @@ -7,11 +7,12 @@ interface PrintK extends Kind1<string> { return: PutStringLn<this['input']> } -interface ConstK<Val> extends Kind1<unknown, Val> { - return: Val -} - export type main = [ - Bind<ReadFile<'./default.nix'>, PrintK>, - Bind<Try<ReadFile<'./unicorn'>, ConstK<'hello world'>>, PrintK> + Bind<ReadFile<'./default.nix'>, <contents extends string>() => + PutStringLn<contents>>, + + Try< + Bind<ReadFile<'./unicorn'>, PrintK>, + <M extends string>() => PutStringLn<`ERROR: ${M}`> + > ] diff --git a/src/eval-env/builtins.ts b/src/eval-env/builtins.ts index f67fcc6..ed94943 100644 --- a/src/eval-env/builtins.ts +++ b/src/eval-env/builtins.ts @@ -31,7 +31,12 @@ const applyFunc = (ctx: Ctx, fn: Type | undefined, val: string): Type => { const typeParameters = functionNode.getTypeParameters() ?? [] if (typeParameters.length > 0) { - typeParameters[0]?.getConstraint()?.replaceWithText(val) + const constraint = typeParameters[0]?.getConstraint() + if (constraint) { + constraint?.replaceWithText(val) + } else { + typeParameters[0]?.setConstraint(val) + } } return resValueNode?.getType() @@ -126,9 +131,7 @@ export default (ctx: Ctx, args: Type[]) => ({ const resultType = applyFunc(ctx, chainToKind, `(${ctx.getResultExpr(resultKey)})['output']`) - const res = await ctx.evaluateType(ctx, resultType) - - return res + return ctx.evaluateType(ctx, resultType) }, Try: async () => { @@ -139,11 +142,8 @@ export default (ctx: Ctx, args: Type[]) => ({ return await ctx.evaluateType(ctx, effTyp) } catch (e) { const error = JSON.stringify((e as any)?.message ?? e) - const catchResExpr = `(${ctx.typeToString( - catchK - )} & { input: ${error} })['return']` - const [resultKey, _] = ctx.createResult(catchResExpr) - return [resultKey] + const resultType = applyFunc(ctx, catchK, error) + return ctx.evaluateType(ctx, resultType) } }, diff --git a/stdlib/effect.ts b/stdlib/effect.ts index 0662d00..341a620 100644 --- a/stdlib/effect.ts +++ b/stdlib/effect.ts @@ -7,7 +7,7 @@ export interface Kind1<Inp = unknown, Out = unknown> { return: Out } -type Func<Inp = unknown, Out = unknown> +export type Func<Inp = unknown, Out = unknown> = Kind1<Inp, Out> | (<_T extends Inp>() => Out) diff --git a/stdlib/exception.ts b/stdlib/exception.ts index ddb980c..d137a87 100644 --- a/stdlib/exception.ts +++ b/stdlib/exception.ts @@ -1,5 +1,5 @@ -import { Effect, Kind1 } from './effect' +import { Effect, Func } from './effect' -export interface Try<_E extends Effect, _Catch extends Kind1> extends Effect {} +export interface Try<_E extends Effect, _Catch extends Func> extends Effect {} export interface Throw<_E> extends Effect {} diff --git a/stdlib/util.ts b/stdlib/util.ts index 20a41fb..cd25d7b 100644 --- a/stdlib/util.ts +++ b/stdlib/util.ts @@ -2,12 +2,17 @@ import { Kind1 } from './effect' export type Let<f extends (...args: any) => any> = ReturnType<f> -export type Apply<K extends Kind1, Val> = (K & { input: Val })['return'] +export type ApplyK<K extends Kind1, Val> = (K & { input: Val })['return'] -export interface Id extends Kind1 { +export type Id = <T>() => T +export interface IdK extends Kind1 { return: this['input'] } +export interface ConstK<Val> extends Kind1<unknown, Val> { + return: Val +} + type ADTDescr = { _type: string; value: any } interface ADTConstructor<A extends ADTDescr> extends Kind1<A['value']> { |
