f# - 让绑定(bind)支持用双反引号括起来的标点符号,但类型不支持?

标签 f# visual-studio-2012

在 Visual Studio 2012 中使用 F#,此代码编译:

let ``foo.bar`` = 5

但是这段代码没有:
type ``foo.bar`` = class end

Invalid namespace, module, type or union case name

根据 F# language specification 的第 3.4 节:
Any sequence of characters that is enclosed in double-backtick marks (````),
excluding newlines, tabs, and double-backtick pairs themselves, is treated
as an identifier.

token ident =
    | ident-text
    | `` [^ '\n' '\r' '\t']+ | [^ '\n' '\r' '\t'] ``

第 5 节将类型定义为:
type := 
    ( type )
    type -> type       -- function type
    type * ... * type  -- tuple type
    typar              -- variable type
    long-ident         -- named type, such as int
    long-ident<types> -- named type, such as list<int>
    long-ident< >      -- named type, such as IEnumerable< >
    type long-ident    -- named type, such as int list
    type[ , ... , ]    -- array type
    type lazy          -- lazy type
    type typar-defns   -- type with constraints
    typar :> type      -- variable type with subtype constraint
    #type              -- anonymous type with subtype constraint

...并且第 4.2 节将 long-ident 定义为:
long-ident :=  ident '.' ... '.' ident

据我从规范中可以看出,类型是用长标识命名的,长标识可以是标识。由于 idents 支持双反引号引用的标点符号,因此类型似乎也应该如此。

那么我是否误读了规范?或者这是一个编译器错误?

最佳答案

看起来规范与实际实现显然不同步,因此一侧或另一侧存在错误。

当您在双反引号中使用标识符时,编译器将其视为名称并简单地生成具有您在反引号中指定的名称的类型(或成员)。它不进行任何名称修改以确保标识符是有效的类型/成员名称。

这意味着您不能使用与编译代码中的某些标准含义相冲突的标识符也就不足为奇了。在您的示例中,它是点,但这里有一些其他示例:

type ``Foo.Bar``() =  // Dot is not allowed because it represents namespace
    member x.Bar = 0

type ``Foo`1``() =    // Single backtick is used to compile generic types
    member x.Bar = 0

type ``Foo+Bar``() =  // + is used in the name of a nested type
    member x.Bar = 0

上面的示例不允许作为类型名称(因为它们与某些标准含义冲突),但是您可以在 let-bindings 中使用它们,因为对变量名称没有这样的限制:
let ``foo`1`` = 0
let ``foo.bar`` = 2
let ``foo+bar`` = 1

这绝对是应该在文档和规范中解释的东西,但我希望这有助于澄清正在发生的事情。

关于f# - 让绑定(bind)支持用双反引号括起来的标点符号,但类型不支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12985468/

相关文章:

list - F# 列表查找项目索引

c++ - Visual Studio 2012 上的 OpenCV,缺少 MSVCP120D.dll

dll - "DLL missing" Visual Studio 2012?

f# - 如何在 f# 中的列表中解包联合值

f# - F# 中的强命名资源

f# - 让!按顺序执行?

c# - 在 Windows 应用商店应用程序 [XAML/C#] 中淡入/淡出 TextBlock

c++ - projAPI(GIS 库)堆溢出

visual-studio - C4067 Visual Studio 警告

.net - 在 F# 中对 2D 数组进行 Foreach 使编译器认为迭代值是对象类型。为什么?