你是一个想了解单子背后理论的Java开发者吗?在这里你会找到一步一步的教程,帮助你理解它们。

单子是一个概念,来源于数学的一个部分,叫做范畴论,而不是一个阶级或者特质。在本文中,我将尝试解释它的结构和内部工作原理。随着...的使用可选择的在Java中,我将尝试用一种更容易理解的方式来描述所有这些。我还将实现一个基本的monad来更好地理解它们是如何工作的,并以一个简短的使用示例来展示monad相对于非monad方法的优势。

为什么要学习单子的工作原理?

首先,对我们使用的东西如何工作有一个基本的了解总是好的。如果你是一个Java开发人员,你可能会使用单子,甚至可能不知道它。这可能会让你感到惊讶,但两个最著名的Java 8特性,即溪流可选择的是单子实现。

另外,现在函数式编程越来越流行,所以有可能我们会有更多类似的一元结构。在这种情况下,了解单子是什么以及它是如何工作的可能会变得更有价值。

回到严肃的话题...

什么是单子?

看完简介,你知道单子是范畴理论中的一个概念。在软件世界中,它可以在任何支持泛型的静态类型语言中实现为一个类或特征。此外,我们可以将它视为一个包装器,它将我们的值放在某个上下文中,并允许我们对该值执行操作,特别是返回包装在相同上下文中的值的操作。此外,我们可以以这样一种方式链接操作,即任何一步操作的输出都是下一步操作的输入。

现代编程语言中的单子示例:

  • 流(Java)。
  • 可选/选项(Java/Scala)。
  • 要么(Scala)。
  • 试试(Scala)。
  • IO Monad(哈斯克尔)。

单子定律

说到单子,最后需要提到的是它们的法则。如果我们想把我们的实现看作一个真正的单子,我们必须服从它们。有三条定律:左侧标识正确的身份,结合性。在我看来,理解它们的真正含义有点困难。

现在,在的帮助下可选的,我将试着更详细地解释上述定律。

但首先有几个假设:

  • 从类型T到类型Optional的函数映射
  • 从R型到Optional型的函数映射

左侧标识

如果我们创建一个新的单子并将其绑定到函数,结果应该与将函数应用于值相同。

Optional<String> leftIdentity = Optional.of(x).flatMap(f);
Optional<String> mappedX = f.apply(x);
assert leftIdentity.equals(mappedX);

正确的身份

将一个单元函数绑定到一个单子的结果应该和创建一个新单子的结果一样。

Optional<Integer> rightIdentity = Optional.of(x).flatMap(Optional::of);
Optional<Integer> wrappedX = Optional.of(x);
assert rightIdentity.equals(wrappedX);

结合性

在函数应用链中,函数如何嵌套并不重要。

Optional<Long> leftSide = Optional.of(x).flatMap(f).flatMap(g);
Optional<Long> rightSide = Optional.of(x).flatMap(v -> f.apply(v).flatMap(g));
assert leftSide.equals(rightSide);

单子的创造

现在,当我们知道了基础知识,我们就可以专注于实现了。

我们首先需要一个参数化类型M<T >,它是T类型值的包装器。我们的类型必须实现两个函数:

  • 关于 (单位)用于包装我们的值,并具有以下签名M<T>(T).
  • 平面地图 (约束)负责执行操作。这里,我们传递一个函数,该函数在我们的上下文中对值进行操作,并返回已经包装在上下文中的另一个类型。此方法应该具有以下签名M<U> (T -> M<U >).

为了使它更容易理解,我将使用可选择的再一次展示在这种情况下上面的结构是什么样子。

这里,第一个条件马上得到满足,因为可选择的是一个参数化类型。该单位职能的作用是通过ofNullable关于方法。平面地图扮演的角色约束功能。当然,在的情况下可选择的,类型边界允许我们使用比上面定义中更复杂的类型。

完成了理论,让我们实施

