是否有内在原因可以解释为什么 Rust 没有更高种类的类型?
Is there an intrinsic reason explaining why Rust does not have higher-kinded-types?
Rust 没有更高级的类型。例如,函子(以及 monad)不能用 Rust 编写。我想知道是否有深层原因解释这一点以及为什么。
例如,我能理解的原因可能是没有零成本抽象使HKT成为可能。或者类型推断要困难得多。当然,我也在寻找解释说明为什么这是一个真正的限制。
如果其他地方已经给出了答案,你能给我link吗?
时间和优先级。
从本质上讲,缺少高等类型并不是设计决定。 Rust 打算有它的某种形式,目前更受欢迎的候选者是 Generic Associated Types (2017)。
虽然实施这些需要时间,但与其他功能相比,还没有被认为是优先事项。例如,async/await 优先于 HKT,const 泛型似乎也优先。
For example, functor (and thus monad) cannot be written in Rust.
实际上,他们可以,尽管它有点笨重。
参见Edmund's Smith lovely hack which he posted on 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
;
}
我确实说它有点笨重...
Rust 没有更高级的类型。例如,函子(以及 monad)不能用 Rust 编写。我想知道是否有深层原因解释这一点以及为什么。
例如,我能理解的原因可能是没有零成本抽象使HKT成为可能。或者类型推断要困难得多。当然,我也在寻找解释说明为什么这是一个真正的限制。
如果其他地方已经给出了答案,你能给我link吗?
时间和优先级。
从本质上讲,缺少高等类型并不是设计决定。 Rust 打算有它的某种形式,目前更受欢迎的候选者是 Generic Associated Types (2017)。
虽然实施这些需要时间,但与其他功能相比,还没有被认为是优先事项。例如,async/await 优先于 HKT,const 泛型似乎也优先。
For example, functor (and thus monad) cannot be written in Rust.
实际上,他们可以,尽管它有点笨重。
参见Edmund's Smith lovely hack which he posted on 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
;
}
我确实说它有点笨重...