将IO [Maybe String]过滤为IO [String]

Par*_*aub 9 monads haskell

如何过滤IO [Maybe String]以仅保留Just列表的值>>=并保留IO上下文.

-- returns Just, if the passed binary-name is not present on the system
binDoesntExist :: String -> IO (Maybe String)
binDoesntExist ...
Run Code Online (Sandbox Code Playgroud)

我没有bind-operator的当前解决方案:

missingBin :: [String] -> IO [String]
missingBin xs = do
  ys <- mapM (\x -> binDoesntExist x) xs
  return $ catMaybes ys
Run Code Online (Sandbox Code Playgroud)

我目前正在学习Haskell并尝试了解如何使用标准库的不同功能.我的解决方案有效,但我想有更简洁的方法.

eps*_*lbe 10

一个简短的解决方案就是

missingBin :: [String] -> IO [String]
missingBin = fmap catMaybes . mapM binDoesntExist
Run Code Online (Sandbox Code Playgroud)

你不需要>>=操作员.

注意: (\x -> binDoesntExist x) = binDoesntExist


Dan*_*ner 5

根据您在 上写的评论binDoesntExist,我怀疑您可能宁愿拥有不同的类型签名,即:

-- returns True if the passed binary is not present on the system
binDoesntExist :: String -> IO Bool
binDoesntExist = ...
Run Code Online (Sandbox Code Playgroud)

这个签名的实现可能比你现有的实现更简单;而另外missingBin也会被相当简单一点:

missingBin :: [String] -> IO [String]
missingBin = filterM binDoesntExist
Run Code Online (Sandbox Code Playgroud)

这个讨论假设你现有的函数总是准确地返回String它传递的值(如果它返回任何值String);但这个假设对我来说似乎并不遥远。