首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

深入解析 Monad(6)Reader Monad

深入解析 Monad(6)Reader Monad

Reader MonadReader Monad 也被称为 Environment Monad,描述的是依赖共享环境的计算。Reader Monad 的类型构造器从类型 T 中创建出一元类型 E → T,而        E 是环境的类型。类型构造器把类型 T 转换成一个从类型 E 到 T 的函数。Reader Monad 的 unit 操作把类型 T 的值 t 转换成一个永远返回 t        的函数,而忽略类型为 E 的参数;bind 操作在转换时,在所返回的函数的函数体中对类型 T 的值 t 进行转换,同时保持函数的结构不变。
清单 8 是 Reader Monad 的示例。Function<E,        T> 是一元类型的声明。ReaderMonad 的 unit 方法返回的 Function 只是简单的返回参数值 value。而 bind 方法的第一个参数是一元类型        Function<E, T1>,第二个参数是把类型 T1 转换成 Function<E, T2> 的函数,返回值是另外一个一元类型 Function<E,        T2>。bind 方法的转换逻辑首先通过 input.apply(e) 来得到类型为 T1 的值,再使用 transform.apply 来得到类型为 Function<E,        T2>> 的值,最后使用 apply(e) 来得到类型为 T2 的值。
清单 8. Reader Monad        示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ReaderMonad {

  public static <T, E> Function<E, T> unit(T value) {
    return e -> value;
  }

  public static <T1, T2, E> Function<E, T2> bind(Function<E, T1>
input, Function<T1, Function<E, T2>> transform) {
    return e -> transform.apply(input.apply(e)).apply(e);
  }

  public static void main(String[] args) {
    Function<Environment, String> m1 = unit("Hello");
    Function<Environment, String> m2 = bind(m1, value -> e ->
e.getPrefix() + value);
    Function<Environment, Integer> m3 = bind(m2, value -> e ->
e.getBase() + value.length());
    int result = m3.apply(new Environment());
    System.out.println(result);
  }
}




清单 8 中使用的环境类型 Environment 如清单        9 所示,其中有两个方法 getPrefix 和 getBase 分别返回相应的值。清单 8 的 m1 是值为        Hello 的单元类型,m2 使用了 Environment 的 getPrefix 方法进行转换,而 m3 使用了 getBase 方法进行转换,最终输出的结果是 107。因为字符串        Hello 在添加了前缀 $$ 之后的长度是 7,与 100 相加之后的值是 107。
清单 9.        环境类型
1
2
3
4
5
6
7
8
9
10
public class Environment {

  public String getPrefix() {
    return "$$";
  }

  public int getBase() {
    return 100;
  }
}

返回列表