完全符合功能范式的准则/实践/规则的详尽列表是什么?

我已经开始和Kotlin一起玩,但是我感觉到我自己的限制。 我的问题是,我仍然认为Java因此风格仍然是必要的,我的问题是所有功能编程狂热者,我认为这将是所有人在开始阶段非常有用,也需要“制动”他们的大脑重新开始建设; 离开舒适区,开始思考伪,而不是“你的第一语言是什么”。 我相信,有经验的多语言开发人员可能会将这些概念咀嚼成简单的建议,使您的程序以完全有效的方式编写,甚至违反了范例 。 我不知道所有的怪癖,但请不要犹豫,包括我可能不知道的普遍接受的条件(我可以随时查找)。 在这一点上,我需要这套规则来让自己受到伤害,而不是打破他们,但是我知道我会感觉到,分析指导原则,了解他们如何变得更坏/更好,这当然是我自己的功课。

所以这些指南的例子就是这样的:

  • 永远不要改变状态,这可以通过使用x,y,z来避免
  • 只使用高阶函数(我可能是错的,只是例子)

我希望这个答案能给我长期的参考,让自己处于极端的条件下,当我感到不舒服的时候,我会停止逃避OOP。 而现在,当我看着Kotlin时,我明白我应该怎样思考问题,而不是用一种语言或另一种语言强加的结构。 意图总是可以转换为您选择的语言,并以适用于该语言的设计模式作为后盾,但是要找到中间地带,我需要首先从舒适区域监禁自己。

  • 避免像瘟疫一样的可变状态

    使用函数式编程的一个要点,可能是最主要的一点,就是避免使用可变状态时需要处理的所有小缺陷,错误和问题。 你应该尽一切可能,以避免变态。 例如,在你需要保持一个计数器变量更新的情况下,不要使用C风格for循环,而是使用map和其他更高阶的函数来抽象出你的迭代模式。 这也意味着,如果可以避免的话,决不应该改变变量的值。 相反,你应该把几乎所有的变量定义为常量,并用函数来计算新值,而不是改变它们。

  • 避免像鼠疫这样的副作用

    可怜的国家丑陋的表弟,副作用。 副作用意味着除了获取值并在函数中返回一个值之外的任何东西。 如果该函数打印数据,则会改变全局变量,将消息发送到线程或任何其他任何东西,而不是简单地使用参数,计算它们的值,并返回一个值,该函数具有副作用。 副作用很重要(请参阅下一个要点),但是如果使用它们,则无法跟踪。 想想每个人如何避免命令式编程中的全局变量。 函数式编程更进一步,并试图避免所有的副作用。 你的程序的大部分应该是纯粹的功能 。 (见前)

  • 当您需要使用副作用时,请保留它们。

    是的,我只是告诉你远离副作用。 但是,没有任何程序是没有任何副作用的。 图形用户界面? 副作用。 音频输出? 副作用。 打印到一个shell? 副作用。 所以,如果你想建立有用的东西,你不能真正摆脱副作用。 你应该做的是编写你的代码,让所有的副作用代码生活在一个主要调用纯函数的薄层中,然后用这些纯函数调用的结果做所需的副作用。

  • 使用纯粹的功能,你可以做的一切

    这是前一点的反面。 纯函数是一个没有任何副作用,也不会改变任何东西的函数。 它只能接受参数并返回一个值。 你应该使用这些。 比如说,你应该用纯函数构造你的日志字符串,然后让副作用层调用这些纯函数,调用更纯的函数来格式化日志字符串转换成完整的日志,然后从副作用层输出日志本身。

  • 使用高阶函数来构造你的代码

    高级函数在某种程度上是使函数式编程工作的粘合剂。 高阶函数是以一个或多个函数作为参数和/或返回函数的函数。 高阶函数的强大之处在于它们可以以声明的方式封装你在命令式程序中使用的许多模式。 例如,让我们来看看三个最常见的高阶函数:

    map是一个函数,它接受函数和值列表,将函数参数应用于每个值,并返回一个新的列表和结果。 map封装了迭代整个模式,以声明的方式对每个值进行操作。

    filter是一个函数,它接受一个函数,该函数返回一个布尔值和一个值列表,并将其函数参数应用于每个值,并返回一个只包含函数参数返回true值的列表。 它以声明的方式封装了从列表中选择结果的整个模式。

    reduce ,也被称为fold ,取一个初始值,一个二元函数和一个值列表。 它使用函数参数将初始值与列表的第一个值相结合,然后将结果与列表的下一个值结合,并继续执行此操作,直到它将列表减少为单个值。 它封装了从值列表中获取总值的整个模式。

    这绝不是一个详尽的高级函数列表,但这三个是最常见的。 我希望这已经足以说明如何构造代码,这些代码只需要以声明方式使用函数就可以获得大量的跟踪变量。 如果你使用这些高阶函数,那么很可能你再也不需要forwhile循环了。

这绝对不是功能性编程实践的详尽列表,但我认为大多数功能性程序员会同意这五个指导方针构成功能性编程的核心。 如果你真的想学习如何应用这些,我的建议是学习一个纯粹的函数式编程语言,比如Haskell,所以你不得不放弃必要的范例,学习如何在功能上构建东西。 如果你选择这样的方式,我会建议从第一原则的精彩的Haskell编程作为一个起始资源。 如果你不想/不能放下现金,那么UPenn的Brent Yorgey的Haskell课程也是一个很好的免费资源。