haskell 颠倒的[也许是]反常行为

lzfw57am  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(184)

我想创建一个函数来接收一些要处理的项,当没有项可以处理时返回Nothing,如果至少有一个项被处理,则返回Just
对我来说,这听起来很像traverseMaybe的作用,但却是相反的,因为如果至少有一项没有处理,它将返回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)
iq0todco

iq0todco1#

因为Maybe [a]是一种奇怪的类型,你不太可能找到一个标准的库函数来做这件事,所以你需要写你自己的函数......你已经写好了。
如果您希望使用更简洁的语言,则可以使用以下方法:

import Data.Maybe

traverseI :: (a -> Maybe a) -> [a] -> Maybe [a]
traverseI f xs = case mapMaybe f xs of
                   [] -> Nothing
                   xs -> Just xs

Maybe [a]是一个“奇怪”类型的原因(至少对于这个特定的应用程序来说)是,更简单的类型[a]已经允许一个值,即空列表[],可以表示所有项目都无法处理的情况。这种类型已经足够强大,不需要额外的Maybe Package 器及其相关联的Nothing值。

相关问题