Monad 是函數式程式設計中的一個基本概念,它提供了一種以結構化方式處理計算和資料轉換的方法。 monad 有多種類型,每種類型都旨在解決特定問題並處理不同類型的資料和效果。
單子是一種抽象,允許對包裝值進行連結操作。它由三個主要屬性定義:
Maybe Monad 用於處理可選值。它表示可能失敗或傳回 null 或未定義的計算。
class Maybe { constructor(value) { this.value = value; } static of(value) { return new Maybe(value); } isNothing() { return this.value === null || this.value === undefined; } map(fn) { return this.isNothing() ? this : Maybe.of(fn(this.value)); } flatMap(fn) { return this.isNothing() ? this : fn(this.value); } } // Usage const maybeValue = Maybe.of('hello') .map(str => str.toUpperCase()) .flatMap(str => Maybe.of(`${str} WORLD`)); console.log(maybeValue); // Maybe { value: 'HELLO WORLD' }
Either Monad 用於處理可以傳回成功值(右)或錯誤值(左)的計算。
class Either { constructor(value, isRight = true) { this.value = value; this.isRight = isRight; } static right(value) { return new Either(value, true); } static left(value) { return new Either(value, false); } map(fn) { return this.isRight ? Either.right(fn(this.value)) : this; } flatMap(fn) { return this.isRight ? fn(this.value) : this; } } // Usage const rightValue = Either.right(5) .map(x => x 1) .flatMap(x => Either.right(x * 2)); console.log(rightValue); // Either { value: 12, isRight: true } const leftValue = Either.left('error') .map(x => x 1) .flatMap(x => Either.right(x * 2)); console.log(leftValue); // Either { value: 'error', isRight: false }
Promise Monad 用於處理非同步計算。
const fetchData = url => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(`Data from ${url}`); }, 1000); }); }; // Usage fetchData('https://api.example.com') .then(data => { console.log(data); // 'Data from https://api.example.com' return fetchData('https://api.example.com/2'); }) .then(data => { console.log(data); // 'Data from https://api.example.com/2' }) .catch(error => { console.error(error); });
List Monad 用於處理生成值清單的計算。
class List { constructor(values) { this.values = values; } static of(values) { return new List(values); } map(fn) { return List.of(this.values.map(fn)); } flatMap(fn) { return List.of(this.values.flatMap(value => fn(value).values)); } } // Usage const list = List.of([1, 2, 3]) .map(x => x 1) .flatMap(x => List.of([x, x * 2])); console.log(list); // List { values: [ 2, 4, 3, 6, 4, 8 ] }
Reader Monad 用於處理依賴某些共享環境或配置的計算。
class Reader { constructor(fn) { this.fn = fn; } static of(value) { return new Reader(() => value); } map(fn) { return new Reader(env => fn(this.fn(env))); } flatMap(fn) { return new Reader(env => fn(this.fn(env)).fn(env)); } run(env) { return this.fn(env); } } // Usage const config = { baseURL: 'https://api.example.com' }; const fetchUser = new Reader(env => `${env.baseURL}/user`); const fetchPosts = new Reader(env => `${env.baseURL}/posts`); const fetchUserAndPosts = fetchUser.flatMap(userURL => fetchPosts.map(postsURL => ({ userURL, postsURL })) ); console.log(fetchUserAndPosts.run(config)); // { userURL: 'https://api.example.com/user', postsURL: 'https://api.example.com/posts' }
Writer Monad 用於處理生成值以及日誌或附加資料的計算。
class Writer { constructor(value, log) { this.value = value; this.log = log; } static of(value) { return new Writer(value, ''); } map(fn) { const result = fn(this.value); return new Writer(result.value, this.log result.log); } flatMap(fn) { const result = fn(this.value); return new Writer(result.value, this.log result.log); } tell(log) { return new Writer(this.value, this.log log); } } // Usage const writer = Writer.of(3) .map(value => new Writer(value 1, 'Incremented\n')) .flatMap(value => new Writer(value * 2, 'Doubled\n')); console.log(writer); // Writer { value: 8, log: 'Incremented\nDoubled\n' }
State Monad 用於處理維護狀態的計算。
class State { constructor(runState) { this.runState = runState; } static of(value) { return new State(state => [value, state]); } map(fn) { return new State(state => { const [value, newState] = this.runState(state); return [fn(value), newState]; }); } flatMap(fn) { return new State(state => { const [value, newState] = this.runState(state); return fn(value).runState(newState); }); } run(initialState) { return this.runState(initialState); } } // Usage const increment = new State(state => [state 1, state 1]); const result = increment .flatMap(() => increment) .flatMap(() => increment) .run(0); console.log(result); // [3, 3]
Monad 提供了一種結構化且可預測的方式來處理函數式程式設計中的計算和資料轉換。每種類型的 monad 都有特定的用途,從使用 Maybe Monad 處理可選值到使用 Promise Monad 管理非同步操作。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3