Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的mapEithers函数_Haskell_Map Function - Fatal编程技术网

Haskell中的mapEithers函数

Haskell中的mapEithers函数,haskell,map-function,Haskell,Map Function,以下功能如何工作: mapEithers :: (a -> Either b c) -> [a] -> Either b [c] mapEithers f (x:xs) = case mapEithers f xs of Left err -> Left err Right ys -> case f x of

以下功能如何工作:

mapEithers :: (a -> Either b c) -> [a] -> Either b [c]
mapEithers f (x:xs) = case mapEithers f xs of
                        Left err -> Left err
                        Right ys -> case f x of
                                      Left err -> Left err
                                      Right y -> Right (y:ys)
mapEithers _ _ = Right []

在第一个case表达式(
case mappeithers f xs
)中,当函数
f
尚未应用于列表元素时,它如何与
Left
Right
值进行模式匹配。

这是经典的递归,我们将
mapEithers
应用于一个子列表,生成类型为
b[c]
,如果它是
左侧的b
,我们只是通过它传播它

如果是
右cs
。然后我们将
f
应用于列表的开头。如果这产生了一个错误,我们将删除所有内容并向上传播,如果它是
正确的c
,那么结果是
正确的(c:cs)


因为我们需要一个重复的基本情况,一个空列表是记录的
Right[]

,这可以用
折叠来写。在真实的Haskell代码中,很少看到显式递归。相反,我们有一系列函数(除其他函数外,
fold
replicItem
map
filter
),它们为我们完成了“繁重的工作”,我们只需要提供一些参数,在使用它们时对它们进行一些定制

在本例中,您有两个
值,一个是列表其余部分的结果,另一个是当前值的结果。如果两者都是
右侧
,则希望它们一起列在一个列表中,如果它们都是
左侧
,则只希望保留错误消息

我在Haskell中所描述的可以写成

(:) <$> f elem <*> rest
mapEithers f = foldr (\elem rest -> (:) <$> f elem <*> rest) (Right [])
编辑:我刚刚意识到,通过一些额外的转换,它可以变得更简单。(但我的哈斯克尔赋不够强壮,无法流利地阅读此文……)


它与递归调用
mapEithers
的结果相匹配,后者是一个
b[c]
。但是当您将
mapEithers
应用于子列表时,由于递归,会再次调用
mapEithers
。这会一直持续到列表变为空,在这种情况下,它应该返回
Right[]
。但这并没有发生。我在推断什么是错的?@Sibi相反,这正是发生的事情。你看到了什么?你是否错过了第二部分,在它变成
Right[]
之后,所有东西都会重新构建?见第二小段谢谢,现在明白了。:-)
MapOrther
与使用
mapM
几乎相同,只是后者选择在第一个
左侧的
结果上进行快捷操作,而不是像
MapOrther
那样在最后一个结果上进行快捷操作。
mapEithers f = foldr (liftA2 (:) . f) (Right [])