Как создать Haskell-подобные функциональные зависимости

Фон: я использую библиотеку nalgebra, и я хочу создать структуру, представляющую многомерное нормальное распределение. Число и тип строки однозначно определяются квадратным матричным типом, поэтому я хочу написать что-то вроде этого:

#[allow(non_snake_case)]
pub struct Multivar𝒩<M: SquareMat<N, V>> {
    μ: V,
    Σ: M,
}

Если бы я использовал Haskell, я бы указал функциональную зависимость между M и N и V. Какой лучший способ сделать это в Rust?

Ответ 1

В то время как у Haskell есть две вещи, чтобы выразить такую ​​взаимосвязь между типами, фондами и связанными с ними типами, Rust имеет только последние. Черты в Rust могут содержать члены типа, которые назначаются конкретными значениями на сайте реализации, и компилятор считает их однозначно идентифицированными комбинацией параметров типа признака (включая Self). Поэтому вам нужно определить черту SquareMat следующим образом:

trait SquareMat {
    type N;
    type V;
    ...
}

impl SquareMat for SomeStruct {
    type N = Four;
    type V = f64;
    ...
}

И тогда этот признак можно использовать следующим образом:

#[allow(non_snake_case)]
pub struct Multivar𝒩<M: SquareMat> {
    μ: M::V,
    Σ: M,
}

Если вы не управляете SquareMat, ну, тогда вам не повезло - вы не можете определить функциональную зависимость на сайте использования признаков, только на сайте объявления признаков, как в Haskell.