Время и приоритет.
Отсутствие типов высшего порядка само по себе не является дизайнерским решением. Предполагается, что в Rust будет такая форма, причем наиболее популярным кандидатом будут Generic Associated Types. (2017) на данный момент.
Однако их реализация требует времени и не считается приоритетной по сравнению с другими функциями. Например, async/await имеет приоритет над HKT, и дженерики const также имеют приоритет.
Например, функтор (и, следовательно, монада) не может быть написан на Rust.
На самом деле они могут, хотя это немного громоздко.
См. отличный лайфхак Эдмунда Смита, который он разместил на https://www.reddit..com/r/rust/comments/cajn09/new_method_for_emulating_higherkinded_types_in/:
trait Unplug {
type F; //The representation type of the higher-kinded type
type A; //The parameter type
}
trait Plug<A> {
type result_t;
}
pub struct Concrete<M: Unplug + Plug<A>,A> {
pub unwrap: <M as Plug<A>>::result_t
}
impl<M: Unplug + Plug<A>, A> Concrete<M,A> {
fn of<MA: Unplug<F=M, A=A> + Plug<A>>(x: MA) -> Self
where M: Plug<A, result_t = MA>
{
Concrete { unwrap: x }
}
}
С помощью которого они реализуют трейт Functor
:
pub trait Functor: Unplug + Plug<<Self as Unplug>::A> {
fn map<B, F>(f: F, s: Self) -> <Self as Plug<B>>::result_t
where
Self: Plug<B>,
F: FnMut(<Self as Unplug>::A) -> B
;
}
// Example impl for a represented Vec
impl<A> Functor for Concrete<Vec<forall_t>, A> {
// remember, Self ~ (Vec<_>, A) ~ "f a"
fn map<B, F>(f: F, s: Self) -> <Self as Plug<B>>::result_t
where
F: FnMut(<Self as Unplug>::A) -> B
{
Concrete::of(s.unwrap.into_iter().map(f).collect())
}
}
И с этого момента сборки Applicative
и Monad
:
pub trait Applicative: Functor {
fn pure(s: <Self as Unplug>::A) -> Self;
fn app<B, F>(
f: <Self as Plug<F>>::result_t, //M<F>
s: Self //M<A>
) -> <Self as Plug<B>>::result_t //M<B>
where
F: FnMut(<Self as Unplug>::A) -> B + Clone,
Self: Plug<F> + Plug<B> + Unplug,
<Self as Plug<F>>::result_t:
Unplug<F=<Self as Unplug>::F, A=F> +
Plug<F> +
Clone,
<Self as Unplug>::F: Plug<F>
;
}
pub trait Monad : Applicative {
fn bind<F,B>(f: F, s: Self) -> <Self as Plug<B>>::result_t
where
Self: Plug<F>+Plug<B>,
F: FnMut(<Self as Unplug>::A) ->
<Self as Plug<B>>::result_t + Clone
;
}
Я сказал, что это немного громоздко...
person
Matthieu M.
schedule
25.09.2019