Skip to content

Commit 0aeb78f

Browse files
committed
用 naryFmap 定义 lift
1 parent 582df46 commit 0aeb78f

4 files changed

Lines changed: 31 additions & 8 deletions

File tree

‎TODO.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
用 generic 函数定义 lift -- 删除 `skipIncompleteInputs`
1+
删除 `skipIncompleteInputs`
22
monads/supported-monad -- 删除 `maybeUnwrapSupported`
33

44
> propagator 支持 dependencies for provenance

‎src/monad/index.ts‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
import { defineGeneric } from "../generic/index.js"
22

3-
export const fmap = defineGeneric({ default: (f, mx) => f(mx) })
4-
export const join = defineGeneric({ default: (mmx) => mmx })
5-
export const bind = (mx: any, f: (x: any) => any) => join(fmap(f, mx))
3+
// (f: (A) -> B, ma: M(A)) -> M(B)
4+
export const fmap = defineGeneric({ default: (f, ma) => f(ma) })
5+
6+
// (mma: M(M(A))) -> M(A)
7+
export const join = defineGeneric({ default: (mma) => mma })
8+
9+
// (ma: M(A), f: (A) -> M(B)) -> M(B)
10+
export const bind = (ma: any, f: (x: any) => any) => join(fmap(f, ma))
11+
12+
// (f: (A0, A1, ...) -> B) -> (M(A0), M(A1), ...) -> M(B)
13+
export function naryFmap(
14+
f: (...args: Array<any>) => any,
15+
): (...margs: Array<any>) => any {
16+
return (...margs) => {
17+
function loop(margs: Array<any>, f: (...args: Array<any>) => any): any {
18+
if (margs.length === 0) return f()
19+
20+
return bind(margs[0], (arg) =>
21+
loop(margs.slice(1), (...restArgs) => f(arg, ...restArgs)),
22+
)
23+
}
24+
25+
return loop(margs, f)
26+
}
27+
}

‎src/monads/nothing-monad.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import { defineHandler } from "../generic/index.js"
33
import { fmap, join } from "../monad/index.js"
44
import { isFunction } from "../utils/isFunction.js"
55

6-
defineHandler(fmap, [isFunction, isNothing], (f, mx) => nothing)
7-
defineHandler(join, [isNothing], (mmx) => nothing)
6+
defineHandler(fmap, [isFunction, isNothing], (f, ma) => nothing)
7+
defineHandler(join, [isNothing], (mma) => nothing)

‎src/propagator/definePrimitive.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Cell, addPropagator, isNothing, nothing, put } from "../cell/index.js"
22
import { isSupported } from "../dependency/index.js"
3+
import { naryFmap } from "../monad/index.js"
4+
import "../monads/nothing-monad.js"
35
import { schedule } from "../scheduler/index.js"
46
import type { MaybePromise } from "../utils/MaybePromise.js"
57
import { repeatApply } from "../utils/repeatApply.js"
@@ -87,8 +89,7 @@ function watch(cells: Array<Cell<any>>, propagator: Propagator): void {
8789
function lift(
8890
fn: (...args: Array<any>) => MaybePromise<any>,
8991
): (...args: Array<Cell<any>>) => MaybePromise<any> {
90-
fn = maybeUnwrapSupported(fn)
91-
fn = skipIncompleteInputs(fn)
92+
fn = naryFmap(fn)
9293

9394
return (...inputs) => fn(...inputs.map((input) => input.content))
9495
}

0 commit comments

Comments
 (0)