在 null/undefined 的情况下是否可以链接 Maybe?

Is is possible to chain Maybe in case of null/undefined?

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

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

现在,因为我想发挥作用并希望避免空值检查,所以我决定使用 Maybe (ramda-fantasy) 作为验证函数:

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

vv 应该 return Y 如果用 "fred" 调用,否则 N.

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

我有两个问题:

  1. 为什么Maybe.map不处理null/undefined?
  2. 如何重写 vv 它在所有三种情况下都会 return 期望值?

编辑:我想解释为什么不应更改验证:它只是来自外部库的函数的简单示例。我想看看 easy/hard 是如何将这些库集成到函数式编程中的。所以不是关于字符串操作,而是关于在某个时候它评估为 null 时的流值。

编辑 2:

这解决了我的问题:

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 Fantasy 是no longer maintained。该团队建议您使用这些概念的其他实现。


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

基本上,这不是 Maybe 设计的工作方式。这个想法是你可以有一个 Just holding absolutely any value。这包括值 nullundefined.

Ramda 添加了一个方便的构造函数,Maybe (val),如果 val 不是 nil 值,它将变为 Just (val),如果是,则变为 Nothing ()。但这并不意味着您不能创建 Just (null)。主要的构造技术是使用staticMaybe .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'
])