函数式编程中的一般函数是什么样的?
有人说"我们没有物体,但我们有更高阶的功能".更高阶的函数会替换对象吗?
在编写面向对象的应用程序时,我尝试从更一般的概念转向更详细的概念,很多时候.如果我尝试在函数式编程中这样做,我是否需要更多高阶函数?
scl*_*clv 11
这个答案面向Haskell而不是Lisp,因为尽管lisp具有更高阶的函数,但惯用的lisp可以并且通常非常面向对象.
我们还将忽略通常与面向对象编程相关的继承(和ad-hoc多态),但在某种程度上是正交的.
通常,抽象数据类型"替换"对象,在某种意义上,通常您使用对象将一堆相关数据捆绑在一起,例如Java或Python,并声明一种数据类型在Haskell或ML中执行此类操作.
但是,对象还会捆绑数据行为.因此,类的对象具有数据,但也有可以访问和改变该数据的函数.在函数式样式中,您只需在数据类型之外声明数据类型上的函数.然后通过任一模块或使用闭包来提供封装.
在后一点上 - 闭包和对象是双重的,尽管表达它们并不一定是惯用的.在波特兰模式wiki上有一些非常老派的讨论:http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent.
哦,以及来自oleg的一个例子:http://okmij.org/ftp/Scheme/oop-in-fp.txt.
忽略类型类(对于惯用的Haskell来说是必不可少的),并且只关注核心函数式编程,这里是一个不同方法的草图,这些方法将通过OO语言中的继承来完成.函数foo使用一些实现接口A的对象和一些实现接口B的对象来生成一些Double.对于更高阶的函数,你可能有一个类型签名fooGen :: (a -> Double -> Double) -> (b -> String -> Double) -> a -> b -> Double
.
该签名表示fooGen
从一些a和一个Double到另一个Double的函数,以及一些b的函数和一个Double的函数,然后它需要a和ab,最后它返回一个Double.
所以现在你可以通过部分应用,通过声明,例如,将"接口"与具体值分开传递fooSpecialized = fooGen funcOnA funcOnB
.
使用类型类,您可以抽象出"接口实现"(或者,更恰当的语言,字典)的传递,并声明foo :: HasSomeFunc a, HasSomeOtherFunc b => a -> b -> Double
.您可以将左侧的内容想象为=>
松散地声明您的具体a和b类型需要实现的接口.
对于一个非常普遍的问题,这当然是一个手写的和部分的答案.