参考
通过use关键字将嵌套的回调函数铺平
type State[S, V] (S) -> (S, V)
fn State::map[S, X, Y](f : (X) -> Y , m : State[S, X]) -> State[S, Y] {
fn res(state : S) -> (S, Y) {
let State(m) = m
let (newstate, value) = m(state)
(newstate, f(value))
}
State(res)
}
fn State::new[S, T](val : T) -> State[S, T] {
fn res(state : S) -> (S, T) {
(state, val)
}
State(res)
}
fn State::bind[S, X, Y](m : State[S, X], f : (X) -> State[S, Y]) -> State[S, Y] {
fn res(state : S) -> (S, Y) {
let State(m) = m
let (newstate, value) = m(state)
let State(m) = f(value)
m(newstate)
}
State(res)
}
fn mkPop[T]() -> State[List[T], T] {
fn pop(stack : List[T]) -> (List[T], T) {
match stack {
Nil => abort("pop(): empty stack")
Cons(elem, rest) => (rest, elem)
}
}
State(pop)
}
fn mkPush[T]() -> (T) -> State[List[T], Unit] {
fn push(elem : T) -> State[List[T], Unit] {
State(fn (stack){(Cons(elem, stack), ())})
}
push
}
fn example() {
let push = mkPush()
let pop = mkPop()
{
State::bind(push(3), fn (__){
State::bind(push(4), fn (__) {
State::bind(pop, fn(four) {
State::new("got \(four)")
})
})
})
}
// 在引入use关键字后可改写为
// {
// use State::bind(push(3))
// use State::bind(push(4))
// use four <- State::bind(pop)
// State::new("got \(four)")
// }
abort("")
}