6

F# コードでこの動作を観察することに完全に困惑しています。ここではインタラクティブ セッションから取得しました。

Microsoft (R) F# 2.0 Interactive build 4.0.40219.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> type foo = Foo of (string * int);;
  type foo = | Foo of (string * int)

> let f = Foo ("bar",42);;
  val f : foo = Foo ("bar", 42)

> match f with Foo x -> x;;
  val it : string * int = ("bar", 42)

> type bar = Bar of string * int;;
  type bar = | Bar of string * int

> let b = Bar ("baz",21);;
  val b : bar = Bar ("baz",21)

> match b with Bar x -> x;;
  match b with Bar x -> x;;
  -------------^^^^^

stdin(7,14): error FS0019: This constructor is applied to 1 argument(s) but expects 2
> 

単一の変数を使用した Foo と Bar の両方でのパターン マッチングが有効であることは明らかです。そのため、誰かがこの奇妙な動作の理由を知っているかどうか、または私が好きならそれをバグと見なすかどうか疑問に思っていました。

更新: 明確にするために、報告されたコンストラクターの型Fooとは次のBarとおりです。

> Foo;;
val it : string * int -> foo = <fun:clo@14-1>
> Bar;;
val it : string * int -> bar = <fun:clo@13>

したがって、確かに、それらは同じ有効なパターンのセットを受け入れる必要があります

4

1 に答える 1

6

これはかなり混乱しているように見えることに同意します。パッドが説明したように、2 つの宣言の違いは構文上のものだけではありません。実際には、異なる型で構成される差別化された共用体ケースを定義しています。

  • の場合Foo、ケースには型の要素が 1 つ含まれますint * string
  • の場合、ケースには typeとBarの 2 つの要素が含まれます。intstring

2 つのオプションは非常に似ていますが、実際には異なります。F# 仕様の型定義を見ればわかります。判別共用体の型定義を説明するビットは次のとおりです。

union-type-defn :=
   type-name '=' union-type-cases type-extension-elements opt

組合型ケース:=
   '|' ユニオン タイプ ケース '|' を選択します ... '|' ユニオンタイプのケース

union-type-case :=
   属性opt   union-type-case-data

union-type-case-data :=
   ident -- null ユニオン ケース
   ident 型 * ... * type -- n-ary ユニオン ケース

「n-ary union ケース」は複数の要素 ( type * ... * type) で構成されることに注意してください。は次のように定義されます (当然のことながら、タプルにすることもできます)。

type :=
   ( type )
   type -> type -- 関数型
   type * ... * type -- タプル type
   ... -- 他にもたくさんの型

union-type-case-dataが (n-ary ではなく) 単項ユニオン ケースのみを使用せず、要素を常にタプルとして扱う理由がわかりません。それは完全に理にかなっていると思いますが、F# が OCaml や ML から継承したものかもしれません。ただし、少なくとも仕様はこれを説明しています!

実際、仕様は少しあいまいだと思います。Foo of int * intタプルを使用すると、n-ary ユニオン ケースと unary ケースの両方として扱うことができるからです (ただし、角かっこで囲まれた type は使用しません( type ))。

于 2012-08-23T10:10:00.803 に答える