【问题标题】:flatmap do notation sugar for nested if undefined如果未定义,flatmap do notation 嵌套的糖
【发布时间】:2021-03-14 12:19:24
【问题描述】:

我有几个函数接受一个数字和额外的参数,返回一个数字或未定义。 我想依次调用这些函数,处理好路径的最终值。

如何避免像下面的代码那样嵌套 if 语句?

export function addPositive(num: number): number | undefined {
    if (num > 0) {
        return num + 2;
    }
}

let four = addPositive(3)

if (four) {
    let five = addPositive(four);

    if (five) {
        let six = addPositive(five);

        console.log(six);
    }
}

【问题讨论】:

  • 我投票结束这个问题,因为它要求改进工作代码 - 请在Code Review
  • 我想你会想要一个类似addPositive() 的函数,它也接受undefined,比如this。我不相信有任何可选的链接或无效的合并技术可以像这样工作,所以你必须自己动手。如果这个答案看起来合理,我会写下来。如果没有,请详细说明您要查找的内容。
  • 我认为这与我所寻找的最接近,谢谢。但是我调用的函数可能会改变,除了获取参数编号并返回可选编号。
  • 我刚看到评论“我正在调用的函数可能会改变”,所以我编辑了我的答案。

标签: typescript


【解决方案1】:

也许可以使用generator functions 来模拟do-notation; Stack Overflow 上还有其他问题,例如 this one,如果这确实是您需要的,您可以咨询。但我认为很难让输入正确(你希望编译器知道let five = yield ap(four) 中的yield 具有将number | undefined 变成number 的效果,而我不知道看不到明显的方法来做到这一点)。就算能做到,也显得相当重量级。


在这个特定的例子中,我宁愿将undefined 检查滚动到addPositive() 的实现中,以便它既接受又返回number | undefined。例如:

function ap(num: number | undefined) {
    return num ? addPositive(num) : undefined;
}

现在您可以将每次调用的结果作为下一次调用的参数传递,而无需求助于生成器之类的东西:

let four = ap(3)
let five = ap(four);
let six = ap(five);
console.log(six); // 9

如果您需要使用不同的函数而不仅仅是addPositive(),那么您可以制作一个转换器,将(x: T) => T | undefined 形式的函数转换为(x: T | undefined) => T | undefined 形式之一:

const def = <T,>(cb: (x: T) => T | undefined) =>
    (x: T | undefined) =>
        typeof x === "undefined" ? undefined : cb(x);

然后上面的ap函数就是

let ap = def(addPositive);

并且行为方式相同:

let four = ap(3)
let five = ap(four);
let six = ap(five);
console.log(six); // 9

Playground link to code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2017-11-15
    • 2020-08-22
    • 2021-12-27
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多