Я начинаю изучать 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
черта? - Или этот подход совершенно неправильный и какой будет ржавый путь?