Module 我应该在模块中保留非函数值,还是将它们带到主程序文件中?

Module 我应该在模块中保留非函数值,还是将它们带到主程序文件中?,module,f#,Module,F#,这是一个关于我应该如何组织我的F#代码的问题。我希望它没有违反所以规则 我的项目中有几十个源文件(名称以.fs结尾)。每个文件包含一个模块。在其中一些文件/模块中,我只定义函数。在其他情况下,我定义函数和其他值(不是函数) 解决方案资源管理器中的最后一个文件是Program.fs(visualstudio),它实际上只包含很少的代码。大多数计算都是在它上面进行的 我正在考虑将其他模块中声明的非函数值移动到Program.fs。以下是我从这一变化中看到的优点和缺点: 优点: 1) 更好地了解程序流

这是一个关于我应该如何组织我的F#代码的问题。我希望它没有违反
所以
规则

我的项目中有几十个源文件(名称以
.fs
结尾)。每个文件包含一个模块。在其中一些文件/模块中,我只定义函数。在其他情况下,我定义函数和其他值(不是函数)

解决方案资源管理器中的最后一个文件是
Program.fs
visualstudio
),它实际上只包含很少的代码。大多数计算都是在它上面进行的

我正在考虑将其他模块中声明的非函数值移动到
Program.fs
。以下是我从这一变化中看到的优点和缺点:

优点:

1) 更好地了解程序流程

2) 更容易选择某一行以上的所有代码,并将其发送到FSI中执行

3) 在编辑器中搜索这些值稍微容易一些

4) 在声明值的行上放置断点可能更容易调试

缺点:

1)
Program.fs
可能变得庞大而笨拙

2) 模块化的损失

3) 实施更改后,如果模块
B
中的值
y
的计算取决于模块
A
中的值
x
“高于”,则我不能再将
y
作为值,必须将其声明为
x
的函数。类似地,如果模块
B
中的函数声明依赖于模块
a
中的值,我必须向函数定义中添加一个参数

下面是在两种替代方法下创建的同一个小程序的两个示例。总的来说,这两者中哪一个更好

// ///////////////// Values in modules \\\\\\\\\\\\\\\\\\\\

// File A.fs

module A

let i = 1
let add x y : float = x + y

// File B.fs

module B

let sqr z = z * z + float i
let x = sqr 99.9

// File Program.fs

open A
open B

let y =
    add (float i) x 
    |> sqr

printfn "%f" y

[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    0 // return an integer exit code

// This is the calculated value for y: 99640524.640100

// ///////////////// Values in Program.fs \\\\\\\\\\\\\\\\\\\\

// File A.fs

module A

let add x y : float = x + y

// File B.fs

module B

open A

let sqr i z = z * z + float i // notice the additional parameter

//File Program.fs

open A
open B

let i = 1
let x = sqr i 99.9

let y =
    add (float i) x 
    |> sqr i

printfn "%f" y

[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    0 // return an integer exit code

// This is the calculated value for y: 99640524.640100
模块中的值\\\\\\\\\\\\\\\\\\\\ //文件A.fs 模块A 设i=1 让我们加上xy:float=x+y //文件B.fs 模块B 设sqrz=z*z+float i 设x=sqr 99.9 //文件Program.fs 开 开放式B 让我来= 加(浮点数i)x |>sqr 打印fn“%f”y [] 让主argv= printfn“%A”argv 0//返回整数退出代码 //这是y:99640524.640100的计算值 //Program.fs中的值\\\\\\\\\\\\\\\\\\\\ //文件A.fs 模块A 让我们加上xy:float=x+y //文件B.fs 模块B 开 让sqr i z=z*z+float i//注意附加参数 //文件Program.fs 开 开放式B 设i=1 设x=sqr i 99.9 让我来= 加(浮点数i)x |>sqr i 打印fn“%f”y [] 让主argv= printfn“%A”argv 0//返回整数退出代码 //这是y:99640524.640100的计算值
正如您所介绍的,第二个版本(将值移到Main)更好。你几乎抓住了一个优势,这是一个非常大的优势。至于你列出的缺点:

  • 大main:是的,这取决于我们谈论的内容有多少,最坏的情况是你可以将值保存在main使用的另一个模块中,并且只用于值。想想“配置模块”
  • 模块化的丧失:我看不到 为什么?如果它增加了模块化程度?你的主要任务不是 依赖于模块X有一些值,它提供了它。然后,您可以将该模块与另一个满足相同接口的模块交换,而不必担心它可能对其他模块产生的连锁反应。如果你有一个大的模块层次结构,你可以考虑按照依赖倒置原则在main中表示它——这需要一些工作,但好消息是,在函数式语言中,你不需要IoC容器,部分应用程序可以完成这项工作
  • 如果模块B依赖于模块a中存在的一个值,那么它一开始就不是非常模块化的,是吗?您必须将其更改为函数,这是一件好事——它将显式地表示现在隐式的内容

  • 请注意,我是根据我的OOP经验写这篇文章的,所以在函数式编程中,有些可能不适用

    只是为了更好地了解您有多大,有多少文件?我的项目中有60个文件。最大的(到目前为止)文件有2600行(大约有12个类,这是唯一一个有类的文件)。然后我有一些200-500行,其他的都很小。将添加更多的类。包含非函数值的文件大约只有5个。