All checks were successful
Build / build (push) Successful in 9m31s
89 lines
2.2 KiB
Markdown
89 lines
2.2 KiB
Markdown
|
||
[[型推論]]
|
||
|
||
[[Erg]]のドキュメントが参考になる
|
||
|
||
[[構造的部分型]]と[[単一化]]の組み合わせ方の参考になる
|
||
|
||
[erg/doc/JA/compiler/inference.md at main · erg-lang/erg · GitHub](https://github.com/erg-lang/erg/blob/main/doc/JA/compiler/inference.md)
|
||
|
||
|
||
## デフォルト型パラメーターの推論
|
||
|
||
[[mimiumのレコード型#レコード型を使った自動パラメータパック]]
|
||
|
||
これをちゃんと推論したい
|
||
|
||
```rust
|
||
fn foo(a,b=1.0,c=2.0){
|
||
a+b+c
|
||
}
|
||
fn dsp(){
|
||
{ a = 4.0 .. } |> foo // should be 7.0
|
||
}
|
||
```
|
||
|
||
試しにオプション型`Option<T> = Some(T) | None`を`T?`と書くことにする
|
||
|
||
`foo:{a:float,b:float?,c:float?}->float`
|
||
|
||
関数内でランタイムチェックしてOKならこういう感じに展開できる
|
||
|
||
```rust
|
||
fn foo(a:float,b:float?,c:float?){
|
||
let b = b.unwrap_or(1.0);
|
||
let c = c.unwrap_or(2.0);
|
||
a+b+c
|
||
}
|
||
//bだけがunwrapされ、cはdefault値になる
|
||
fn dsp(){
|
||
foo({ a = 4.0 , b = 3.0 }) // should be 9.0
|
||
}
|
||
```
|
||
|
||
そもそもSubtypingがきちんと働けばImcompleteRecord(`{..}`)とか書く必要ないっぽい
|
||
|
||
ランタイムチェックをなくそうと思うと、結局静的ポリモーフィズムになる
|
||
|
||
`{a:float, b:float}` と `{a:float, b:float?, c:float?}`
|
||
|
||
float?はfloatとNoneいずれも受け入れられる。float?はfloatのサブタイプである。
|
||
|
||
`float? <: float`
|
||
|
||
`U' <: U`ならば`{a:T,b:U,c:V}` <: `{a:T,b:U'}`
|
||
|
||
|
||
|
||
でも構造的部分型だと[[mimiumでのIOパラメーター#mimiumの多段階計算 と組み合わせる]]の話とコンフリクトする
|
||
|
||
```rust
|
||
//この場合、aとbだけがuiに現れることになる?
|
||
fn dsp(){
|
||
foo(control!({ a = 4.0 , b = 3.0 }))
|
||
}
|
||
```
|
||
|
||
|
||
|
||
```rust
|
||
//この場合ならRow Polymorphismになるとかすればいいのか
|
||
fn dsp(){
|
||
foo(control!({ a = 4.0 , b = 3.0 .. }))
|
||
}
|
||
```
|
||
|
||
この時、
|
||
|
||
- control関数は`forall T. (T)->'T `
|
||
- 実引数の型`forall r. {a:float,b:float ..r }`(rは列多相のカインド変数)
|
||
- fooの引数の要求 `{a:float,b:float?,c:float?}`
|
||
|
||
これを単一化するとTは`{a:float,b:float,c:float?}`に・・・なる?
|
||
|
||
ImcompleteRecordリテラルが実行されてコンストラクタが呼ばれた時どうなるか
|
||
|
||
|
||
|
||
|