-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipe-and-flow.ts
69 lines (56 loc) · 1.77 KB
/
pipe-and-flow.ts
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
66
67
68
69
/**
* Both pipe and flow are used to compose operations
*/
import { flow, pipe } from "fp-ts/function";
// ===== PIPE =====
/**
* A -> B
*/
const getValueLength = (value: string) => value.length;
pipe("hello", getValueLength); // Evaluates to 5
/**
* A -> B -> C
*/
const isAtLeast3 = (n: number) => n >= 3;
pipe("hello", getValueLength, isAtLeast3); // Evaluates to true
/**
* A -> B -> C -> D
*/
const trim = (value: string) => value.trim();
pipe(
" hi ",
trim, // 'hi'
getValueLength, // 2
isAtLeast3 // false
);
// The above operation is equivalent to:
isAtLeast3(getValueLength(trim("hello")));
// All functions passed to pipe must be unary, therefore taking only one argument
// Raw implementation without library abstraction:
export const pipeRaw = <A, B, C>(a: A, f: (a: A) => B, g: (b: B) => C): C =>
g(f(a));
// ===== FLOW =====
/**
* The `flow` function performs function composition
*
* In general, if a function receives a single argument (unary) and pipes it
* into a series of functions, it's possible to replace it with `flow`
*/
// Example: Composing two functions
// A -> B -> C
const isLongEnough = flow(getValueLength, isAtLeast3);
isLongEnough("hello"); // Evaluates to true
// Example: Composing three functions
// A -> B -> C
const isValid1 = flow(trim, getValueLength, isAtLeast3);
isValid1(" hello "); // Evaluates to true
// Example: Composing four functions, and the first one receives 2 arguments
// A -> B -> C -> D
const concat = (value1: string, value2: string) => value1 + value2;
const isValid2 = flow(concat, trim, getValueLength, isAtLeast3);
isValid2("hey", "hey"); // Evaluates to true
// Raw implementation without library abstraction:
export const flowRaw =
<A, B, C>(f: (a: A) => B, g: (b: B) => C) =>
(a: A): C =>
g(f(a));