当前位置:首页 > 文章列表 > 文章 > 前端 > JavaScript 函数式编程简介:不同的 monad #11

JavaScript 函数式编程简介:不同的 monad #11

来源:dev.to 2024-07-16 08:27:50 0浏览 收藏

珍惜时间,勤奋学习!今天给大家带来《JavaScript 函数式编程简介:不同的 monad #11》,正文内容主要涉及到等等,如果你正在学习文章,或者是对文章有疑问,欢迎大家关注我!后面我会持续更新相关内容的,希望都能帮到正在学习的大家!

JavaScript 函数式编程简介:不同的 monad #11

monad 是函数式编程中的一个基本概念,它提供了一种以结构化方式处理计算和数据转换的方法。单子有多种类型,每种类型都旨在解决特定问题并处理不同类型的数据和效果。

什么是 monad?

单子是一种抽象,允许对包装值进行链接操作。它由三个主要属性定义:

  1. unit(也称为 of 或 return):接受一个值并将其包装在 monad 中的函数。
  2. bind(也称为 flatmap 或 chain):一个函数,它接受一个 monadic 值和一个返回 monad 的函数,将该函数应用于包装的值,并返回一个新的 monad。
  3. 结合性:一元运算的组合应该是结合性的。

monad 的常见类型

  1. 也许是 monad
  2. monad
  3. 承诺莫纳德
  4. 列出 monad
  5. 读者莫纳德
  6. 作家莫纳德
  7. 状态 monad

1.也许是莫纳德

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' }

2. 任一 monad

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 }

3. 承诺单子

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);
  });

4. 列出单子

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 ] }

5. 读者单子

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' }

6.作家莫纳德

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' }

7. 状态单子

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 管理异步操作。

本篇关于《JavaScript 函数式编程简介:不同的 monad #11》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

版本声明
本文转载于:dev.to 如有侵犯,请联系study_golang@163.com删除
Nextjs 中的路由国际化指南 (i)Nextjs 中的路由国际化指南 (i)
上一篇
Nextjs 中的路由国际化指南 (i)
Python 循环 1
下一篇
Python 循环 1
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • SEO标题协启动:AI驱动的智能对话与内容生成平台 - 提升创作效率
    协启动
    SEO摘要协启动(XieQiDong Chatbot)是由深圳协启动传媒有限公司运营的AI智能服务平台,提供多模型支持的对话服务、文档处理和图像生成工具,旨在提升用户内容创作与信息处理效率。平台支持订阅制付费,适合个人及企业用户,满足日常聊天、文案生成、学习辅助等需求。
    2次使用
  • Brev AI:零注册门槛的全功能免费AI音乐创作平台
    Brev AI
    探索Brev AI,一个无需注册即可免费使用的AI音乐创作平台,提供多功能工具如音乐生成、去人声、歌词创作等,适用于内容创作、商业配乐和个人创作,满足您的音乐需求。
    2次使用
  • AI音乐实验室:一站式AI音乐创作平台,助力音乐创作
    AI音乐实验室
    AI音乐实验室(https://www.aimusiclab.cn/)是一款专注于AI音乐创作的平台,提供从作曲到分轨的全流程工具,降低音乐创作门槛。免费与付费结合,适用于音乐爱好者、独立音乐人及内容创作者,助力提升创作效率。
    2次使用
  • SEO标题PixPro:AI驱动网页端图像处理平台,提升效率的终极解决方案
    PixPro
    SEO摘要PixPro是一款专注于网页端AI图像处理的平台,提供高效、多功能的图像处理解决方案。通过AI擦除、扩图、抠图、裁切和压缩等功能,PixPro帮助开发者和企业实现“上传即处理”的智能化升级,适用于电商、社交媒体等高频图像处理场景。了解更多PixPro的核心功能和应用案例,提升您的图像处理效率。
    2次使用
  • EasyMusic.ai:零门槛AI音乐生成平台,专业级输出助力全场景创作
    EasyMusic
    EasyMusic.ai是一款面向全场景音乐创作需求的AI音乐生成平台,提供“零门槛创作 专业级输出”的服务。无论你是内容创作者、音乐人、游戏开发者还是教育工作者,都能通过EasyMusic.ai快速生成高品质音乐,满足短视频、游戏、广告、教育等多元需求。平台支持一键生成与深度定制,积累了超10万创作者,生成超100万首音乐作品,用户满意度达99%。
    3次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码