我想创建一个函数来接收一些要处理的项,当没有项可以处理时返回Nothing
,如果至少有一个项被处理,则返回Just
。
对我来说,这听起来很像traverse
对Maybe
的作用,但却是相反的,因为如果至少有一项没有处理,它将返回Nothing
,如果所有项都处理了,它将返回Just
。
假设traverseI
是我的“反向”导线:
myFunc :: [Int] -> Maybe [Int]
myFunc xs = traverseI (\x -> if x > 5 then Just (x+1) else Nothing) xs
myFunc [1, 3, 6, 9] -- Just [7, 10]
myFunc [1, 2, 3] -- Nothing
我猜我可以mapMaybe
这些值,然后检查它是否至少有一个项目,但我想知道是否有更“优雅”的解决方案。
编辑:我正在寻找的是某种方法来获得这个函数的等价物:
traverseI :: (a -> Maybe a) -> [a] -> Maybe [a]
traverseI _ [] = Nothing
traverseI f (x:xs) = do
let mh = f x
let mt = traverseI f xs
case mh of
Nothing -> mt
Just h -> case mt of
Nothing -> Just [h]
Just t -> Just (h:t)
1条答案
按热度按时间iq0todco1#
因为
Maybe [a]
是一种奇怪的类型,你不太可能找到一个标准的库函数来做这件事,所以你需要写你自己的函数......你已经写好了。如果您希望使用更简洁的语言,则可以使用以下方法:
Maybe [a]
是一个“奇怪”类型的原因(至少对于这个特定的应用程序来说)是,更简单的类型[a]
已经允许一个值,即空列表[]
,可以表示所有项目都无法处理的情况。这种类型已经足够强大,不需要额外的Maybe
Package 器及其相关联的Nothing
值。