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