简体   繁体   English

是否有内在原因解释为什么 Rust 没有更高种类的类型?

[英]Is there an intrinsic reason explaining why Rust does not have higher-kinded-types?

Rust does not have higher-kinded-types. Rust 没有更高种类的类型。 For example, functor (and thus monad) cannot be written in Rust.例如,仿函数(因此也就是 monad)不能写在 Rust 中。 I would like to know if there is a deep reason explaining this and why.我想知道是否有深层原因解释这一点以及原因。

For instance, reason that I can understand can be that there is no zero-cost abstraction making HKT possible.例如,我能理解的原因可能是没有零成本的抽象使 HKT 成为可能。 Or type inference is significantly more difficult.或者类型推断要困难得多。 And of course, I also looking for an explaination showing me why this is a real limitation.当然,我也在寻找一个解释,告诉我为什么这是一个真正的限制。

If the anwer was already given somewhere else, could you give me the link?如果答案已经在其他地方给出,你能给我链接吗?

Time & Priority .时间和优先级

The absence of Higher Kinded Types is not a design decision, per se.没有更高种类的类型本身并不是设计决定。 It is intended that Rust will have some form of it, with the more popular candidate being Generic Associated Types (2017) at the moment. Rust 将具有某种形式,目前更受欢迎的候选者是通用关联类型 (2017)

Implementing those take time, though, and has not been judged a priority compared to other features.但是,实施这些需要时间,并且与其他功能相比,并没有被认为是优先级。 For example, async/await was prioritized over HKTs, and const generics also seem to be prioritized.例如,async/await 优先于 HKT,而 const generics 似乎也优先。


For example, functor (and thus monad) cannot be written in Rust.例如,仿函数(因此也就是 monad)不能写在 Rust 中。

Actually, they can, although it's a bit unwieldy.实际上,它们可以,尽管它有点笨拙。

See Edmund's Smith lovely hack which he posted on https://www.reddit.com/r/rust/comments/cajn09/new_method_for_emulating_higherkinded_types_in/ :请参阅 Edmund 在https://www.reddit.com/r/rust/comments/cajn09/new_method_for_emulating_higherkinded_types_in/上发布的 Smith 可爱的 hack

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 }
    }
}

With which they implement a Functor trait:他们用它实现了一个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())
    }
}

And from then on build Applicative and Monad :从那时起构建ApplicativeMonad

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
        ;
}

I did say it was a bit unwieldy...我确实说它有点笨拙...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM