在F#中键入name作为标识符

时间:2017-10-31 20:27:01

标签: f#

我刚刚开始研究F#并意外地写了这个绑定

let List = 1

现在,当我尝试获取List方法时,例如' filter'我收到此错误

  

错误FS0039:字段,构造函数或成员'过滤器'没有定义。

当然,使用像Microsoft.FSharp.Collections.List.filter这样的完整类型名称的方法仍在使用。

我想知道为什么可以在F#中使用类型名称作为标识符,以及如何将名称列表设置为从Microsoft.FSharp.Collections键入List。

当我试图像这样重新分配时

type List = Microsoft.FSharp.Collections.List<'T>

我得到了

  

错误FS0039:未定义类型参数&#T;

谢谢!

2 个答案:

答案 0 :(得分:6)

在F#中,您可以重新定义几乎所有内容并隐藏现有定义。这适用于两种类型(实际上类型有关于阴影的不同行为,它们在打开命名空间时它们会影响它们的值)和值但不可互换,因为值和类型(以及模块)可以在范围内以某种方式同时共存。编译器将尽力找出哪一个。

你不是被迫的,但在F#中使用let绑定是一种常见的好习惯。

关于你的第二个问题,你在右侧使用的类型参数在作业的左侧不存在,它应该是:

type List<'T> = Microsoft.FSharp.Collections.List<'T>

但请注意filter不属于该类型。它在List模块中定义。

答案 1 :(得分:4)

你应该将你的let绑定从List重命名为合理的东西 - 正如Gustavo所提到的,你的定义是从F#隐藏核心List模块而无法使用List引用你的整数和模块。阴影核心功能将使您的代码非常混乱。使用camelCase进行绑定也是一个好主意,但这只是一种品味问题。

如果您坚持隐藏List,则您无法使用List.filter致电List.filter。如果你想要更短的东西,你可以定义模块别名:

module FsList = Microsoft.FSharp.Collections.List

请注意,尝试使用List<'T>执行类似的操作并不会执行相同的操作,因为filter之类的函数位于名为List的模块中,而不是静态成员类型。有了这个,您可以使用filter来呼叫FsList.filter