我刚刚开始研究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;
谢谢!
答案 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
。