3

私はF#を学んでいますが、この言語で型推論とジェネリックスがどのように機能するかを理解していません。たとえば、ジェネリックmin関数を宣言し、さまざまなタイプのパラメーターで使用できます。

let min a b = if a < b then a else b

let smallestInt = min 3 5
let smallestFloat = min 3.0 5.0

しかし、タイプで同じことを試してみると、機能しません。

type Point2D(x, y) = 
    member this.X = x
    member this.Y = y

let float32Point = new Point2D(0.0f, 1.0f)
let intPoint = new Point2D(0, 1) // This expression was expected to have type 
                                 // float32 but here has type int

だから、私はいくつかの質問があります:

  • 型定義ではなく、異なる型のジェネリック関数定義を再利用できるのはなぜですか?
  • 関数は、C#ジェネリックのように、実行時にすべてのタイプに特化していますか?または、C ++テンプレートのようにコンパイル時に?または、すべての引数をIComparableとして扱うためにボクシングが実行されますか?

ありがとう。

4

1 に答える 1

6

クラスには明示的な型パラメーターが必要です。これは機能します:

type Point2D<'T>(x:'T, y:'T) = 
    member this.X = x
    member this.Y = y

let float32Point = Point2D(0.0f, 1.0f)
let intPoint = Point2D(0, 1)

2番目の質問に答えるために、の定義にminは署名があります'a -> 'a -> 'a (requires comparison)。制約はコンパイル時にのみ存在します(実行時の署名は同じですが、comparison制約はありません)。

<GenericLessThanIntrinsicは、制約のあるへの呼び出しに置き換えられます。制約は単に呼び出し元に伝播されます。

また、仕様のセクション14.6.7から:

一般化とは、可能な場合は定義のジェネリック型を推測し、それによって構成を複数の異なる型で再利用できるようにするプロセスです。一般化は、このセクションの後半にリストされている場合を除き、すべての関数、値、およびメンバー定義にデフォルトで適用されます。一般化は、オブジェクト式にジェネリック仮想メソッドを実装するメンバー定義にも適用されます。

(強調を追加)

クラスがリストにないことに注意してください。理論的根拠はないと思いますが、それ仕様によるものです。

于 2012-05-14T18:04:44.000 に答える