函数式编程if语句

时间:2018-06-21 12:51:04

标签: functional-programming

我在js中与以下伪代码类似(数字为占位符):

    if (user.isActive()) {
        if (user.hasManyComments()) {
            if (user.isSpecial()) {
                return {ok: true}
            } else {
                return {ok: false, error: 'has comments'}
            }
        } else { 
             return {ok:true}
        }
    } else {
        return {ok: true}
    }
} else {
    return {ok: false, error: 'err'}
}

如何将代码同时转换为功能性和可读性?

我更喜欢以JS为例。

我知道在FP中您不具有if的编译功能,但是在某些情况下很难删除复杂的if语句。

可以使用库。

如果我只有一个水平的if可以,但是如果达到3,4个水平则很难

谢谢

1 个答案:

答案 0 :(得分:0)

对于此代码:

if (user.isActive()) {
    if (user.hasManyComments()) {
        if (user.isSpecial()) {
            return {ok: true}
        } else {
            return {ok: false, error: 'has comments'}
        }
    } else { 
         return {ok:true}
    }
} else {
    return {ok: true}
}

我认为它只需要一些重构酱即可。首先,您有3条良好的路径(return {ok: true})和2条可能结果的错误路径,但有4条return语句。让我们看看是否可以将其降低到1-1的比率:

return !user.isActive() || (!user.hasManyComments() || user.isSpecial()) ?
  {ok: true} :
  {ok: false, error: 'has comments'};

经验法则:您应该检查一次条件,并且返回语句的数量不得超过实际代码路径的数量。坦白说,我不一定认为它比您的原文更可读,即使更短。请注意,我基本上已经打过高尔夫球,这里有些中间。为了使它更具可读性,因为我们使用了大量的求反法,我们可以执行以下操作:

const tooManyComments = user.isActive() && 
  user.hasManyComments() &&
  !user.isSpecial();

return tooManyComments ? {ok: false, err: 'err'} : {ok: true};

现在,我们仅检查错误路径,否则返回true。

在评论中回答问题

如果要使其更短,可以通过滥用逗号运算符来实现。但这也许是一种更清洁(且仍然简短)的解决方案:

const hasTooManyComments = user => (user.isActive() && 
  user.hasManyComments() &&
  !user.isSpecial());

const response = hasTooManyComments(user) ? 
  {ok: false, err: 'err'} :
  {ok: true};

您还可以使其成为函数:

const generateResponse = user => hasTooManyComments(user) ? ...