Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

リテラルを篩型に暗黙昇格する機能 #151

Open
KisaragiEffective opened this issue May 26, 2023 · 0 comments
Open

リテラルを篩型に暗黙昇格する機能 #151

KisaragiEffective opened this issue May 26, 2023 · 0 comments
Labels

Comments

@KisaragiEffective
Copy link
Owner

KisaragiEffective commented May 26, 2023

blocked by #160

気持ちとしては次のような表記が通ってほしいわけであるが、今日のRust (※少なくとも、1.69.0) ではコンパイルが通らない:

use core::num::NonZeroU32;

fn non_zero(nzu32: NonZeroU32) {}

fn main() {
    non_zero(1);
    //       ^ mismatched types
}

そこで、次のようなルールで型Xを持つリテラルxのみを型Tに暗黙昇格する機能をつけたい。こうすることで双方にとってほぼノーコストかつよりtype-safeなプログラムが実現可能である。

  1. Tは正確にフィールドを一つのみ持たなければならない (注: この制約は過剰である)。このフィールドの型をXとする。
  2. Tは、構築するにあたってXに対して追加で構成時の要件を持つ必要がある。
  3. Tは、XからResult<T, ?>への非メンバー関数を持つ必要がある。
  4. プログラマは3の要件を満たす関数をコンパイラにコンパイラ依存の方法で教える必要がある。
  5. もし型Xが型Tの制約を満たしていることを検査せずにそのまま「通す」"unchecked"な関数を持っていて (もちろん、これは安全ではないのでそのように印がつけられる必要がある)、かつコンパイル時にxTの要件を満たしていることが100%確実であれば、xはそのような"unchecked"な関数を使ってTへと変換される; これを正しく実装するのはコンパイラの責任である。
  6. xが渡された先がジェネリックサイト、または述語に対して全体量化されたサイトではない。この条件は事実上必要な要件であり、この条件を取り除くと次のようなコードでどの型へ昇格されるのかが不明瞭になる:
    // Scala 2 / Scala 3
    import eu.timepit.refined.api.Refined
    def forallPredicate[V, P](site: V Refined P) = ???
    
    def generic[V](site: V) = ???
    
    generic(1) // Int Refined ???
    forallPredicate(1) // Int Refined ???

もし今日のRustがこのようなシステムを持っていたとして、上述のNonZeroU32の例で言い換えると、以下のとおりになる。

  1. NonZeroU32u32のみをフィールドとして持つ。
  2. NonZeroU32は「ゼロではないu32を格納する」という追加の要件を持つ。
  3. NonZeroU32TryFrom<u32>の実装を持つ。
  4. TryFromの実装で既知である。
  5. NonZeroU32::new_uncheckedがそれに当てはまる。
  6. 自明
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant