8

Rustにはアフィン論理のセマンティクスがあると言われました-つまり、削除/弱体化はありますが、重複/縮小はありません。

以下がコンパイルされます。

fn throw_away<A, B>(x: A, _y: B) -> A {
    x
}

複製が許可されていないため、次のコードはコンパイルされません。

fn dup<A>(x: A) -> (A, A) {
    (x, x)
}

同様に、これらはどちらもコンパイルされません。

fn throw_away3<A, B>(x: A, f: fn(A) -> B) -> A {
    x;
    f(x)
}

fn throw_away4<A, B>(x: A, f: fn(A) -> B) -> A {
    throw_away(x, f(x))
}

弱体化も目立ちます

fn weaken<A, B, C>(f: fn(A) -> B) -> impl Fn(A, C) -> B {
    move |x: A, y: C| f(x)
}

返す代わりにfn(A, C) -> B、返しimpl Fn(A, C) -> Bました。fn(A, C) -> B代わりに戻る方法はありますか?そうでなくても構いません。私はただ興味があります。

私が期待する他の何かは、あなたが持ち上げることができるということAです() -> A。ただし、Rust の関数は複製して複数回使用することができます。例えば、

fn app_twice(f: fn(A) -> A, x: A) -> A {
    f(f(x))
}

実際に function があったと仮定するとlift(x: A) -> fn() -> A、移動のセマンティクスを壊すことができます。たとえば、これにより、

fn dup_allowed(x: A) -> (A, A) {
    let h = lift(x);
    (h(), h())
}

したがって、 に持ち上げるAfn() -> Aは、関数が「線形/アフィン」であるか、一度しか使用できないことを知る必要があります。Rust はこれにタイプを提供します: FnOnce() -> A. 以下では、最初はコンパイルされ、2 番目はコンパイルされません。

fn app_once(f: impl FnOnce(A) -> A, x: A) -> A {
    f(x)
}

fn app_twice2(f: impl FnOnce(A) -> A, x: A) -> A {
    f(f(x))
}

次の関数は互いに逆関数です (おそらく、Rust のセマンティクスについては、実際に互いに逆関数であると言えるほどよく知りません)。

fn lift_up<A>(x: A) -> impl FnOnce() -> A {
    move || x
}

fn lift_up_r<A>(f: impl FnOnce() -> A) -> A {
    f()
}

fn dup<A>(x: A) -> (A, A) { (x,x) }はコンパイルされないため、次のことが問題になるのではないかと考えました。

fn dup<A>(x: fn() -> A) -> (A, A) {
    (x(), x())
}

Rust は型に対して何か特別なことをしているようですfn(A) -> B

上記で x が再利用可能/複製可能であることを宣言する必要がないのはなぜですか?

おそらく、何か違うことが起こっているのでしょう。宣言された関数は少し特別fn f(x: A) -> B { ... }ですA -> B. したがって、f複数回使用する必要がある場合は、必要に応じて何度でも再証明できますfn(A) -> Bが、まったく別のものです。それは構築されたものではなく、仮説的なものであり、fn(A) -> Bs が複製可能であることを使用する必要があります。実際、私はそれが自由に複製可能なエンティティのようなものだと考えてきました. ここに私の大まかな例えがあります:

  • fn my_fun<A,B>(x :A) -> B { M } "は" x:A |- M:B
  • fn(A) -> B"is" !(A -o B) したがって自由に複製可能
  • したがって、fn() -> A"is" !(() -o A) = !A したがってfn () -> A、 A 上の (co)free 重複
  • fn dup_arg<A: Copy>(x: A) -> B { M }A が重複しているか、コモノイドであると「言う」
  • impl FnOnce (A) -> B「は」A -o B

しかし、これは正しいはずがありません... とは何impl Fn(A) -> Bですか? ちょっといじってみると、fn(A) -> Bよりも厳しいようですFn(A) -> B。私は何が欠けていますか?

4

1 に答える 1