gpt4 book ai didi

functional-programming - 函数式编程如何在似乎不可避免的情况下避免状态?

转载 作者:行者123 更新时间:2023-12-04 08:40:43 25 4
gpt4 key购买 nike

假设我们定义了一个函数c sum(a, b),即函数式编程风格,该函数返回其参数的总和。到目前为止,一切都很好; FP的所有优点,没有任何问题。

现在假设我们在具有动态类型和单例,有状态错误流的环境中运行此代码。然后假设我们传递了a和/或b的值,而sum不是为处理(即不是数字)而设计的,它需要以某种方式指示错误。

但是如何?该功能应该是纯净的且无副作用。如何将错误插入到全局错误流中而不违反该规则?

最佳答案

我所知道的任何一种编程语言都没有内置“单状态状态错误流”之类的东西,因此您必须编写一个。如果您试图以纯函数式风格编写程序,那么您根本不会做这样的事情。

但是,您可以使用sum函数来返回总和或错误指示。实际上,通常使用名称Either来知道用于执行此操作的类型。然后,您可以轻松地创建一个函数,该函数调用可能会返回错误的一堆计算,并返回其他计算中遇到的所有错误的列表。这与您在说的很接近。它只是显式地返回,而不是全局的。

请记住,编写功能程序时的问题是“如何制作具有所需行为的程序?”不是,“我将如何复制一种采用另一种编程风格的特定方法?”。 “全局有状态错误流”不是目的,而是手段。纯函数样式不能有全局有状态错误流,不可以。但是,请问自己,您正在使用全局有状态错误流来实现什么;不管是什么,您都可以在函数式编程中实现这一点,而不必使用相同的机制。

询问纯函数式编程是否可以实现依赖于副作用的特定技术,就像询问如何在面向对象的编程中使用汇编中的技术一样。 OO提供了不同的工具供您使用来解决问题。将自己限制在使用这些工具来模拟不同的工具集将不是一种有效的方法。



对评论的回应:如果要通过错误流实现的目标是将错误消息记录到终端,那么可以,在某种程度上,代码将必须执行IO来做到这一点。1

打印到终端就像其他任何IO一样,没有什么特别之处,因此值得一提,因为在这种情况下,状态似乎特别不可避免。因此,如果这将您的问题变成“纯函数程序如何处理IO?”,那么毫无疑问,SO上有很多重复的问题,更不用说许多专门针对该问题的博客文章和教程了。对于纯编程语言的实现者和用户来说,这并不是突然的惊喜,这个问题已经存在了数十年,并且已经有了一些相当复杂的思想。

不同语言采用了不同的方法(Haskell中的IO monad,Mercury中的独特模式,Haskell的历史版本中的请求和响应的惰性流等等)。基本思想是提出一个可由纯代码操纵的模型,并将模型的操纵与语言实现中的实际不纯运算挂钩。这使您可以保留纯净的好处(适用于纯代码但不适用于一般不纯代码的证明仍将适用于使用纯IO模型的代码)。

纯模型必须经过精心设计,以使您实际上无法对实际IO进行任何无意义的操作。例如,Mercury通过编写程序来做IO,就好像您作为额外的参数传递了Universe的当前状态一样。这种纯模型可以准确地表示依赖并影响程序外部Universe的操作的行为,但是仅当系统在任何时候都存在Universe的确切状态时,才可以贯穿整个程序。 。所以有一些限制


类型io被抽象化,因此无法构造该类型的值。获得一个的唯一方法是从呼叫者那里传递一个。语言实现将io值传递到main谓词中,以启动整个过程。
传递给iomain值的模式声明为唯一。这意味着您不能做可能导致其重复的事情,例如将其放入容器中或将相同的io值传递给多个不同的调用。唯一模式可确保您只能将io值关联到也使用唯一模式的谓词,并且一旦将其传递给值“死”且无法在其他任何地方传递的值,则将其立即传递。




1请注意,即使在命令式程序中,如果您的错误记录系统返回错误消息流,然后才真正决定将它们打印到程序的最外层,则您将获得很大的灵活性。如果您的日志调用直接直接写输出,那么我想起来的只有几件事情变得很难用这样的系统进行:


推测性地执行计算,并通过检查是否发出任何错误来查看其是否失败
将多个高级系统组合到一个系统中,在日志中添加标签以区分每个系统
仅在还存在错误消息时才发出调试和信息日志消息(因此,在没有要调试的错误的情况下输出是干净的,在有错误的情况下输出详细信息)

关于functional-programming - 函数式编程如何在似乎不可避免的情况下避免状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13107734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com