Cor*_*Xii 3 state functional-programming
假设我们定义了一个函数c sum(a, b),函数式编程,它返回其参数的总和.到现在为止还挺好; FP的所有好东西没有任何问题.
现在让我们假设我们在一个动态类型和单例,有状态错误流的环境中运行它.然后让我们说我们传递一个值的a和/或b说sum是不是设计来处理(即不是数字),它需要以某种方式指示错误.
但是怎么样?这个功能应该是纯粹的,没有副作用.它如何在不违反全局错误流的情况下插入错误?
我所知道的编程语言没有内置的"单例状态错误流",所以你必须制作一个.而且你根本就不会做出这样的事情,如果你试图在纯功能性的风格来写你的程序.
但是,您可以使用sum函数返回总和或指示错误.实际上,用于执行此操作的类型通常由名称所知Either.然后,您可以轻松地创建一个函数来调用可能返回错误的一大堆计算,并返回在其他计算中遇到的所有错误的列表.这与你所谈论的非常接近; 它只是明确地返回而不是全球化.
请记住,编写功能程序时的问题是"如何制作具有我想要的行为的程序?" 不,"我将如何复制另一种编程风格的特定方法?"."全局有状态错误流"是一种手段而非目的.您不能在纯函数样式中拥有全局有状态错误流,不能.但问问自己,你正在使用全局状态错误流来实现 ; 无论它是什么,你都可以在函数式编程中实现它,而不是使用相同的机制.
询问纯函数式编程是否可以实现依赖于副作用的特定技术,就像询问如何在面向对象编程中使用汇编技术.OO提供了不同的工具供您解决问题; 限制自己使用这些工具来模拟不同的工具集并不是一种有效的方法.
回应评论:如果你想用错误流实现的是将错误消息记录到终端,那么是的,在某种程度上代码将不得不做IO来做到这一点.1
打印到终端就像任何其他IO一样,没有什么特别之处,这使得它值得单挑作为一个国家似乎特别不可避免的情况.因此,如果这会将您的问题转变为"纯功能程序如何处理IO?",那么毫无疑问会有很多重复的问题,更不用说许多博客文章和教程正是针对该问题.对于纯编程语言的实现者和用户来说,这不是一个突然的惊喜,这个问题已经存在了几十年,并且已经有一些相当复杂的想法被放入答案中.
在不同语言中采用了不同的方法(IOHaskell中的monad,Mercury中的独特模式,Haskell历史版本中的请求和响应的惰性流等).基本思想是提出一个可以通过纯代码操作的模型,并将模型的操作与语言实现中的实际不纯操作联系起来.这使您可以保持纯度的好处(适用于纯代码但不适用于一般不纯的代码的证明仍然适用于使用纯IO模型的代码).
纯粹的模型必须经过精心设计,以便您实际上无法对其进行任何在实际IO方面没有意义的事情.例如,Mercury通过让您编写程序来执行IO,就像您将宇宙的当前状态作为额外参数传递一样.这个纯模型准确地表示了依赖于并影响程序外部的Universe的操作行为,但仅限于系统中任何时候只有一个Universe状态,从头到尾贯穿整个程序. .所以有一些限制
io是抽象的,因此无法构造该类型的值; 获得一个的唯一方法是从你的来电者传递一个.语言实现将一个io值传递给main谓词,以完成所有操作.io传入的值的模式main被声明为它是唯一的.这意味着您无法执行可能导致重复的操作,例如将其放在容器中或将相同的io值传递给多个不同的调用.唯一模式确保您只能将io值绑定到也使用唯一模式的谓词,并且只要在值"死"并且无法在其他任何位置传递时传递它.1请注意,即使在命令式程序中,如果您的错误记录系统返回错误消息流,然后实际上只是决定将它们打印在程序的最外层附近,您将获得很大的灵活性.如果您的日志调用是直接直接写入输出,那么我可以想到的一些事情就是这样一个系统变得更加困难:
| 归档时间: |
|
| 查看次数: |
989 次 |
| 最近记录: |