ลองนึกภาพว่าเราต้องการใช้ชุดของฟังก์ชันกับxif และเฉพาะในกรณีที่xไม่ใช่ค่าว่าง:
if (x !== null) x = a(x);
if (x !== null) x = b(x);
if (x !== null) x = c(x);
ตอนนี้สมมติว่าเราต้องทำเช่นเดียวกันกับy:
if (y !== null) y = a(y);
if (y !== null) y = b(y);
if (y !== null) y = c(y);
และเช่นเดียวกับz:
if (z !== null) z = a(z);
if (z !== null) z = b(z);
if (z !== null) z = c(z);
อย่างที่คุณเห็นโดยไม่มีนามธรรมที่เหมาะสมเราจะต้องทำซ้ำโค้ดซ้ำแล้วซ้ำเล่า สิ่งที่เป็นนามธรรมดังกล่าวมีอยู่แล้ว: อาจจะเป็นโมนาด
บางที monad ถือทั้งมูลค่าและบริบทการคำนวณ:
- monad รักษามูลค่าให้ปลอดภัยและใช้ฟังก์ชันต่างๆ
- บริบทการคำนวณคือการตรวจสอบค่าว่างก่อนใช้ฟังก์ชัน
การใช้งานที่ไร้เดียงสาจะมีลักษณะดังนี้:
⚠️การใช้งานนี้มีวัตถุประสงค์เพื่อเป็นภาพประกอบเท่านั้น! นี่ไม่ใช่วิธีที่ควรทำและผิดในหลายระดับ อย่างไรก็ตามสิ่งนี้จะช่วยให้คุณเข้าใจได้ดีขึ้นว่าฉันกำลังพูดถึงอะไร
อย่างที่คุณเห็นว่าไม่มีอะไรสามารถทำลายได้:
- เราใช้ชุดฟังก์ชันเพื่อคุณค่าของเรา
- หาก ณ จุดใดค่าจะกลายเป็นโมฆะ (หรือไม่ได้กำหนด) เราก็ไม่ใช้ฟังก์ชันใด ๆ อีกต่อไป
const abc = obj =>
Maybe
.of(obj)
.map(o => o.a)
.map(o => o.b)
.map(o => o.c)
.value;
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script>
function Maybe(x) {
this.value = x; //-> container for our value
}
Maybe.of = x => new Maybe(x);
Maybe.prototype.map = function (fn) {
if (this.value == null) { //-> computational context
return this;
}
return Maybe.of(fn(this.value));
};
</script>
ภาคผนวก 1
ฉันไม่สามารถอธิบายได้ว่า monads คืออะไรเนื่องจากนี่ไม่ใช่จุดประสงค์ของโพสต์นี้และมีคนที่ดีกว่าฉัน อย่างไรก็ตามดังที่ Eric Elliot กล่าวไว้ในโพสต์บล็อกประวัติ JavaScript Monads Made Simple :
ไม่ว่าคุณจะมีทักษะในระดับใดหรือเข้าใจทฤษฎีหมวดหมู่การใช้ monads ทำให้โค้ดของคุณทำงานได้ง่ายขึ้น การไม่ใช้ประโยชน์จาก monads อาจทำให้โค้ดของคุณทำงานได้ยากขึ้น (เช่น callback hell, สาขาตามเงื่อนไขที่ซ้อนกัน, ความฟุ่มเฟื่อยมากขึ้น)
ภาคผนวก 2
นี่คือวิธีที่ฉันจะแก้ปัญหาของคุณโดยใช้ไฟล์ Maybe monad frommonetjs
const prop = key => obj => Maybe.fromNull(obj[key]);
const abc = obj =>
Maybe
.fromNull(obj)
.flatMap(prop('a'))
.flatMap(prop('b'))
.flatMap(prop('c'))
.orSome('🌯')
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script src="https://www.unpkg.com/monet@0.9.0/dist/monet.js"></script>
<script>const {Maybe} = Monet;</script>
try..catchคำสั่ง ที่กล่าวว่าอาร์เรย์ที่มีองค์ประกอบที่แตกต่างกันอย่างมากดูเหมือนจะเป็นปัญหาในการออกแบบสำหรับฉัน