Есть ли внутренняя причина, объясняющая, почему у Rust нет типов с более высоким родом? - PullRequest
4 голосов
/ 25 сентября 2019

Ржавчина не имеет типов с более высоким родом.Например, функтор (и, следовательно, монада) не может быть написан на Rust.Я хотел бы знать, есть ли глубокая причина, объясняющая это и почему.

Например, причина, которую я могу понять, может заключаться в том, что нет абстракции с нулевой стоимостью, делающей возможным HKT.Или вывод типа значительно сложнее.И, конечно же, я также ищу объяснение, показывающее мне, почему это реальное ограничение.

Если ответ уже был дан где-то еще, не могли бы вы дать мне ссылку?

1 Ответ

9 голосов
/ 25 сентября 2019

Время и приоритет .

Отсутствие высших типовых типов само по себе не является дизайнерским решением.Предполагается, что у Rust будет какая-то форма, более популярным из которых является Generic Associated Types (2017) на данный момент.

Реализация этих задач требует времени, и не имеетбыл оценен в качестве приоритета по сравнению с другими функциями.Например, async / await имеет приоритет над HKT, а константные дженерики также имеют приоритет.


Например, функтор (и, следовательно, монада) не может быть записан в 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
        ;
}

Я сказал, что это было немного громоздко ...

...