ここで紹介されているHKT
に対して関数を定義したい。
具体的には中身の数値(ここではi32
)を2乗する関数square
を定義したい。
trait HKT<U> {
type T;
type MU;
}
trait Mappable<U>: HKT<U> {
fn map<F: FnOnce(Self::T) -> U>(self, f: F) -> Self::MU;
}
fn square<T>(mappable: T) -> T::MU
where
T: Mappable<i32, T = i32>,
{
mappable.map(|x| x * x)
}
これで完成。Mappable
に対してT=i32
の型パラメータ指定ができることに気づくまでに時間がかかった。
例えばOption
に対して実装するならこうなる。
impl<T, U> HKT<U> for Option<T> {
type T = T;
type MU = Option<U>;
}
impl<T, U> Mappable<U> for Option<T> {
fn map<F: FnOnce(Self::T) -> U>(self, f: F) -> Self::MU {
match self {
Some(v) => Some(f(v)),
None => None,
}
}
}
fn main() {
let a = Some(1i32);
println!("{:?}", square(a));
}