【问题标题】:Is is possible to chain Maybe in case of null/undefined?在 null/undefined 的情况下是否可以链接 Maybe?
【发布时间】:2021-09-10 14:16:33
【问题描述】:

有一个给定的功能,它是固定的,不能改变:

const validate = v => v === "fred" ? "Y" : undefined

现在,因为我想使用功能并且想避免空检查,所以我决定使用Maybe (ramda-fantasy) 进行验证功能:

const vv = val => Maybe(val).map(v=> validate(v)).getOrElse("N")

如果用"fred" 调用vv,则应返回Y,否则返回N

  • vv(null) 返回N -> 好的
  • vv("fred") 返回Y -> 好的
  • vv("ding") 返回 undefined -> 错误,应为 N

问题是,Maybe.map 总是返回 Just,我不明白(因为我只是在学习它)。对我来说,如果此函数的行为方式与返回 NoneJustMaybe(val) 类似,我将受益匪浅。

我有两个问题:

  1. 为什么Maybe.map 不处理空/未定义?
  2. 如何重写vv 使其在所有三种情况下都返回预期值?

编辑:我想解释一下为什么不应该更改 validate:它只是来自外部库的函数的简单示例。我想看看将这些库集成到函数式编程中的难易程度。所以不是关于字符串操作,只是关于在某些时候它评估为 null 时的流式值。

EDIT2:

这解决了我的问题:

Either.ofNullable = Either.prototype.ofNullable = function (value) {
    return value == null ? Either.Left("is null") : Either.Right(value);
};

编辑3: 我已经实现了自己的 Either,但缺少功能:https://github.com/maciejmiklas/functional-ts/blob/main/src/either.ts

【问题讨论】:

    标签: ramda.js ramda-fantasy


    【解决方案1】:

    注意:Ramda Fantasy 是no longer maintained。团队建议您使用这些概念的其他实现。


    但我们仍然可以回答这个问题,因为任何合理的Maybe 实现都可能是这样的

    基本上,Maybe 的设计初衷并非如此。这个想法是你可以有一个 Justhold absolutely any 值。这包括值nullundefined

    Ramda 添加了一个方便的构造函数Maybe (val),如果 val 不是 nil 值,它将变成 Just (val),如果是,则变成 Nothing ()。但这并不意味着您不能创建Just (null)。主要的构造技术是使用静态Maybe .of。你可以注意到

    Maybe (null)    //=> Nothing ()
    Maybe.of (null) //=> Just (null)
    

    所以我们可能不会让这种技术发挥作用。我们不能只是 map 这样一个现有的 validate 而不是我们的 Maybe 并期望它能够工作。但是,我们可以使用这样的版本:

    const validate = v => v === "fred" ? Just ("Y") : Nothing ()
    

    在这里,我们还有一个问题。 Maybe ('fred') .map (validate) 产生 Just (Just ('Y'))。我们有额外的嵌套。但这正是chain 的用途。它删除了这样一个额外的级别,因此Maybe ('fred') .chain (validate) 产生Just ('Y')。然后我们可以使用它like this:

    const validate = v => v === "fred" ? Just ("Y") : Nothing ()
    const vv = val => Maybe (val) .chain (validate) .getOrElse ('N')
    
    console .log ([
      vv (null),   // 'N'
      vv ('fred'), // 'Y' 
      vv ('ding')  // 'N'
    ])
    

    【讨论】:

    • OP 确实要求保持validate 的完整性。 val => Maybe(validate(val)).getOrElse("N") 有效吗? Maybe 的不错的入门读物。
    • @Thankyou:虽然可以,但似乎没有理由为此使用Maybe。只需(v, r = validate2(v)) => r == 'Y' ? 'Y' : 'N' 就可以了。在 Maybe 中包装一些东西只是为了在同一个表达式中展开它并不会添加任何有用的东西。我想我也应该提出类似(val) => Maybe(val).map(validate).getOrElse('N') || 'N' 的建议,但我认为这很明显,并不能真正帮助人们了解Maybe
    • @Thankyou:或者我想我们可以变得更加陌生并使用类似(val) => Maybe(Maybe(val).map(validate).getOrElse('N')).getOrElse('N') 的东西。但我不会对此感到满意。
    • 我原来的理解是validate是一个导入函数,OP想把它带进Maybe
    • @Thankyou:是的,我明白了,但我假设目标是以某种方式与Maybe(val) 一起使用。在String -> String 函数的上下文中简单地引入Maybe 对我来说意义不大;有很多方法可以做得更好。但我不认为有一个的方法来做我认为OP想要的,即将Just(String) | Nothing()String -> String | Undefined结合得到String ('Y'|'N')undefined(也许很不幸)是语言中的一个值,可以包含在Just 中。但我可能完全误解了。
    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 2014-09-16
    • 2011-06-06
    • 2017-12-14
    • 2011-01-12
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    相关资源
    最近更新 更多