Polymorphi c закрытия в Русте - PullRequest
       22

Polymorphi c закрытия в Русте

2 голосов
/ 19 января 2020

Я начинаю изучать Rust (заранее извиняюсь) и пытаюсь реализовать библиотеку monadi c parin combinator. Синтаксические анализаторы реализуют черту Parser следующим образом:

// parse success is a value + the rest of input
type ParseResult<'a, T> = Option<(T, &'a str)>;

trait Parser<A> {
    fn parse<'a>(&self, input: &'a str) -> ParseResult<'a, A>;
}

То есть: метод parse - это life-polymorphi c. Эта черта может быть реализована для функций / замыканий полиморфизма c времени жизни с использованием границ признака более высокого ранга следующим образом:

// parser impl for functions
impl<F, A> Parser<A> for F
where
    for<'a> F: Fn(&'a str) -> ParseResult<'a, A>,
{
    fn parse<'a>(&self, input: &'a str) -> ParseResult<'a, A> {
        self(input)
    }
}

Моя проблема заключается в том, что замыкания автоматически не удовлетворяют признаку Parser. Вместо этого, кажется, что средство проверки типов нуждается в некоторой помощи от программиста:

// higher-rank helper
fn cast<A, F>(func: F) -> impl Parser<A>
where
    F: for<'a> Fn(&'a str) -> ParseResult<'a, A>,
{
    func
}

// applicative pure parser
fn pure<A: Copy>(a: A) -> impl Parser<A> {
    // doesn't work without explicit cast
    cast(move |input| Some((a, input)))
}

Без явного преобразования ошибка:

error[E0271]: type mismatch resolving `for<'a> <[closure@src/lib.rs:29:5: 29:34 a:_] as std::ops::FnOnce<(&'a str,)>>::Output == std::option::Option<(A, &'a str)>`
  --> src/lib.rs:27:27
   |
27 | fn pure<A: Copy>(a: A) -> impl Parser<A> {
   |                           ^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
   |
   = note: required because of the requirements on the impl of `Parser<A>` for `[closure@src/lib.rs:29:5: 29:34 a:_]`
   = note: the return type of a function must have a statically known size

У меня следующие вопросы:

  • Это нормальное поведение? (т.е. тот факт, что тип замыкания остается мономорфным при жизни c при проверке черты Parser без явного приведения)
  • Существует ли лучший / более идиоматический c способ заставить замыкания удовлетворять Parser черта?
  • Или этот подход совершенно неправильный и какой будет ржавый путь?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...