Skip to content

Commit 5da3490

Browse files
committed
Factor out serializePartiallyAppliedFunction
This makes it easier to define higher-order prelude functions.
1 parent c658a22 commit 5da3490

File tree

1 file changed

+31
-97
lines changed

1 file changed

+31
-97
lines changed

src/language/compiling/semantics/prelude.ts

Lines changed: 31 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ import { keyPathToMolecule } from '../../semantics/key-path.js'
1313
import {
1414
lookupPropertyOfObjectNode,
1515
makeUnelaboratedObjectNode,
16-
serializeObjectNode,
1716
} from '../../semantics/object-node.js'
1817
import {
1918
containsAnyUnelaboratedNodes,
2019
isSemanticGraph,
21-
serialize,
2220
type SemanticGraph,
2321
} from '../../semantics/semantic-graph.js'
2422
import {
@@ -48,6 +46,16 @@ const handleUnavailableDependencies =
4846
}
4947
}
5048

49+
const serializePartiallyAppliedFunction =
50+
(keyPath: readonly string[], argument: SemanticGraph) => () =>
51+
either.makeRight(
52+
makeUnelaboratedObjectNode({
53+
0: '@apply',
54+
function: { 0: '@lookup', query: keyPathToMolecule(keyPath) },
55+
argument,
56+
}),
57+
)
58+
5159
const preludeFunction = (
5260
keyPath: readonly string[],
5361
signature: FunctionType['signature'],
@@ -90,14 +98,7 @@ export const prelude: ObjectNode = makeObjectNode({
9098
parameter: types.functionType,
9199
return: types.something,
92100
},
93-
() =>
94-
either.map(serialize(argument), serializedArgument =>
95-
makeUnelaboratedObjectNode({
96-
0: '@apply',
97-
function: { 0: '@lookup', query: { 0: 'apply' } },
98-
argument: serializedArgument,
99-
}),
100-
),
101+
serializePartiallyAppliedFunction(['apply'], argument),
101102
option.none,
102103
functionToApply => {
103104
if (!isFunctionNode(functionToApply)) {
@@ -164,19 +165,10 @@ export const prelude: ObjectNode = makeObjectNode({
164165
parameter: function0.signature.parameter,
165166
return: function1.signature.parameter,
166167
},
167-
() =>
168-
either.flatMap(function0.serialize(), serializedFunction0 =>
169-
either.map(function1.serialize(), serializedFunction1 =>
170-
makeUnelaboratedObjectNode({
171-
0: '@apply',
172-
function: { 0: '@lookup', query: { 0: 'flow' } },
173-
argument: makeUnelaboratedObjectNode({
174-
0: serializedFunction0,
175-
1: serializedFunction1,
176-
}),
177-
}),
178-
),
179-
),
168+
serializePartiallyAppliedFunction(
169+
['flow'],
170+
makeObjectNode({ 0: function0, 1: function1 }),
171+
),
180172
option.none,
181173
argument => either.flatMap(function0(argument), function1),
182174
),
@@ -203,17 +195,7 @@ export const prelude: ObjectNode = makeObjectNode({
203195
parameter: types.integer,
204196
return: types.integer,
205197
},
206-
() =>
207-
either.makeRight(
208-
makeUnelaboratedObjectNode({
209-
0: '@apply',
210-
function: {
211-
0: '@lookup',
212-
query: { 0: 'integer', 1: 'add' },
213-
},
214-
argument: number2,
215-
}),
216-
),
198+
serializePartiallyAppliedFunction(['integer', 'add'], number2),
217199
option.none,
218200
number1 => {
219201
if (
@@ -252,17 +234,10 @@ export const prelude: ObjectNode = makeObjectNode({
252234
parameter: types.integer,
253235
return: types.boolean,
254236
},
255-
() =>
256-
either.makeRight(
257-
makeUnelaboratedObjectNode({
258-
0: '@apply',
259-
function: {
260-
0: '@lookup',
261-
query: { 0: 'integer', 1: 'less_than' },
262-
},
263-
argument: number2,
264-
}),
265-
),
237+
serializePartiallyAppliedFunction(
238+
['integer', 'less_than'],
239+
number2,
240+
),
266241
option.none,
267242
number1 => {
268243
if (
@@ -301,17 +276,7 @@ export const prelude: ObjectNode = makeObjectNode({
301276
parameter: types.integer,
302277
return: types.integer,
303278
},
304-
() =>
305-
either.makeRight(
306-
makeUnelaboratedObjectNode({
307-
0: '@apply',
308-
function: {
309-
0: '@lookup',
310-
query: { 0: 'integer', 1: 'subtract' },
311-
},
312-
argument: number2,
313-
}),
314-
),
279+
serializePartiallyAppliedFunction(['integer', 'subtract'], number2),
315280
option.none,
316281
number1 => {
317282
if (
@@ -393,14 +358,7 @@ export const prelude: ObjectNode = makeObjectNode({
393358
parameter: types.something,
394359
return: types.something,
395360
},
396-
() =>
397-
either.map(serializeObjectNode(cases), serializedCases =>
398-
makeUnelaboratedObjectNode({
399-
0: '@apply',
400-
function: { 0: '@lookup', query: { 0: 'match' } },
401-
argument: serializedCases,
402-
}),
403-
),
361+
serializePartiallyAppliedFunction(['match'], cases),
404362
option.none,
405363
argument => {
406364
if (!nodeIsTagged(argument)) {
@@ -448,17 +406,10 @@ export const prelude: ObjectNode = makeObjectNode({
448406
parameter: types.naturalNumber,
449407
return: types.naturalNumber,
450408
},
451-
() =>
452-
either.makeRight(
453-
makeUnelaboratedObjectNode({
454-
0: '@apply',
455-
function: {
456-
0: '@lookup',
457-
query: { 0: 'natural_number', 1: 'add' },
458-
},
459-
argument: number2,
460-
}),
461-
),
409+
serializePartiallyAppliedFunction(
410+
['natural_number', 'add'],
411+
number2,
412+
),
462413
option.none,
463414
number1 => {
464415
if (
@@ -514,17 +465,7 @@ export const prelude: ObjectNode = makeObjectNode({
514465
parameter: types.something,
515466
return: types.something,
516467
},
517-
() =>
518-
either.makeRight(
519-
makeUnelaboratedObjectNode({
520-
0: '@apply',
521-
function: {
522-
0: '@lookup',
523-
query: { 0: 'object', 1: 'lookup' },
524-
},
525-
argument: key,
526-
}),
527-
),
468+
serializePartiallyAppliedFunction(['object', 'lookup'], key),
528469
option.none,
529470
argument => {
530471
if (!isObjectNode(argument)) {
@@ -575,17 +516,10 @@ export const prelude: ObjectNode = makeObjectNode({
575516
parameter: types.string,
576517
return: types.string,
577518
},
578-
() =>
579-
either.makeRight(
580-
makeUnelaboratedObjectNode({
581-
0: '@apply',
582-
function: {
583-
0: '@lookup',
584-
query: { 0: 'string', 1: 'concatenate' },
585-
},
586-
argument: string1,
587-
}),
588-
),
519+
serializePartiallyAppliedFunction(
520+
['string', 'concatenate'],
521+
string1,
522+
),
589523
option.none,
590524
string2 => {
591525
if (typeof string1 !== 'string' || typeof string2 !== 'string') {

0 commit comments

Comments
 (0)