pub fn compile_monad_flat_map(load_monad: CompiledActions, args: CellRef) -> Result<CompiledActions, BindError> {
    // Start by pushing the monad onto the stack
    let mut actions = load_monad;
    actions.push(Action::Push);

    // Next push the closure arguments onto the stack. The first value in args should be a list of bindings
    let ListTuple((values, closure)): ListTuple<(CellRef, CellRef)> = args.try_into()?;

    let mut pos = &values;
    while let SafasCell::List(car, cdr) = &**pos {
        // Compile this value
        actions.extend(compile_statement_quick(car.clone())?);

        // Push onto the stack
        actions.push(Action::Push);

        // Move to the next value in the list
        pos = cdr;
    }

    // Generate the closure body by evaluating it
    actions.push(Action::Value(closure));
    actions.push(Action::Call);

    // Call FlatMap to resolve the monad
    actions.push(Action::FlatMap);

    Ok(actions)
}
///
/// Compiles a monad flat_map expression
/// 
/// load_monad specifies the actions required to load the monad into the current value
/// 
/// args specifies the arguments of the monad. There are two of these: the bindings to compile and push on to the stack,
/// and the closure to resolve with these bindings.
///
Compiles a monad flat_map expression
load_monad specifies the actions required to load the monad into the current value

args specifies the arguments of the monad. There are two of these: the bindings to compile and push on to the stack,
and the closure to resolve with these bindings.
Compiles a monad flat_map expression load_monad specifies the actions required to load the monad into the current value args specifies the arguments of the monad . There are two of these : the bindings to compile and push on to the stack and the closure to resolve with these bindings .
pub fn compile_monad_flat_map(load_monad: CompiledActions, args: CellRef) -> Result<CompiledActions, BindError> {
    // Start by pushing the monad onto the stack
    let mut actions = load_monad;
    actions.push(Action::Push);
    // Next push the closure arguments onto the stack. The first value in args should be a list of bindings
    let ListTuple((values, closure)): ListTuple<(CellRef, CellRef)> = args.try_into()?;
    let mut pos = &values;
    while let SafasCell::List(car, cdr) = &**pos {
        // Compile this value
        actions.extend(compile_statement_quick(car.clone())?);
        // Push onto the stack
        actions.push(Action::Push);
        // Move to the next value in the list
        pos = cdr;
    }
    // Generate the closure body by evaluating it
    actions.push(Action::Value(closure));
    actions.push(Action::Call);
    // Call FlatMap to resolve the monad
    actions.push(Action::FlatMap);
    Ok(actions)
}
pub fn compile_monad_flat_map ( load_monad : CompiledActions , args : CellRef ) -> Result < CompiledActions , BindError > { // Start by pushing the monad onto the stack let mut actions = load_monad ; actions . push ( Action :: Push ) ; // Next push the closure arguments onto the stack. The first value in args should be a list of bindings let ListTuple ( ( values , closure ) ) : ListTuple < ( CellRef , CellRef ) > = args . try_into ( ) ? ; let mut pos = & values ; while let SafasCell :: List ( car , cdr ) = & * * pos { // Compile this value actions . extend ( compile_statement_quick ( car . clone ( ) ) ? ) ; // Push onto the stack actions . push ( Action :: Push ) ; // Move to the next value in the list pos = cdr ; } // Generate the closure body by evaluating it actions . push ( Action :: Value ( closure ) ) ; actions . push ( Action :: Call ) ; // Call FlatMap to resolve the monad actions . push ( Action :: FlatMap ) ; Ok ( actions ) }
Compiles a monad flat_map expression
load_monad specifies the actions required to load the monad into the current value
Compiles a monad flat_map expression load_monad specifies the actions required to load the monad into the current value
load_monad
CompiledActions
args
CellRef
load_monad
CompiledActions
args
CellRef