
[[型推論]]

[[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リテラルが実行されてコンストラクタが呼ばれた時どうなるか