import java.util.function.Function;public final class WrapperMonad<T> {private final T value;private WrapperMonad(T value) {this.value = value;}static <T> WrapperMonad<T> of(T value) {return new WrapperMonad<>(value);}<U> WrapperMonad<U> flatMap(Function<T, WrapperMonad<U>> function) {return function.apply(value);}// For sake of asserting in Exampleboolean valueEquals(T x) {return value.equals(x);}
}

瞧,单子完成了。下面详细描述一下我在这里到底做了什么。

这里到底发生了什么

我们实现的基础是参数化类不可变字段命名为“价值”,负责存储我们的价值。然后,我们有一个私有的构造函数,这使得除了通过我们的包装方法之外,不可能以任何其他方式创建一个对象关于.

接下来,我们有两个基本的单子函数,即关于(相当于单位)和平面地图(相当于约束),这将保证我们的实现以单子定律的形式满足所需的条件。

描述完这些功能后,是时候给出一个使用示例了。这就是了。

import java.util.function.Function;public class Example {public static void main(String[] args) {int x = 2;// Task: performing operation, returning wrapped value, over the value inside the container object.// Non-MonadFunction<Integer, Wrapper<String>> toString = i -> new Wrapper<>(i.toString());Function<String, Wrapper<Integer>> hashCode = str -> new Wrapper<>(str.hashCode());Wrapper<Integer> wrapper = new Wrapper<>(x);Wrapper<String> stringifyWrapper = toString.apply(wrapper.value);// One liner - Wrapper<Integer> hashCodedWrapper = hashCode.apply(toString.apply(x).value);Wrapper<Integer> hashCodedWrapper = hashCode.apply(stringifyWrapper.value);// MonadFunction<Integer, WrapperMonad<String>> toStringM = i -> WrapperMonad.of(i.toString());Function<String, WrapperMonad<Integer>> hashCodeM = str -> WrapperMonad.of(str.hashCode());WrapperMonad<Integer> hashCodedWrapperMonadic = WrapperMonad.of(x).flatMap(toStringM).flatMap(hashCodeM);assert hashCodedWrapperMonadic.valueEquals(hashCodedWrapper.value);System.out.println("Values inside wrappers are equal");}
}

在上面的代码中,除了看到单子如何工作,我们还可以看到使用它们的一些好处。

在一元部分,所有的操作都被合并到一个单独的执行管道中,这使得代码更具声明性,更易于阅读和理解。此外,如果有一天我们决定添加错误处理逻辑,它可以很好地封装在里面关于平面地图方法。

另一方面,在这个例子的非一元部分,我们有一个不同的包私有字段值的设计,我们需要一种从包装器外部访问值的方法,这打破了封装。就目前而言,该代码片段可读性足够好,但是您可能会注意到它不是扩展友好的。添加任何类型的异常处理都可能使它变得非常复杂。

总结

单子是一个非常有用和强大的概念,可能我们很多人在日常工作中都会用到它。我试图对其理论基础及其背后的逻辑提供清晰的描述性解释。我实现了一个定制的monad来表明它不是一个复杂的结构。在上面的例子中,我展示了monad的用法,这种方法的潜在优点,以及它与普通方法调用的不同之处。

关于Monad的常见问题

什么是单子?

单子是一个源于数学范畴理论的概念。

我为什么要关心Monad?

如果你是一名Java开发人员,你可能每天都在使用monad,但是我可以告诉你你有问题。例如,Stream和Optional是monad实现中最容易混淆的对象。此外,函数式编程变得越来越流行,所以我们可能会看到更多这样的结构。

什么是单子定律?

每个单子的实现都必须满足三个法则:左恒等式、右恒等式和结合律。

实现Monad需要什么?

要实现Monad,您需要一个参数化类型M<T >和两个方法unit和bind。

什么是单子?Java开发人员的基本理论相关推荐

  1. 什么是单子?Java 开发人员的基本理论

    monad 是一个源自数学的一部分的概念,称为 范畴论,而不是类或特征.在本文中,我将尝试解释它的结构和内部工作原理.通过使用 Java 中的Optional ,我将尝试以更易于理解的方式描述所有这些 ...

  2. 什么是适用的?Java开发人员的基础理论

    你是一个想了解应用程序背后的理论的Java开发人员吗?在这里你会找到一步一步的教程,帮助你理解它们. Applicative只是另一个在意义和历史上类似于函子和单子.我在以前的文章中已经讨论过这两个问 ...

  3. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序

    面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...

  4. Java开发人员 2019 生态系统信息图

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://www.jetbrains.c ...

  5. Java开发人员最常犯的10个错误,你犯过几个?

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 来源:http://t.cn/EJscOju 阅读目录 Array转ArrayList 判断一个数组是 ...

  6. 还在重复造轮子?Java开发人员必知必会的20种常用类库和API

    介绍 一个有经验的Java开发人员特征之一就是善于使用已有的轮子来造车.<Effective Java>的作者Joshua Bloch曾经说过:"建议使用现有的API来开发,而不 ...

  7. 十大最急需IT技术人才榜:Java开发人员领跑

    据Dice网站最新的调查显示,本月"最急需的十大IT技术"Java开发人员排到首位,紧随其后的是移动应用程序开发人员和NET开发人员.该数据显示,软件开发人员名列第四.不过这是一个 ...

  8. 恒生java开发复试_2019恒生电子面试经验(JAVA开发人员,实施工程师等)

    为了帮助职业圈网友能够及时了解恒生电子的面试流程以及面试过程所涉及的面试问题,职业圈小编把2019最新恒生电子面试经验编辑好,马上提供给大家,以便能够尽快帮助到有需要的人.文章中还为你提供恒生电子面试 ...

  9. 优秀的Java开发人员必备的6个技能

    作为历史最为悠久的编程语言,Java的发展势头一直非常好.而Java从业人员的选择范围也非常多,大致上可以将Java开发人员分为两类,一类是技术人员,一类是管理人员.无论是哪一类,想要成为一名优秀的J ...

  10. Java开发人员在编程中常见的雷!

    身为一名Java从业人员,其职场生涯就是一边踩"坑",一边上升的过程.这个过程中不仅要学会修改无数bug,也要学会越过很多"坑".今天,千锋老师为大家分享一些J ...

最新文章

  1. CCNP路由实验---3、人工汇总EIGRP路由
  2. VC++ 常用编程技巧总结
  3. 《openssl编程》之openssl简介
  4. 交通安全与智能控制专业学计算机吗,交通安全与智能控制专业排名好不好_主要课程及就业前景分析...
  5. 算法专题(1)-信息学基本解题流程!
  6. jest忽略如何添加忽略_大多数人忽略的基本家庭维护任务
  7. python坦克大战_Life is short,you need Python——Python实现坦克大战(一)
  8. JS延迟加载百度分享代码,提高网页速度
  9. jquery easyui datagrid 获取Checked选择行(勾选行)数据
  10. 基于java的enigma的加密程序
  11. 针对豆瓣TOP250电影知识图谱的构建(Python+neo4j)
  12. java毕业设计选题基于SSM毕业设计管理系统|毕设管理文档成绩Shiro
  13. 吴恩达-机器学习-简单决策树
  14. 西门子组态软件wincc短信报警,微信推送
  15. Phython画星空(较复杂)
  16. (android文档原创翻译)管理Activity的生命周期一
  17. 多人共享的待办事项app有哪些
  18. C#的AES加密解密(ECB)
  19. VS Code中常用插件
  20. 计算机无法识别ipad2,iTunes无法识别iPad mini怎么办【解决方法】

热门文章

  1. 小米 红米5A 线刷兼救砖_解账户锁_纯净刷机包_教程
  2. 知乎8.5k赞的回答:自学编程需要注意什么?
  3. 7-2 学生成绩排序 (15 分)
  4. 谈谈对Promise的理解
  5. zblog导航小智收录网导航模板
  6. win10镜像无法再此计算机上运行,Win10镜像无法安装提示“运行此工具时出现问题”的两种解决方案...
  7. linux修改文件:E212 can't open file for writing
  8. 一种插槽式的组件化框架中间件——SCC
  9. 亚信安全发现勒索软件新变种 Word文档成为导火索
  10. 解决Maven报错:Could not transfer artifact xxx