0

有一个给定的函数,它是固定的,不能更改:

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

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

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

vv如果 Y用 else 调用它应该返回。"fred"N

  • vv(null)返回N-> 确定
  • vv("fred")返回Y-> 确定
  • vv("ding")返回undefined-> 错误,预期N

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

我有两个问题:

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

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

编辑2:

这解决了我的问题:

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

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

4

1 回答 1

2

注意: Ramda Fantasy不再维护。团队建议您使用这些概念的其他实现。


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

基本上,这不是 Maybe 设计的工作方式。这个想法是你可以拥有一个 Just绝对持有任何价值。这包括值nullundefined

Ramda 添加了一个方便的构造函数,Maybe (val)它变成Just (val)if val 不是 nil 值,变成Nothing ()if 它是。但这并不意味着您不能创建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'). 然后我们可以像这样使用它:

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'
])
于 2020-10-16T18:49:34.140 回答