编程与类型系统05
发表于:2024-06-29 | 分类: 学习

函数类型

策略模式

策略设计模式是一种行为软件设计模式,允许在运行时从一组算法中选择某个算法。它把算法与使用算法
的组件解耦,从而提高了整个系统的灵活性。

函数的类型

  • 函数类型或签名:函数的实参类型和返回类型决定了函数的类型。如果两个函数接受相同的实参,并返回相同的类型,那么它们具有相同的类型。实参集合加上返回类型也称为函数的签名。
  • 一等函数:将函数赋值给变量,并像处理类型系统中的其他值一样处理它们,就得到了所谓的一等函数。这意味着语言将函数视为“一等公民”,赋予它们与其他值相同的权利:它们有类型,可被赋值给变量,可作为实参传递,可被检查是否有效,以及在兼容的情况下可被转换为其他类型。

不使用 switch 语句的状态机

使用switch的状态机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
enum TextMod {
Text,
Marker,
Code,
}

class TextRender {
private mode: TextMod = TextMod.Text;
private result: string[] = [];
private codeSample: string[] = [];
renderText(lines: string[]): string[] {
this.result = [];
this.mode = TextMod.Text;
for (let line of lines) {
this.renderLine(line);
}
return this.result;
}
private renderLine(line: string): void {
switch (this.mode) {
case TextMod.Text:
this.renderTextLine(line);
break;
case TextMod.Marker:
this.renderMarkerLine(line);
break;
case TextMod.Code:
this.renderCodeLine(line);
break;
}
}
private renderTextLine(line: string): void {
this.result.push(line);
if (line.startsWith("<!--")) {
this.loadCodeSample(line);
this.mode = TextMod.Marker;
}
}
private renderMarkerLine(line: string): void {
this.result.push(line);
if (line.startsWith("```ts")) {
this.result = this.result.concat(this.codeSample);
this.mode = TextMod.Code;
}
}
private renderCodeLine(line: string): void {
if (line.startsWith("```")) {
this.result.push(line);
this.mode = TextMod.Text;
}
}
private loadCodeSample(line: string): void {}
}

另外一种状态机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class renderText {
private result: string[] = [];
private renderLine: (line: string) => void = this.renderTextLine;
private codeSample: string[] = [];

renderTexted(lines: string[]): string[] {
this.result = [];
this.renderLine = this.renderTextLine;
for (let line of lines) {
this.renderLine(line);
}
return this.result;
}

private renderTextLine(line: string): void {
this.result.push(line);
if (line.startsWith("<!--")) {
this.loadCodeSample(line);
this.renderLine = this.renderMarkerLine;
}
}
private renderMarkerLine(line: string): void {
this.result.push(line);
if (line.startsWith("```ts")) {
this.result = this.result.concat(this.codeSample);
this.renderLine = this.renderCodeLine;
}
}
private renderCodeLine(line: string): void {
if (line.startsWith("```")) {
this.result.push(line);
this.renderLine = this.renderTextLine;
}
}
private loadCodeSample(line: string): void {}
}

使用和类型的状态机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class RenderTextLine {
result: string[];

constructor(result: string[]) {
this.result = result;
}

render(line: string): RenderTextLine | RenderMarkerLine {
this.result.push(line);
if (line.startsWith("<!--")) {
return new RenderMarkerLine(this.result, this.loadCodeSample(line));
} else {
return this;
}
}

private loadCodeSample(line: string): string[] {
let newlines: string[] = [];
newlines.push(line);
return newlines;
}
}

class RenderMarkerLine {
result: string[];
codeSample: string[];
constructor(result: string[], codeSample: string[]) {
this.result = result;
this.codeSample = codeSample;
}
render(line: string): RenderMarkerLine | RenderCodeLine {
this.result.push(line);
if (line.startsWith("```ts")) {
this.result = this.result.concat(this.codeSample);
return new RenderCodeLine(this.result);
} else {
return this;
}
}
}

class RenderCodeLine {
result: string[];
constructor(result: string[]) {
this.result = result;
}

render(line: string): RenderCodeLine | RenderTextLine {
if (line.startsWith("```")) {
this.result.push(line);
return new RenderTextLine(this.result);
} else {
return this;
}
}
}
function RenderText(lines: string): string[] {
let render: RenderTextLine | RenderMarkerLine | RenderCodeLine =
new RenderTextLine([]);
for (let line of lines) {
render = render.render(line);
}
return render.result;
}

立即创建和延迟创建

  • 立即创建:立即得到并传递值,即使我们在以后决定丢弃该值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Bike {}
    class Car {}
    function makeRide(isRunning: boolean, bike: Bike, car: Car): Bike | Car {
    if (isRunning) {
    return car;
    } else {
    return bike;
    }
    }
    makeRide(false, new Bike(), new Car());

  • 延迟创建:计算是以函数的方式表达的,传递的是函数而非实际的值,所以可以在需要值的时候调用函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Bike {}
    class Car {}
    function makeRide(isRunning: boolean, bike: Bike, car: () => Car): Bike | Car {
    if (isRunning) {
    return car();
    } else {
    return bike;
    }
    }
    function makeCar() {
    return new Car();
    }
    makeRide(false, new Bike(), makeCar);

lambda

使用匿名函数:

1
2
3
4
5
6
7
8
9
10
11
class Bike {}
class Car {}
function makeRide(isRunning: boolean, bike: Bike, car: () => Car): Bike | Car {
if (isRunning) {
return car();
} else {
return bike;
}
}
makeRide(false, new Bike(), () => new Car());

lambda,也称为匿名函数,是没有名称的函数定义。lambda 通常用于一次性的、短期存在的处理,并像数据一样被传来传去。

自制 map()

1
2
3
4
5
6
7
8
function map(items, func) {
var result = [];
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
var item = items_1[_i];
result.push(func(item));
}
return result;
}

自制 filter()

1
2
3
4
5
6
7
8
9
function filter<T>(items: T[], func: (item: T) => T[]): T[] {
let result: T[] = [];
for (const item of items) {
if (func(item)) {
result.push(item);
}
}
return result;
}

自制 reduce()

1
2
3
4
5
6
7
function reduce<T>(items: T[], previous: T, next: (x: T, y: T) => T): T {
let result: T = previous;
for (const item of items) {
result = next(result, item);
}
return result;
}
上一篇:
编程与类型系统06
下一篇:
编程与类型系统04