私はリストの長さを取得する関数を書く必要がある代入に取り組んでいます。これは簡単な作業ですが、わからないことがあります。SML演算子とオペランドがfoldrで一致しない
私の単純なコード
val len = foldr (fn(_, y) => y + 1) 0
は
警告この警告生成:型がダミーの型にインスタンス化されるための 値の制限を一般化しませVARS(X1、X2を、...)
これをREPLで実行しようとすると、次のようになります。
len [1, 2, 3, 4];
stdIn:18.1-18.17 Error: operator and operand don't agree [overload conflict]
operator domain: ?.X1 list operand:
[int ty] list in expression:
len (1 :: 2 :: 3 :: <exp> :: <exp>)
なぜこれが機能しないのかわかりません。私はいくつかの関数型プログラミングの原則を知っています。もちろん
私はこの
fun len xs = foldr (fn(_, y) => y + 1) 0 xs
のように、一部のアプリケーションなしでそれを動作させることができますが、私は最初のバージョンが動作しない理由を理解したいと思います。
私は見ているので、型は割り当てられていません...しかし、なぜ型が 'foldr'関数から推測されないのでしょうか?部分的なアプリケーションは、最初の2つの引数がなくても、 'foldr'と同じ型の関数* value *であると思うでしょう。 – Pavlin
実際、2つのアプリケーションを持つ用語は関数の値にまで減少しますが、コンパイラはこれを構文的に扱います*。これは*何も減らさないことを意味し、単に用語の形を見ます。時にはこのルールは過度に慎重であり、適切に動作するプログラムを拒否します。何らかのタイプのシステムが '1 +(0なら0、次に1が真)のようなものを拒否します。しかし、タイプセーフティーを支払うのはちょっとした代償です。また、ランタイムオーバーヘッドが発生することもなく、これも重要です。 –