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

时间:2011-09-26 04:24:30

标签: f# functional-programming

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

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

  

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

当我添加module CoolFunctions时,我得到了

  

定义中结构化构造的意外启动。预期'='或其他标记

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

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

3 个答案:

答案 0 :(得分:34)

提供一些关于在名称空间之间进行选择的具体建议,F#中的模块abd类:

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

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

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

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

如果您有一个文件,它可以以namespace Foo.Barmodule 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 =
    ....