如何创建State Monad来表示胶子中的可变状态?

时间:2019-01-29 23:34:47

标签: rust rust-gluon

我对在我的Rust应用程序中使用gluon作为脚本语言感兴趣。但是,该应用程序使用了一些相当大的结构,这些结构最好与可变对象一起使用,而不是复制和变异。

由于gluon是一种纯粹的函数式语言,因此我认为执行此操作的正确方法是创建相应的Monad类并向其中添加函数。从头开始构建它似乎需要大量的工作,而且我什至不确定现有的从函数运行脚本的方法是否会支持这一点。我想知道这是否是正确的道路,是否有简化实施的方法-但我似乎找不到任何此类使用的小型示例。

作为简化示例,请考虑应用程序状态,它基本上是一个映射,仅具有两个功能。

struct ApplicationState { /* ... */ }

impl ApplicationState {
    fn get(k: &str) -> Option<String> { /* ... */ }
    fn set(k: &str, v: &str) { /* ... */ }
}

我希望它具有类似配置胶子代码

get: String -> ApplicationState Option String
set: String -> String -> ApplicationState ()

let main : ApplicationStateAction () = do
    let v = get("a")
    match v with 
        | Some w -> 
            set "b" v
        | None -> 
            set "c" "something"

最后,Rust实际运行起来就像

fn set_config(state: &mut ApplicationState, script: &str) -> Result<(), Box<std::error::Error>> {
    let vm = gluon::new_vm();
    // TODO: Configure the VM to know about the
    //       ApplicationStateAction Monad and it's
    //       set and get functions.
    let mut source = String::new();
    ();

    let mut source = String::new();
    let mut file = File::open(str)?;
    file.read_to_string(&mut source)?;

    // TODO: How do we define ApplicationStateAction in rust?
    let (f, _) = gluon::Compiler::new()
        .run_expr::<ApplicationStateAction>(&vm, "f", &source)
        .unwrap();

    // TODO: How do we apply the ApplicationStateAction to the ApplicationState?
}

我意识到我可以通过使用IO monad进行排序来实现大部分功能,然后可以使用run_io中的gluon::Compiler功能。但是,IO Monad为脚本提供了太多功能-我确实想将脚本限制为仅列入白名单的功能。

0 个答案:

没有答案