问题描述
const validate = v => v === "fred" ? "Y" : undefined
现在,因为我想发挥作用并希望避免进行空检查,所以我决定将Maybe
(ramda-fantasy
)用于验证功能:
const vv = val => Maybe(val).map(v=> validate(v)).getorElse("N")
vv
如果返回Y
,则返回"fred"
,否则返回N
。
-
vv(null)
返回N
->确定 -
vv("fred")
返回Y
->确定 -
vv("ding")
返回undefined
->错误,预期N
问题是Maybe.map
总是返回Just
,我不理解(因为我只是在学习它)。对我来说,如果此函数的行为类似于返回Maybe(val)
或None
的{{1}}的行为,我将是有益的。
我有两个问题:
- 为什么
Just
不处理null / undefined? - 如何重写
Maybe.map
以使其在所有三种情况下都返回期望值?
编辑:我想解释为什么不应该更改validate:这只是来自外部库的函数的简单示例。我想看看将这样的库集成到函数式编程中有多么容易/困难。因此,与字符串操作无关,而与在某些时候计算为空的流值有关。
EDIT2:
这解决了我的问题:
vv
解决方法
注意:Ramda Fantasy是no longer maintained。该团队建议您使用这些概念的其他实现。
但是我们仍然可以回答这个问题,因为任何合理的Maybe
实现都可能是正确的
基本上,这不是Maybe设计的工作方式。这个想法是,您可以拥有一个Just持有绝对任何值。其中包括值null
和undefined
。
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')
产生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'
])
。然后我们可以使用它like this:
from lxml import etree as et
from collections import defaultdict
import pandas as pd
d = defaultdict(list)
root = et.fromstring(xml)
tree = et.ElementTree(root)
def traverse(el,d):
if len(list(el)) > 0:
for child in el:
traverse(child,d)
else:
if el.text is not None:
d[tree.getelementpath(el)].append(el.text)
traverse(root,d)
df = pd.DataFrame(d)
df.head()