Nest.JS | Monads -> ผู้อ่าน

Jan 27 2023
Reader monad หรือที่เรียกว่า "Environment monad" เป็นแนวคิดการเขียนโปรแกรมเชิงฟังก์ชันที่อนุญาตให้คุณส่งผ่านสภาพแวดล้อมหรือบริบทที่ใช้ร่วมกันตลอดการคำนวณ ช่วยให้คุณสามารถเขียนโค้ดที่ไม่ขึ้นกับค่าเฉพาะของบริบทนั้น ทำให้สามารถใช้ซ้ำได้มากขึ้นและทดสอบได้ง่ายขึ้น

Reader monad หรือที่เรียกว่า "Environment monad" เป็นแนวคิดการเขียนโปรแกรมเชิงฟังก์ชันที่อนุญาตให้คุณส่งผ่านสภาพแวดล้อมหรือบริบทที่ใช้ร่วมกันตลอดการคำนวณ ช่วยให้คุณสามารถเขียนโค้ดที่ไม่ขึ้นกับค่าเฉพาะของบริบทนั้น ทำให้สามารถใช้ซ้ำได้มากขึ้นและทดสอบได้ง่ายขึ้น

Reader monad มักจะใช้ในการจัดการการขึ้นต่อกันและค่าการกำหนดค่าในภาษาการเขียนโปรแกรมเชิงฟังก์ชัน เช่น JavaScript Reader monad ช่วยให้คุณอธิบายการคำนวณที่ขึ้นอยู่กับบริบทภายนอกบางส่วนด้วยวิธีที่บริสุทธิ์และเรียบเรียงได้ ซึ่งช่วยให้เหตุผลและทดสอบโค้ดของคุณง่ายขึ้น

โดยทั่วไปแล้ว Reader monad จะถูกนำไปใช้เป็นวัตถุที่มีเมธอดเดียว ซึ่งเรียกว่าrunซึ่งรับบริบทเป็นอินพุตและส่งกลับผลลัพธ์ของการคำนวณ สามารถใช้ Reader monad เพื่อเชื่อมโยงการคำนวณหลายรายการเข้าด้วยกันซึ่งขึ้นอยู่กับบริบทเดียวกันและสร้างการคำนวณที่ซับซ้อนมากขึ้น

นี่คือตัวอย่างของ Reader monad ใน JavaScript:

class Reader {
  constructor(fn) {
    this.run = fn
  }
  map(f) {
    return new Reader(e => f(this.run(e)))
  }
  chain(f) {
    return new Reader(e => f(this.run(e)).run(e))
  }
  // ...
}

ตัวอย่างเช่น คุณสามารถสร้าง Reader ที่ใช้วัตถุการกำหนดค่าและส่งกลับค่าตามการกำหนดค่านั้น จากนั้นคุณสามารถเชื่อมโยง Reader หลายตัวเข้าด้วยกันเพื่อสร้างการคำนวณที่ซับซ้อนยิ่งขึ้น โดยไม่ต้องส่งออบเจกต์การกำหนดค่าผ่านแต่ละขั้นตอน

สิ่งสำคัญคือต้องทราบว่า Reader Monad ไม่ใช่รูปแบบทั่วไปใน JavaScript แต่ส่วนใหญ่จะใช้ในภาษาการเขียนโปรแกรมเชิงฟังก์ชัน เช่น Haskell, scala เป็นต้น

ตัวอย่างวิธีใช้ReaderMonad ใน Nest.js:

import { Injectable } from '@nestjs/common';
import { Reader, reader } from 'fp-ts/lib/Reader';

@Injectable()
export class MyService {
  public incrementCounter(counter: number): Reader<number, number> {
    return reader.of(counter + 1);
  }

  public decrementCounter(counter: number): Reader<number, number> {
    return reader.of(counter - 1);
  }

  public getCounter(counter: number): Reader<number, number> {
    return reader.of(counter);
  }
}

Monad Readerใช้เพื่อสรุปการผ่านการกำหนดค่า การพึ่งพา หรือบริบทตลอดทั้งโปรแกรมหรือชุดของฟังก์ชัน

ในตัวอย่างนี้incrementCounter()เมธอดเพิ่มตัวนับและส่งคืนค่าใหม่decrementCounter()เมธอดลดตัวนับและส่งคืนค่าใหม่getCounter()เมธอดส่งคืนค่าตัวนับปัจจุบัน

คุณสามารถเชื่อมโยงการคำนวณหลายรายการโดยใช้เมธอด.map(), .chain(),.ap()

const program: Reader<number, number> = myService
  .incrementCounter(10)
  .chain(counter => myService.decrementCounter(counter))
  .chain(counter => myService.getCounter(counter));

console.log(program.run());

สิ่งสำคัญคือต้องสังเกตว่าตัวอย่างนี้เป็นเพียงตัวอย่างพื้นฐานและไม่ได้แสดงให้เห็นถึงพลังทั้งหมดของ Monads ในการเขียนโปรแกรมเชิงฟังก์ชัน Monads สามารถใช้เพื่อจัดการกรณีต่างๆ เช่น การจัดการข้อผิดพลาด การผูกมัดการคำนวณหลายรายการ และอื่นๆ คุณควรเข้าใจปัญหาและใช้กรณีต่างๆ ก่อนใช้ Monads

นอกจากนี้run()ต้องเรียกใช้เมธอดเพื่อดำเนินการ Reader Monad และรับผลลัพธ์ โดยจะใช้สภาพแวดล้อมเป็นอาร์กิวเมนต์

รายการชิ้นส่วน: