我不得不承认我对函数式编程知之甚少。我从这里和那里读到过它,因此知道在函数式编程中,函数返回相同的输出,对于相同的输入,无论函数被调用多少次。它就像一个数学函数,对于函数表达式中涉及的输入参数的相同值,它的计算结果相同。
例如,考虑一下:
f(x,y) = x*x + y; // It is a mathematical function
无论你使用多少次f(10,4),它的价值永远不变104。因此,无论您在何处编写f(10,4),都可以将其替换为104,而不会更改整个表达式的值。此属性称为表达式的引用透明度。
f(10,4)
104
正如维基百科所说(链接),
相反,在函数式代码中,函数的输出值仅取决于输入到函数的参数,因此使用相同的参数 x 值调用函数 f 两次将产生相同的结果 f(x) 两次。
函数式编程中可以存在时间函数(返回 当前时间)吗?
如果是,那它怎么可能存在?不违反函数式编程的原则吗?它特别违反了引用透明性,这是函数式编程的属性之一(如果我正确理解的话)。
或者如果不是,那么在函数式编程中如何知道当前时间?
另一种解释方式是:没有 函数 可以获取当前时间(因为它一直在变化),但是一个 动作 可以获取当前时间。假设它getClockTime是一个常量(或者一个空函数,如果你喜欢的话),它表示获取当前时间的 动作 。这个 动作 无论何时使用,每次都是一样的,所以它是一个实常数。
getClockTime
同样,假设print是一个需要一些时间表示并将其打印到控制台的函数。由于函数调用在纯函数式语言中不会有副作用,因此我们将其想象为一个函数,它接受时间戳并将打印它的 操作返回到控制台。 同样,这是一个真正的函数,因为如果你给它相同的时间戳,它每次都会返回相同的打印 动作。
print
现在,如何将当前时间打印到控制台?好吧,你必须将这两个动作结合起来。那么我们该怎么做呢?我们不能只传递getClockTime给print,因为 print 需要一个时间戳,而不是一个动作。但是我们可以想象有一个操作符,>>=它 结合了 两个动作,一个获取时间戳,另一个将一个作为参数并打印出来。将此应用于前面提到的动作,结果是...... tadaaa......一个新的动作,它获取当前时间并打印它。顺便说一句,这正是 Haskell 中的做法。
>>=
Prelude> System.Time.getClockTime >>= print Fri Sep 2 01:13:23 鏉变含 (妯欐簴鏅�) 2011
因此,从概念上讲,您可以这样查看:纯函数式程序不执行任何 I/O,它定义了一个 动作 ,然后运行时系统执行该动作。 动作 每次都是一样的,但执行的结果取决于执行时的情况。
我不知道这是否比其他解释更清楚,但它有时可以帮助我这样想。