簡體   English   中英

是否有內在原因解釋為什么 Rust 沒有更高種類的類型?

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

Rust 沒有更高種類的類型。 例如,仿函數(因此也就是 monad)不能寫在 Rust 中。 我想知道是否有深層原因解釋這一點以及原因。

例如,我能理解的原因可能是沒有零成本的抽象使 HKT 成為可能。 或者類型推斷要困難得多。 當然,我也在尋找一個解釋,告訴我為什么這是一個真正的限制。

如果答案已經在其他地方給出,你能給我鏈接嗎?

時間和優先級

沒有更高種類的類型本身並不是設計決定。 Rust 將具有某種形式,目前更受歡迎的候選者是通用關聯類型 (2017)

但是,實施這些需要時間,並且與其他功能相比,並沒有被認為是優先級。 例如,async/await 優先於 HKT,而 const generics 似乎也優先。


例如,仿函數(因此也就是 monad)不能寫在 Rust 中。

實際上,它們可以,盡管它有點笨拙。

請參閱 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 }
    }
}

他們用它實現了一個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())
    }
}

從那時起構建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
        ;
}

我確實說它有點笨拙...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM