Functional programming 在函数式编程中,是;“拯救国家”;一个算法在递归函数参数欺骗?

Functional programming 在函数式编程中,是;“拯救国家”;一个算法在递归函数参数欺骗?,functional-programming,Functional Programming,例如,假设我们必须编写一个算法来获取整数数组的最大值,如果我们让递归函数返回模拟全局对象赋值的各种信息,我们还能调用代码函数吗?例如: function getMax(array, props={}) { const {index = 0, actualMax = array[0]}= props ///initial props const arrayNotEnded = array[index + 1] !== undefined if (arrayNotEnded)

例如,假设我们必须编写一个算法来获取整数数组的最大值,如果我们让递归函数返回模拟全局对象赋值的各种信息,我们还能调用代码函数吗?例如:

function getMax(array, props={}) {
    const {index = 0, actualMax = array[0]}= props ///initial props
    const arrayNotEnded = array[index + 1] !== undefined
    if (arrayNotEnded) {
        const maxOf= (a, b) => a > b ? a : b
        const newMax = maxOf(actualMax, array[index+1])
        const nextIndex = index+1
        return getMax(array, {index:nextIndex, actualMax:newMax} )
    }else return actualMax
}

<有趣的是,在Haskell,我们不能有可选的参数,所以这个逻辑不会是很酷的工作,因为每次我们需要调用这个函数时,我们都必须通过最初的道具。

是的,你可以认为它是作弊,但是这是函数编程中的一个众所周知的技术。累加器参数。记住:代码不会因为没有状态而变得功能化,函数式编程就是要使状态显式化。没有比将其作为函数的参数更好的方法了

不过,您的代码还有一些其他问题。最重要的是,状态应该是函数的内部状态,只传递给助手函数(可能是本地声明的或单独的),而不是作为函数公共接口的一部分。这还可以防止通过传递无效状态(例如越界索引)而混淆助手函数。是的,可选参数也有气味——不是因为您认为这在Haskell中是不可能的(使用
可能
),而是因为它可能被遗忘或错误地传递。相反,helper函数应该有一个必需的状态参数,
getMax
应该没有状态参数。
最后但并非最不重要的一点是,您应该避免对数组进行越界索引访问-检查长度以了解结束位置,不要与未定义的
进行比较。这包括无条件地访问
数组[0]
——这很容易忽略函数可以返回
未定义的
。也要明确此错误条件

我是这样写的:

function getMax(array) {
    if (!array.length)
        throw new Error("array must be non-empty");
    else
        return maxFrom(1, array[0]);

    function maxFrom(index, max) {
        if (index < array.length)
            return maxFrom(index+1, array[index] > max ? array[index] : max);
        else
            return actualMax
    }
}
函数getMax(数组){
如果(!array.length)
抛出新错误(“数组必须非空”);
其他的
返回maxFrom(1,数组[0]);
函数maxFrom(索引,最大值){
if(索引<数组长度)
返回maxFrom(索引+1,数组[index]>max?数组[index]:max);
其他的
返回实际最大值
}
}

甚至比抛出异常更好的是,如果您手头有一个代数数据类型,您可以返回它来表示错误或结果。

Haskell可能会为此使用嵌套函数,例如
getMax arr=innerMax 0(head arr),其中innerMax arr index actualMax=…
。它不会改变状态,每次调用都会给出相同的答案,所以我称之为函数。只是一个疑问:当你说Haskell中的Maybe to do可选参数时,你是说允许一个参数为“Nothing”吗?您确定这可以视为可选参数吗?因为我们需要指定我们希望该参数为空,不像其他语言(如javascript)那样,我们可以在没有参数的情况下简单地调用函数。@Vitorfigm是的,它在语义上是等价的,就像在javascript中传递
未定义的
。在JS中可以省略
undefined
参数只是一个语法特性。当然,Haskell中还有其他解决方案,从使用默认值可以覆盖或不覆盖的记录参数,到允许可变(省略表)参数的高级重载技巧。