作为 FP 设计关于可重用库的关键区别之一的前提(对于我正在学习的内容),这些库比相应的 OO(通常)更以数据为中心。
TFD (类型优先开发)等新兴技术似乎也证实了这一点,Tomas Petricek 在这篇博文中对此进行了很好的解释。
如今的语言是多范式的,同一 Petricek 在其书中解释了可从 C# 使用的各种功能技术。
我在这里感兴趣,因此问题是如何正确分区代码。
所以我定义了库数据结构,使用等效的可区分联合(如 Petricek 书中所示),并且我计划根据我的需求的域逻辑将它们与不可变列表和/或元组一起使用。
我在哪里放置作用于数据结构的操作(方法...函数)?
如果我想定义一个使用标准委托中体现的函数值的高阶函数,Func<T1...TResult>
我应该把它放在哪里?
常识告诉我将这些方法分组到静态类中,但我想得到那些已经用 C# 编写过函数库的人的确认。
假设这是正确的并且我有一个像这样的高阶函数:
static class AnimalTopology {
IEnumerable<Animal> ListVertebrated(Func<Skeleton, bool> selector) {
// remainder omitted
}
}
如果选择脊椎动物有N个我想在图书馆展示的特殊案例,那么更正确的展示方式是什么。
static class VertebratedSelectorsA {
// this is compatible with "Func<Skeleton, bool> selector"
static bool Algorithm1(Skeleton s) {
//...
}
}
或者
static class VertebratedSelectorsB {
// this method creates the function for later application
static Func<Skeleton, bool> CreateAlgorithm1Selector(Skeleton s) {
// ...
}
}
任何指示将不胜感激。
编辑:
我想引用 Mads Torgersen 的真实世界函数式编程前言T. Petricek 的两句话:
[...] 您可以在 C# 中使用函数式编程技术获得极大的好处,尽管在 F# 中这样做更容易、更自然。[...] 函数式编程是一种心态。[...]
编辑-2:
我觉得有必要进一步澄清这个问题。标题中提到的函数与函数式编程严格相关;我不是在问更实用的分组方法的方式,更逻辑的方式或更有意义的方式。
这意味着实现将尝试尽可能多地遵循NOOO宣言总结的 FP 的创始概念,并在此处引用以方便和清晰:
- 类上的函数和类型
- 纯度高于可变性
- 组合优于继承
- 方法分派之上的高阶函数
- 空值选项
问题是围绕如何布局遵循 FP 概念编写的 C# 库,因此(例如)绝对不是将方法放入数据结构中的选项;因为这是一个创始的面向对象范式。
编辑-3:
此外,如果问题得到回应(和各种评论),我不想给人一种错误的印象,即有人说一种编程范式优于另一种。和之前一样,我将在其书 Expert F# 3.0(第 20 章 - 设计 F# 库 - pg.565)中提到 FP 的权威人士 Don Syme:
[...] 函数式和 OO 编程方法相互竞争是一个常见的误解。事实上,它们在很大程度上是正交的。[...]