All checks were successful
Build / build (push) Successful in 9m31s
2.2 KiB
2.2 KiB
Ergのドキュメントが参考になる
erg/doc/JA/compiler/inference.md at main · erg-lang/erg · GitHub
デフォルト型パラメーターの推論
mimiumのレコード型#レコード型を使った自動パラメータパック
これをちゃんと推論したい
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ならこういう感じに展開できる
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の多段階計算 と組み合わせるの話とコンフリクトする
//この場合、aとbだけがuiに現れることになる?
fn dsp(){
foo(control!({ a = 4.0 , b = 3.0 }))
}
//この場合なら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リテラルが実行されてコンストラクタが呼ばれた時どうなるか