Nest.JS | Monads -> รัฐ
State monad เป็นแนวคิดการเขียนโปรแกรมเชิงฟังก์ชันที่ช่วยให้คุณจัดการสถานะในลักษณะที่ใช้งานได้และไม่เปลี่ยนรูป ช่วยให้คุณเขียนโค้ดที่อัปเดตสถานะของการคำนวณด้วยวิธีที่บริสุทธิ์และเรียบเรียงได้ ซึ่งทำให้ง่ายต่อการให้เหตุผลและทดสอบ
State monad มักถูกใช้เพื่อจัดการการคำนวณ stateful ในภาษาโปรแกรมเชิงฟังก์ชัน เช่น JavaScript monad สถานะช่วยให้คุณอธิบายการคำนวณที่อัปเดตสถานะบางอย่างด้วยวิธีที่บริสุทธิ์และเรียบเรียงได้ ซึ่งทำให้ง่ายต่อการให้เหตุผลเกี่ยวกับและทดสอบรหัสของคุณ
โดยทั่วไปแล้ว monad ของสถานะจะถูกนำไปใช้เป็นวัตถุที่มีเมธอดเดียว ซึ่งเรียกว่าrunซึ่งรับสถานะเริ่มต้นเป็นอินพุตและส่งกลับผลลัพธ์ของการคำนวณและสถานะที่อัปเดต สามารถใช้ State monad เพื่อเชื่อมโยงการคำนวณหลายรายการเข้าด้วยกันซึ่งอัปเดตสถานะเดียวกันและสร้างการคำนวณที่ซับซ้อนมากขึ้น
นี่คือตัวอย่างของ State monad ใน JavaScript:
class State {
constructor(fn) {
this.run = fn
}
map(f) {
return new State((state) => {
const [result, updatedState] = this.run(state);
return [f(result), updatedState];
});
}
chain(f) {
return new State((state) => {
const [result, updatedState] = this.run(state);
return f(result).run(updatedState);
});
}
// ...
}
ตัวอย่างเช่น คุณสามารถสร้างสถานะที่รับหมายเลขเริ่มต้นและส่งคืนหมายเลขใหม่โดยเพิ่มขึ้นทีละหนึ่ง จากนั้นคุณสามารถเชื่อมโยงหลายสถานะเหล่านี้เข้าด้วยกันเพื่อสร้างการคำนวณที่ซับซ้อนมากขึ้นซึ่งจะอัปเดตสถานะหลายครั้งโดยไม่ต้องส่งค่าด้วยตนเอง ระบุในแต่ละขั้นตอน
โปรดทราบว่า State Monad ไม่ใช่รูปแบบทั่วไปใน JavaScript ส่วนใหญ่จะใช้ในภาษาการเขียนโปรแกรมเชิงฟังก์ชัน เช่น Haskell, scala เป็นต้น
ตัวอย่างวิธีใช้StateMonad ใน Nest.js:
import { Injectable } from '@nestjs/common';
import { State, state } from 'fp-ts/lib/State';
interface StateType {
counter: number;
}
@Injectable()
export class MyService {
public incrementCounter(): State<StateType, number> {
return state.get().map(s => s.counter + 1).put({ counter: s.counter + 1 });
}
public decrementCounter(): State<StateType, number> {
return state.get().map(s => s.counter - 1).put({ counter: s.counter - 1 });
}
public getCounter(): State<StateType, number> {
return state.get().map(s => s.counter);
}
}
Monad Stateใช้เพื่อจัดการสถานะในลักษณะการทำงาน ตัวอย่างนี้ใช้ตัวนับอย่างง่ายเป็นสถานะ แต่สถานะอาจเป็นอะไรก็ได้ เช่น วัตถุหรืออาร์เรย์
เมธอดincrementCounter()เพิ่มตัวนับและอัปเดตสถานะdecrementCounter()เมธอดลดตัวนับและอัปเดตสถานะ เมธอดgetCounter()ส่งคืนค่าตัวนับปัจจุบัน
คุณสามารถเชื่อมโยงการคำนวณหลายรายการโดยใช้เมธอด.map(), .chain(),.ap()
const program: State<StateType, number> = myService
.incrementCounter()
.chain(() => myService.incrementCounter())
.chain(() => myService.getCounter());
console.log(program.run({ counter: 0 }).value);
สิ่งสำคัญคือต้องสังเกตว่าตัวอย่างนี้เป็นเพียงตัวอย่างพื้นฐานและไม่ได้แสดงให้เห็นถึงพลังทั้งหมดของ Monads ในการเขียนโปรแกรมเชิงฟังก์ชัน Monads สามารถใช้เพื่อจัดการกรณีต่างๆ เช่น การจัดการข้อผิดพลาด การผูกมัดการคำนวณหลายรายการ และอื่นๆ คุณควรเข้าใจปัญหาและใช้กรณีต่างๆ ก่อนใช้ Monads
นอกจากนี้run()ต้องเรียกเมธอดเพื่อดำเนินการ State Monad และรับผลลัพธ์ โดยจะใช้สถานะเริ่มต้นเป็นอาร์กิวเมนต์
รายการชิ้นส่วน:





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)