File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11# 210_5
22
3+ ## 2026/4/13 实现 either-flat-map
4+
35## 2026/1/20 修改either的实现方法
46
5- ## 2026/1/19 开源either相关的代码
7+ ## 2026/1/19 开源either相关的代码
Original file line number Diff line number Diff line change 2020 from-right to-right
2121 either? ; 导出通用判断函数
2222 either-left? either-right?
23- either-map either-for-each
23+ either-map either-flat-map either- for-each
2424 either-get-or-else
2525 either-or-else
2626 either-filter-or-else
122122 ) ; if
123123 ) ; define
124124
125+ ; ; 扁平映射函数:如果 either 是右值,则应用返回 Either 的函数 f
126+ (define (either-flat-map f either )
127+ (check-either either " either-flat-map" )
128+ (unless (procedure? f)
129+ (type-error (format #f " In function either-flat-map: argument *f* must be *procedure*! **Got ~a**" f))
130+ ) ; unless
131+ (if (either-right? either)
132+ (let ((result (f (to-right either))))
133+ (check-either result " either-flat-map: return value of f must be an Either" )
134+ result
135+ ) ; let
136+ either
137+ ) ; if
138+ ) ; define
139+
125140 ; ; 遍历函数:如果 either 是右值,则应用函数 f (执行副作用)
126141 (define (either-for-each f either )
127142 (check-either either " either-for-each" )
Original file line number Diff line number Diff line change 3838; ; 三、高阶操作
3939; ; 用于映射、遍历和过滤 Either 的函数
4040; ; either-map - 仅对 Right 中的值进行映射
41+ ; ; either-flat-map - 对 Right 执行返回 Either 的链式操作
4142; ; either-for-each - 仅对 Right 中的值执行副作用
4243; ; either-filter-or-else - 不满足条件时回退到 Left
4344; ; either-contains? - 判断 Right 中的值是否满足目标
Original file line number Diff line number Diff line change 1+ (import (liii check)
2+ (liii error)
3+ (liii either)
4+ ) ; import
5+
6+ (check-set-mode! 'report-failed )
7+
8+ ; ; either-flat-map
9+ ; ; 对 Right 值执行返回 Either 的过程,并避免产生嵌套 Either。
10+ ; ;
11+ ; ; 语法
12+ ; ; ----
13+ ; ; (either-flat-map proc either)
14+ ; ;
15+ ; ; 参数
16+ ; ; ----
17+ ; ; proc : procedure?
18+ ; ; 要应用到 Right 值上的函数,返回值应为 Either。
19+ ; ;
20+ ; ; either : either
21+ ; ; 输入 Either 值。
22+ ; ;
23+ ; ; 返回值
24+ ; ; ----
25+ ; ; either
26+ ; ; 若输入为 Right,则返回 proc 的结果;若输入为 Left,则原样返回。
27+ ; ;
28+ ; ; 注意
29+ ; ; ----
30+ ; ; 对 Left 具有短路特性,不会执行 proc。
31+ ; ;
32+ ; ; 示例
33+ ; ; ----
34+ ; ; (to-right (either-flat-map (lambda (x) (from-right (* x 2))) (from-right 5))) => 10
35+ ; ;
36+ ; ; 错误处理
37+ ; ; ----
38+ ; ; type-error 当 proc 不是过程或 either 不是 Either 时
39+
40+ (let ((left-val (from-left " error" ))
41+ (right-val (from-right 5 )))
42+ (check (to-left (either-flat-map (lambda (x ) (from-right (* x 2 ))) left-val)) => " error" )
43+ (let ((result (either-flat-map (lambda (x ) (from-right (* x 2 ))) right-val)))
44+ (check-true (either-right? result))
45+ (check (to-right result) => 10 )
46+ ) ; let
47+ ) ; let
48+
49+ (let* ((val1 (from-right 10 ))
50+ (val2 (either-flat-map (lambda (x ) (from-right (+ x 5 ))) val1))
51+ (val3 (either-flat-map (lambda (x ) (from-right (* x 2 ))) val2)))
52+ (check-true (either-right? val3))
53+ (check (to-right val3) => 30 )
54+ ) ; let*
55+
56+ (let ((result (either-flat-map (lambda (x ) (from-left (string-append " bad: " (number->string x))))
57+ (from-right 7 ))))
58+ (check-true (either-left? result))
59+ (check (to-left result) => " bad: 7" )
60+ ) ; let
61+
62+ (check-catch 'type-error (either-flat-map (lambda (x ) (from-right x)) " not-either" ))
63+ (check-catch 'type-error (either-flat-map " not-a-proc" (from-right 10 )))
64+
65+ (check-report)
You can’t perform that action at this time.
0 commit comments