Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I don’t understand some parts of StateMonad #1

Open
cangSDARM opened this issue Jun 25, 2021 · 2 comments
Open

I don’t understand some parts of StateMonad #1

cangSDARM opened this issue Jun 25, 2021 · 2 comments

Comments

@cangSDARM
Copy link

in fib section:

fn pure(v: A) -> Self // pure: (v) -> State<InState, v>
fn flatMap<F> // F: Fn(A) -> State<InState, B>

fn fib(n: u64) -> State<'static, (u64, u64), u64> {
        match n {
            0 => State::flatMap(
                get(),
                |x: (u64, u64)| { State::pure(x.0) }    /// <--- here, 难道不应该是 |x: u64| { State::pure(x) } 么?
            ),
            _ => State::flatMap(
                modify(|x: (u64, u64)| { (x.1, x.0 + x.1) }),  /// 这里就很明显,说明 value 是 u64, state 是 (u64, u64)
                move |_| fib(n - 1)
         )
    }
}

and later part:

assert_eq!(fib(7).eval((0, 1)), 13);   /// 这里修改为 eval((2, 3)), 它会执行 2...7 的fib么
@fzyzcjy
Copy link
Contributor

fzyzcjy commented Jan 14, 2022

// 这里修改为 eval((2, 3)), 它会执行 2...7 的fib么

I guess no. At least fib(7) means it will include fib(6), fib(5), ... fib(0).

But it may give 9th fib number?

@PhotonQuantum
Copy link
Owner

Sorry for my extremely late reply!

            0 => State::flatMap(
                get(),
                |x: (u64, u64)| { State::pure(x.0) }    /// <--- here, 难道不应该是 |x: u64| { State::pure(x) } 么?
            ),

Let's look at the implementation of get.

pub fn get<'a, S: Clone>() -> State<'a, S, S> {
    State { run_state: Box::new(|state: S| (state.clone(), state)) }
}

The idea of get is to copy the state to the output field, so we may work on it or just return it (or say, pure it, if you like). As the state is of type (int, int), the output field is of the same type now. So, when we flatMap on it, we are coping with a (int, int) input.

assert_eq!(fib(7).eval((0, 1)), 13);   /// 这里修改为 eval((2, 3)), 它会执行 2...7 的fib么

The fib sequence starts with 0, 1. If you change the initial state to 2, 3, you have a sequence like 2, 3, 5, 8, 13, 21, 34, 55, ... . So you get the 8th num in this sequence, which is 55, although you may say that it's the 11th fib number as well.

Note: the fib seq here starts from 0 and 1, and fib(n) means the (n+1)-th fib number because we index from 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants