我开始使用F#进行编码,并且正在使用函数作为参数调用函数 - 在线有大量的学习资源。现在我试图将这些部分组合成一个不仅仅是一组函数的东西。不幸的是,我找不到很多处理结构,设计或甚至“位”如何联系在一起的资源。
我找到了namespace
关键字(例如namespace MyOnlyNamespace
)但是我在命名空间中放置的函数出现了编译器错误:
命名空间不能包含值。考虑使用模块来保存您的值声明。
当我添加module CoolFunctions
时,我得到了
定义中结构化构造的意外启动。预期'='或其他标记
所以我有一个多部分的问题(但请回答你可以做的任何部分)
答案 0 :(得分:34)
提供一些关于在名称空间之间进行选择的具体建议,F#中的模块abd类:
如果您正在使用预期从F#中使用的let
编写函数,那么将它们放在模块中是最佳选择。这为您提供了与List.map
和其他基本F#函数类似的API。
关于命名,您应该使用camelCase
,除非您希望C#用户也调用这些函数。在这种情况下,您应该使用PascalCase
(并注意该模块将被编译为静态类)。
如果您正在编写类型decarations,那么这些通常应放在命名空间中。它们也允许在模块内部,但随后它们将被编译为嵌套类。
如果您正在编写F#类,那么它们也应该放在命名空间中。通常,如果您正在编写将由C#调用的F#代码,那么使用类是最好的机制,因为您可以完全控制用户将看到的内容(F#类被编译为一个类)。
如果您有一个文件,它可以以namespace Foo.Bar
或module Foo.Bar
开头,它将文件中的所有代码放在命名空间或模块中。您始终可以在此顶级声明中嵌套更多模块。一个常见的模式是从单个namespace
开始,然后在文件中包含一些类型和模块声明:
namespace MyLibrary
type SomeType =
// ...
module SomeFuncs =
let operation (st:SomeType) = // ...
答案 1 :(得分:6)
关于F#组件的设计,有一个非常好的draft online。
JPalmer已经指出了合成问题,但我认为其他一些问题值得更多:
什么是模块?
是的JPalmer是对的 - 模块被编译成静态类但我们真的关心F#吗? 恕我直言,你应该在F#编程时使用更多的模块而不是类。 在OOP中,您可以在其中定义类和方法。 在FP中,您可以定义简单类型(没有行为)和一组转换它们的函数。收集这些功能的自然场所就是模块。
它是一个类(类似于VB.NET模块)还是它 完全不同的东西?
VB模块确实是一个很好的比较。
如果还有其他内容,那么F#中是否有类?
是的,你可以使用F#中的类 - 它是一个完整的.net语言,而.net是OOP。你可以在F#中做几乎所有你可以在VB.net的C#中做的事情(只有某些情况下通用约束可能会很痛苦)
我应该使用其他结构吗? 否 - 将您的功能收集到模块中,但当然要为您的数据使用记录和抽象数据类型。
如何申报模块?
查看在线文档:模块(F#) - 您将找到所需的一切。
答案 2 :(得分:4)
什么是模块:
将模块编译为静态类。但我认为模块类似于C#中的命名空间
F#中有类 - 使用
type SomeType(constructor,args) =
....
如果你有
namespace Name
module Mod
....
这将无法编译 - 如您所知,您可以使用一些替代方案
module Namespace.Module
作为文件中的第一行
或
namespace Name
module Mod =
....