4

OCamlで

    let nth_diff_type i (x, y, z) =
        match i with
         1 -> x
        |2 -> y
        |3 -> z
        |_ -> raise (Invalid_argument "nth")

現在のタイプはint->('a,'a,'a)->'aですよね?

これは、x、y、z が同じ型でなければならないことを意味します。

だから私の質問は、x、y、z が同じ型である必要がないように、最大​​のポリモーフィックを与えることは可能ですか?

4

3 に答える 3

8

いいえ、そうではありません。

OCaml の関数は、戻り値の型を 1 つだけ持つ必要があります。戻り値の型が一意である場合、さまざまな引数の型を持つことができます。

let nth_diff_type i (x, y, z) =
    match i with
    | 1 -> `Fst x
    | 2 -> `Snd y
    | 3 -> `Thd z
    |_ -> raise (Invalid_argument "nth")

// val nth_diff_type :
//   int -> 'a * 'b * 'c -> [> `Fst of 'a | `Snd of 'b | `Thd of 'c ] = <fun>

トリプレット用のいくつかのユーティリティ関数を作成したい場合は、残念ながらそれらを個別に定義する必要があります。

let fst3 (x, _, _) = x
let snd3 (_, y, _) = y
let thd3 (_, _, z) = z
于 2013-01-16T17:49:23.690 に答える
2

f関数が正しい型を持っているなどのタプルの任意の要素に任意の関数を適用する場合、fこのポリモーフィックをある程度拡張することができます。

nth_diff_type言い換えれば、関数で何ができるかを考えると、その型が何であれ、 の結果に適用するには正しい型の関数が必要だという結論に達するでしょう。

nth_diff_type任意のタプルで機能するインスタントを仮定すると、その結果は潜在的に任意の型になります。intstring、またはより複雑なデータ型のインスタンスを取得する場合があります。そのタイプを と呼びましょうt。では、 type の値で何ができるでしょうtか? の値を受け入れる関数にのみ渡すことができますt

したがって、問題は適切な関数を選択することです。その選択は、タプル内の要素のランクとは非常によく似た基準で行われます。もしそうなら、あなたのタプルと、 に適用できる関数のタプルを単純に渡して、nth_diff_typeそれ自体でアプリケーションを実行させてみませんか?

let nth_diff_type i (a,b,c) (fa,fb,fc) =
    match i with
        | 1 -> fa a
        | 2 -> fb b
        | 3 -> fc c
        | _  -> failwith "out of range"

-: val nth_diff_type : int -> ( 'a * 'b * 'c) -> (('a -> 'd) * ('b -> 'd) * ('c -> 'd)) -> 'd
于 2013-01-17T05:34:24.330 に答える
1

コードは、非依存型システムではすでに完全にポリモーフィックです。依存型システムに移行することもできます(ただし、複雑さのコストのため、おそらく必要ありません)。この場合、型は次のようになります。

(n : int) -> (a * b * c) -> (match n with 1 -> a | 2 -> b | 3 -> c | _ -> Error)

パッドの提案に加えて、最初にパターンマッチングによって定義する代わりに、レコードまたはオブジェクトタイプを使用して直接「アウトプロジェクション」操作を行うこともできます。

type ('a, 'b, 'c) triple = { nth1 : 'a; nth2 : 'b; nth3 : 'c } 

(* replace *) nth_diff_type 2 v (* by *) v.nth2

オブジェクトタイプを使用する場合(事前にタイプを定義する必要がないという構造的なフレーバーが追加されます)

 (* replace *) nth_diff_type 2 v (* by *) v#nth2

これらの置換は定数整数でのみ機能することに注意してください(そうでない場合は、整数->型の依存関係が必要になるため)。GADTと実存型を使用して特定の選択を渡すことをサポートすることもできますが、既存の単純型システムに精通していないために、どのように理解するかを理解できないために、莫大な複雑さのコストを支払う必要があります。あなたは本当に物事をやりたいのです。

于 2013-01-17T01:17:50.273 に答える