F#函数应该放在模块,类还是其他结构中?

Kir*_*rst 28 f# functional-programming

我开始使用F#进行编码,并且正在使用函数作为参数调用函数 - 在线有大量的学习资源.现在我试图将这些部分组合成一个不仅仅是一组函数的东西.不幸的是,我找不到很多处理结构,设计或甚至"位"如何结合在一起的资源.

我找到了namespace关键字(例如namespace MyOnlyNamespace),但是我在命名空间中放置的函数出现了编译器错误:

命名空间不能包含值.考虑使用模块来保存您的值声明.

当我加上module CoolFunctions我得到

定义中结构化构造的意外启动.预期'='或其他令牌

所以我有一个多部分的问题(但请回答你可以做的任何部分)

  • 什么是模块?
  • 它是一个类(类似于VB.NET模块)还是完全不同的东西?
  • 如果还有别的,那么F#中是否有类?
  • 我应该使用其他结构吗?
  • 我如何申报模块?

Tom*_*cek 35

为了给出关于命名空间之间选择的一些具体建议,F#中的模块abd类:

  • 如果您正在使用let预期从F#中使用的函数编写函数,那么将它们放在模块中是最佳选择.这为您提供了List.map与其他基本F#函数类似的API .

    关于命名,camelCase除非您希望C#用户也调用这些函数,否则您应该使用它.在这种情况下,您应该使用PascalCase(并注意该模块将被编译为静态类).

  • 如果您正在编写类型级别,那么这些通常应放在命名空间中.它们也允许在模块内部,但随后它们将被编译为嵌套类.

  • 如果您正在编写F#类,那么它们也应该放在命名空间中.通常,如果您正在编写将由C#调用的F#代码,那么使用类是最好的机制,因为您可以完全控制用户将看到的内容(F#类被编译为一个类).

如果您有一个文件,它可以以namespace Foo.Bar或开头module Foo.Bar,它将文件中的所有代码放在命名空间或模块中.您始终可以在此顶级声明中嵌套更多模块.一个常见的模式是从单个开始,namespace然后在文件中包含一些类型和模块声明:

namespace MyLibrary

type SomeType = 
  // ...

module SomeFuncs = 
  let operation (st:SomeType) = // ...
Run Code Online (Sandbox Code Playgroud)

  • 作为F#模块的公共C#/ VB.Net面向值的替代方法,您可以将camelCase与[<CompiledName("PascalCase")>]结合使用;) (3认同)
  • 谢谢你的回答.只是注意到[F#组件设计指南](http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp-component-design-guidelines.pdf)建议使用标准. NET命名约定 - 即用于类型,方法和命名空间的PascalCase,以及用于参数和局部变量的camelCase. (2认同)

Car*_*ten 6

关于F#组件的设计,在线有一个非常好的草案.

JPalmer已经指出了合成问题,但我认为其他一些问题值得更多:

什么是模块?

是的JPalmer是对的 - 模块被编译成静态类但我们真的关心F#吗?恕我直言,你应该在F#编程时使用更多的模块而不是类.在OOP中,您可以在其中定义类和方法.在FP中,您可以定义简单类型(没有行为)和一组转换它们的函数.收集这些功能的自然场所就是模块.

它是一个类(类似于VB.NET模块)还是完全不同的东西?

VB模块确实是一个很好的比较.

如果还有别的,那么F#中是否有类?

是的,你可以使用F#中的类 - 它是一个完整的.net语言,而.net是OOP.你可以在F#中做几乎所有你可以在VB.net的C#中做的事情(只有某些情况下通用约束可能会很痛苦)

我应该使用其他结构吗?否 - 将您的功能收集到模块中,但当然要为您的数据使用记录和抽象数据类型.

我如何申报模块?

看看在线文档:模块(F#) - 在那里你会找到你需要的一切.