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