3

最近、関数宣言の関数名の前に型変数を使用できることに気付きました。しかし、私はそれがどのように使用されているかを見ることができません。これを使用した例を次に示します。

Poly/ML 5.5.2 Release
> fun 'a print a = PolyML.print (a);
val print = fn: 'a -> 'a
> print "foo";
?
val it = "foo": string
> pint string "foo";
Error-Value or constructor (string) has not been declared
Found near print string "foo"
Static Errors
> string print "foo";
Error-Value or constructor (string) has not been declared
Found near string print "foo"
Static Errors
> val f : string -> string = print;
val f = fn: string -> string
> f "foo";
?
val it = "foo": string

そこで、これを踏まえていくつか質問があります。まず、関数名の前の型変数のユースケースの良い例は何ですか (引数または戻り値の型シグネチャでのより一般的な型変数とは対照的です)。また、型でできるように、型に特化したいことを示す方法はありますか?:

> type 'a t = 'a list;
eqtype 'a t
> type f = string t;
type f = string t

明示的な型シグネチャを持つ新しい変数 を作成して特殊化を宣言しましたval fが、これは同じことではないと思います。たとえば、上記の型の例からすると、次のことができると思います。

> val s = string print;
Error-Value or constructor (string) has not been declared Found near string print
Static Errors

しかし、それは失敗します。

最後に、型変数が関数内の引数の型を隠しているのはなぜですか? PolyML.print 関数は、実際の値ではなく疑問符 (型がわからないことを示す) を出力するため、これがまったく発生すると推測しているだけです。型を明確に制約する新しい関数を宣言したときでさえ、f渡される変数の型を認識していませんでした。(この特定の部分は、関数の初期型変数とは何の関係もないと確信していますが、引数の(暗黙の)型変数とは関係ありませんa。)

4

1 に答える 1

5

a の直後に型変数を配置する背後にある考え方funは、型変数のその後の使用にスコープを設定することです。の違いを検討してください。

> fun f x =
# let
#     fun I (y:'a): 'a = y
# in
#     I I
# end;
val f = fn: 'a -> 'b -> 'b

> fun 'a f x =
# let
#     fun I (y:'a): 'a = y
# in
#     I I
# end;
Type error in function application.
   Function: I : 'a -> 'a
   Argument: I : 'a -> 'a
   Reason:
      Can't unify 'a to 'a -> 'a (Cannot unify with explicit type variable)

Iの一般的な使用法はさまざまな型に特化できるため、最初の型チェックが行われます。I2つ目は、funで型変数をスコープすることにより、そのレベルで一般化できないと言ったため、そうではありません。'aあなたは、inside のすべてのオカレンスを同じにしたいと言いfました。

ML には、値と型、およびさまざまな種類のモジュールに対して個別の名前空間があります。 stringは型として定義されていますが、値が期待されるコンテキストでこの識別子を使用すると、未定義になります。型制約を追加する必要があります。: string -> string

PolyML.print最後に、例として使用する場合は注意してください。これは通常の ML ポリモーフィック関数ではなく、コンパイル時に型情報に応じて引数を出力する、無限にオーバーロードされた関数です。これは Poly/ML 拡張であり、PolyML 構造になっているのはそのためですが、print標準 ML となったものの初期のドラフトには存在していました。

于 2016-03-17T09:23:07.387 に答える