在 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
.
vv(null)
returns N
-> OK
vv("fred")
returns Y
-> OK
vv("ding")
returns undefined
-> 错误,预期 N
问题是,Maybe.map
总是returns Just
,我不明白(因为我只是在学习它)。对我来说,如果这个函数的行为方式与 Maybe(val)
类似 returns None
或 Just
.
我有两个问题:
- 为什么
Maybe.map
不处理null/undefined?
- 如何重写
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。这包括值 null
和 undefined
.
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'
])
有一个给定的函数,它是固定的,不能更改:
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
.
vv(null)
returnsN
-> OKvv("fred")
returnsY
-> OKvv("ding")
returnsundefined
-> 错误,预期N
问题是,Maybe.map
总是returns Just
,我不明白(因为我只是在学习它)。对我来说,如果这个函数的行为方式与 Maybe(val)
类似 returns None
或 Just
.
我有两个问题:
- 为什么
Maybe.map
不处理null/undefined? - 如何重写
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。这包括值 null
和 undefined
.
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'
])