Как мне создать Государственную Монаду, чтобы представлять изменяемое состояние в глюоне? - PullRequest
0 голосов
/ 30 января 2019

Я заинтересован в использовании глюона в качестве языка сценариев в моем приложении Rust.Тем не менее, приложение использует некоторые довольно большие структуры, с которыми лучше работать как изменяемые объекты, а не копировать и изменять их.

Поскольку глюон является чисто функциональным языком, я предполагаю, что правильный способ сделать это - создать соответствующий класс 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?
}

Я понимаю, что, вероятно, смогу пройти большую часть пути, используя монаду ввода-вывода для своего секвенирования, и тогда я смогу использовать функциональность run_io из gluon::Compiler.Тем не менее, IO Monad предоставляет слишком много функциональности для сценариев - я действительно хочу ограничить сценарии только несколькими белыми функциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...