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(这与两个文件中的构造函数签名不同时得到的错误不同)。我能找到的关于在签名文件中定义构造函数的唯一真实文档是MSDN,它处理无参数构造函数。

如果将鼠标悬停在 .fs 文件中的 Test 上,则构造函数的签名与 .fsi 文件中的签名匹配。我也尝试过更改构造函数,使其不是隐含的,没有欢乐。

我正在使用 VS2012 RC,并尝试过 .Net 4 和 4.5。

4

3 回答 3

6

评论太长了,所以我将其发布为答案。

Test的构造函数接收两个参数作为其参数,而不是一个元组的参数。我承认,*论点之间看起来令人困惑。但签名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) -> Test参加 FSI 会议。我使用 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 回答