「値の制限」とは、高次の関数型プログラミングがないことを意味しますか?
絶対違う! 値の制限は、高階関数型プログラミングをほとんど妨げません。それが行うことは、多相関数(高階関数ではなく) の一部の適用を最上位で制限することです。
あなたの例を見てみましょう。あなたの問題は、oops
andoops2
がアイデンティティ関数であり、 type を持っていることforall 'a . 'a -> 'a
です。つまり、それぞれがポリモーフィックな値です。しかし、右側はいわゆる「構文値」ではありません。関数アプリです。(もしそうなら、型システムを破壊する可変参照とリストを使用してハッキーな関数を構築できるため、関数アプリケーションは多相値を返すことはできません。つまり、終了関数型 type を書くことができますforall 'a 'b . 'a -> 'b
。
幸いなことに、ほとんどすべての実際のケースで、問題のポリモーフィック値は関数であり、イータ展開によって定義できます。
let oops x = simple "" x
このイディオムには実行時間のコストがかかるように見えますが、インライン ライナーとオプティマイザーによっては、コンパイラーによって取り除くことができます。
このoops2
例は、値コンストラクターをパックおよびアンパックする必要があるため、より面倒です。
let oops2 = F(fun x -> let F f = get "" in f x)
これは非常に面倒ですが、無名関数fun x -> ...
は構文値でありF
、データ型コンストラクターであり、構文値に適用されるコンストラクターも構文値であり、ボブは叔父です。のパッキングとアンパッキングF
はすべて恒等関数にコンパイルされるため、 とまったく同じマシン コードにコンパイルされoops2
ます。oops
None
実行時の計算でやのような多態的な値を返したい場合は、さらに厄介です[]
。Nathan Sanders が示唆しているように、次のような単純な式で値の制限に違反する可能性がありますrev []
。
Standard ML of New Jersey v110.67 [built: Sun Oct 19 17:18:14 2008]
- val l = rev [];
stdIn:1.5-1.15 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val l = [] : ?.X1 list
-
高次のものは何もありません!それでも、値の制限が適用されます。
実際には、値の制限は、高階関数の定義と使用に何の障害にもなりません。あなたは単にイータ展開します。