4

F# スクリプト ファイルのシグネチャ ファイルを作成しているときにエラーが発生しましたが、うまく解決できません。

複製するには、新しい F# クラス ライブラリを作成し、ファイル Test.fs を追加します。

namespace Signatures

open System

type Test (id : Guid, name : string) =

  member this.Id = id
  member this.Name = name

これでうまくビルドできます。次に、その上に新しい署名ファイル Test.fsi を作成します。

namespace Signatures

open System

type Test =

  new : (Guid * String) -> Test

  member Id : Guid
  member Name : String

これはエラーでビルドされなくなりましたModule 'Signatures' requires a value 'new : (Guid * String) -> Test(これは、コンストラクターの署名が 2 つのファイルで異なる場合に発生するエラーとは異なります)。署名ファイルでコンストラクターを定義することについて私が見つけることができる唯一の実際のドキュメントは、MSDNであり、パラメーターなしのコンストラクターを扱っています。

.fs ファイルの Test にカーソルを合わせると、コンストラクターの署名が .fsi ファイルの署名と一致します。また、コンストラクターを変更して、喜びのない暗黙的ではないようにしました。

私は VS2012 RC を使用しており、.Net 4 と 4.5 を試しました。

4

3 に答える 3

6

コメントするには長すぎるので、回答として投稿します。

Testのコンストラクターは、タプルである 1 つの引数ではなく、パラメーターとして 2 つの引数を受け取ります。*引数の間が混乱しているように見えることは認めます。しかし、署名Guid -> string -> Testはそれよりもさらに悪いです。コンストラクターは、いくつかの入力を取得し、新しい型のインスタンスを生成する必要があります。カリー化された形式と部分適用は、コンストラクターのコンテキストでは意味がありません。

括弧がここで明確にするのに役立つと思います。

type Test (id : System.Guid, name : string) =
  member this.Id = id
  member this.Name = name

new : id:Guid * name:string -> Testしながら生産する

type Test (tuple: System.Guid * string) =
  let id, name = tuple
  member this.Id = id
  member this.Name = name

new : tuple:(Guid * string) -> TestFSI セッションで教えてくれます。記録には F# 2.0/MonoDevelop 3.0 を使用しています。

型シグネチャの作成に関しては、通常、コードを F# Interactive に送信し、生成されたシグネチャをfsiファイルにコピーして、間違いを回避します。ツールチップと F# Interactive が VS2012 RC でタイプ シグネチャを間違って表示する場合は、fsbugs (at) microsoft (dot) com で報告する必要があります。

于 2012-07-30T19:31:00.123 に答える
3

余分な括弧のペアが重要になる場合があります。次の点を考慮してください。

type T =
  static member Add(x, y) = x + y
  static member AddTuple((x, y)) = x + y

これは、C# では次のように表示されます。

int Add(int x, int y)
int AddTuple(Tuple<int, int> arg)

接線的には、コンストラクターで同様のことを行うことはできません。

type Test((id, name)) = class end //DOESN'T COMPILE

コンストラクターはすでにタプル形式で引数を取るため、と は別のものであると予想'a * 'bされます。('a * 'b)これは、メソッドの構文と一致しています。

于 2012-07-30T19:38:29.230 に答える
1

これが機能する理由を誰かが説明したい場合は、ぜひ知りたいのですが、構文をいじり始めて、コンパイラからもっと明らかになるものが得られるかどうかを確認しました.

タプルであるブラケットを削除すると、コンパイルされます。つまり、これを変更します。

new : (Guid * String) -> Test

に:

new : Guid * String -> Test
于 2012-07-30T17:53:32.877 に答える