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

深入解析 Monad(7)State Monad

深入解析 Monad(7)State Monad

State        MonadState Monad 可以在计算中附加任意类型的状态值。State Monad 与 Reader Monad 相似,只是 State Monad        在转换时会返回一个新的状态对象,从而可以描述可变的环境。State Monad 的类型构造器从类型 T 中创建一个函数类型,该函数类型的参数是状态对象的类型 S,而返回值包含类型 S        和 T 的值。State Monad 的 unit 操作返回的函数只是简单地返回输入的类型 S 的值;bind 操作所返回的函数类型负责在执行时传递正确的状态对象。
清单 10 给出了 State Monad 的示例。State Monad 使用元组 Tuple2<T,        S> 来保存计算值和状态对象,所对应的一元类型是 Function<S, Tuple2<T, S>> 表示的函数。unit        方法所返回的函数只是简单地返回输入状态对象。bind 方法的转换逻辑使用 input.apply(s) 得到 T1 和 S 的值,再用得到的 S 值调用 transform。
清单 10. State Monad        示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class StateMonad {

  public static <T, S> Function<S, Tuple2<T, S>> unit(T value) {
    return s -> Tuple.of(value, s);
  }

  public static <T1, T2, S> Function<S, Tuple2<T2, S>>
bind(Function<S, Tuple2<T1, S>> input,
      Function<T1, Function<S, Tuple2<T2, S>>> transform) {
    return s -> {
      Tuple2<T1, S> result = input.apply(s);
      return transform.apply(result._1).apply(result._2);
    };
  }

  public static void main(String[] args) {
    Function<String, Function<String, Function<State, Tuple2<String,
State>>>> transform =
        prefix -> value -> s -> Tuple
            .of(prefix + value, new State(s.getValue() +
value.length()));

    Function<State, Tuple2<String, State>> m1 = unit("Hello");
    Function<State, Tuple2<String, State>> m2 = bind(m1,
transform.apply("1"));
    Function<State, Tuple2<String, State>> m3 = bind(m2,
transform.apply("2"));
    Tuple2<String, State> result = m3.apply(new State(0));
    System.out.println(result);
  }
}




State Monad 中使用的状态对象如清单 11 所示。State 是一个包含值 value 的不可变对象。清单 10 中的 m1 封装了值 Hello。transform 方法用来从输入的字符串前缀 prefix        中创建转换函数。转换函数会在字符串值上添加给定的前缀,同时会把字符串的长度进行累加。转换函数每次都返回一个新的 State 对象。转换之后的结果中字符串的值是 21Hello,而        State 对象中的 value 为 11,是字符串 Hello 和 1Hello 的长度相加的结果。
清单 11.        状态对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class State {

  private final int value;

  public State(final int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }

  @Override
  public String toString() {
    return "State{" +
        "value=" + value +
        '}';
  }
}

返回列表