面试亮点--聊聊函数式的monad

函数式编程就是用函数写程序,当然这是一句废话。我相信大家都知道什么是用函数写程序。但是大家可能不知道如何通过函数去构造复杂的、大型的、可扩展的、可测试,复用率高,安全性强的、有数学证明的程序。

面向对象编程以现实世界为原型去投影程序的世界,适合对事务进行抽象、组织、分解;函数式编程则研究的是如何更好的进行计算。

计算是计算机最重要的能力。让计算没有副作用、让计算可以并行、让计算可以被数学证明、让计算更安全、让计算最大程度被复用,这些都是函数式编程的目标。

因此作为一个出色的Java工程师,是有必要学习一下函数式编程的。

关联面试题:

  1. Optional的作用?
  2. FunctionalInterface在做什么?
  3. 说说你理解的函数式编程?
  4. 解释下什么是Monad?
  5. 如何实现管道和流?

流计算的类型设计?

请你先看一下这个例子。一开始,我们构造了一个Optional的类型。

 @Test
public void test_optional(){
   
    var result = Optional.of(100)
        .map(x -> x*x)
        .map(x -> x / 100);

}

我们用map进行映射,求了平方,好除以100。请你仔细观察类型的变化,看看有没有什么发现。
在这里插入图片描述
上图中是类型的变化,数据源的类型是Optional。中间map函数运算时,进行了拆箱,实际操作的类型是整数到整数的函数。最终的结果,依然是Optional。

那么家来请你思考两个问题:

  1. 为什么中间的运算不用Optional类型?
  2. 为什么两端的数据用Optional类型?

道理其实很简单。在我们进行流计算的这个过程当中,我们期望的是类型的统一、以及类型的安全。Optional类型支持空值,准确说,是empty/undefined类型,因此使用起来更加安全。

空值和空值进行操作,没有抛异常,而是继续返回空值。这让我们无论得到什么值,计算都可以继续。

if(!optionalValue.isPresent()) {
   
  return Optional.empty();
}
// 计算逻辑

这样的写法不可取。这样会产生大量的判断,这样的写法应该被封装起来。只有这样才能最大程度的减少程序员的心智负担。

看下下面的例子:

@Test
public void test_udef(){
   
    Optional<Integer> x= Optional.empty();
    var y = x.map(a -> a * a);
    System.out.println(y);
}

在上面的程序当中map内部实现了逻辑,对于empty的值,并不会进入计算逻辑,而是直接以empty的值返回,这样大大节省了用户进行判断的时间。

流计算之所以要设计这些中间的类型,是为了封装错误、避免问题、组织一致性的计算过程、以及惰性的求值过程……

Monad

上面我们描述的流计算的类型设计,实际上就是Monad模式。Monad有非常多的定义。比如说,数学上的。我们先给一个最简单的定义,是从设计模式上去思考。

  • 一个Monad设计模式有3个显著的特点:
  • 一个泛型的构造函数。比如: Optional

不改变泛型类型的运算操作,内部是非泛型计算:例如:Optional map(T -> R)
泛型类型不变。 比如可以是Optional到Optional,但还是Optional类型。
你可能会说,这样的设计究竟有什么用?这个设计其实非常有价值。比如说你可以思考一下Stream的设计。

@Test
public void test_stream(){
   
    var result = Stream.of("Hello", "World")
        .map(x -> x.length());
}

泛型类型不变是构造流计算的基石。Stream 是一类事物,这一类事物无论作用在怎样的操作上,最终结果还是Stream。这样map、filter、reduce等操作就能作用在任何类型的流上。

也是Monad的值。Moand设计模式中,除了要设计bind方法,还需要构造函数(或工厂方法)。这个构造函数用于构造Monad类型,比如Stream.of等等。

实战场景

管道和流计算是需要Monad的一个非常重要的场景。在我们实现业务逻辑的时候,抽象到非常领域化的逻辑也可以使用Monad。尽管通常这样的设计模式我们会被称之为连贯操作。但是设计的好的连贯操作。应该是Monad,因为Monad的拥有数学的证明,严密可靠。

比如:

SearchResult<Order> result = Search.
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值