深入解析 Monad(6)Reader Monad
- UID
- 1066743
|
深入解析 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;
}
}
|
|
|
|
|
|
|