7

整数とトリプレットを取り、指定された位置でトリプレットの要素を返す関数を作成しようとしています (ヒッキーの本の演習 5.3)。トリプレットには、さまざまなタイプの要素を含めることができる必要があります。

それぞれがトリプルの特定の要素を返す 3 つの小さな関数を記述し、それに応じて大きな関数がそれらの 1 つを返すようにすると、うまくいくと思いましたが、うまくいきません。

この「イータ拡張」の概念をいじってみましたが、わかりませんでした。

let nth1 (a, _, _) = a
let nth2 (_, b, _) = b
let nth3 (_, _, c) = c

let nth i = match i with
    | 1 -> nth1
    | 2 -> nth2
    | _ -> nth3

let main = printf "%d\n" (nth 1 ("hello", 2, 'c'))

ここでは「2」と書くだけです。何かアドバイス?

4

2 に答える 2

7

あなたの質問に対する基本的な答え:

OCaml では、型システムが機能する方法により、強制的に単一のnthのみが返されます。あなたが望むのは交差型に似たものですが、OCaml の静的型セマンティクスは代わりに単一の型のみを返すことを強制します。この結果、タプルは要素が同じ型の場合に退化する必要があります。nth

この相互作用を考えてみましょう:

# let nth1 (a,_,_) =a;;
val nth1 : 'a * 'b * 'c -> 'a = <fun>
# let nth2 (_,b,_) = b;;
val nth2 : 'a * 'b * 'c -> 'b = <fun>
# let nth3 (_,_,c) = c;;
val nth3 : 'a * 'b * 'c -> 'c = <fun>
# let nth i = match i with
      | 1 -> nth1
      | 2 -> nth2
      | _ -> nth3;;
val nth : int -> 'a * 'a * 'a -> 'a = <fun>

したがって、あなたの質問は奇妙です。printf呼び出しのためではなく、 の定義のためですnth。代わりに、これらのタイプのいくつかを組み合わせた独自のタイプを作成することを検討することもできます。

実際、あなたが説明した種類の動作は、実際に取得する型がinput の値に依存する依存型に少し似ていますi。従属型付けは ML で見られる let 束縛ポリモーフィズムよりもはるかに表現力があるため、これは当然問題になるはずです!

タプルのインスタンスに対してこれを行うことができます。たとえば、型を作成できます。

type IntOrStringOrX = int | string | X

それに応じて、n番目のタイプを書き留めることができます...

于 2012-10-02T17:47:20.457 に答える
6

通常、コードを記述する前に型について考えると役立ちます。関数の提案されたタイプは何ですか?

于 2012-10-02T17:47:11.877 に答える