过滤 IO [Maybe String] 到 IO [String]

Filter IO [Maybe String] to IO [String]

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

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

我当前没有绑定运算符的解决方案:

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

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

一个简短的解决方案是

missingBin :: [String] -> IO [String]
missingBin = fmap catMaybes . mapM binDoesntExist

你不需要 >>= 运算符。

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

根据您在 binDoesntExist 上写的评论,我怀疑您可能更愿意使用不同的类型签名,即:

-- returns True if the passed binary is not present on the system
binDoesntExist :: String -> IO Bool
binDoesntExist = ...

此签名的实现可能比您现有的实现更简单; 另外你的missingBin也会更简单:

missingBin :: [String] -> IO [String]
missingBin = filterM binDoesntExist

此讨论假定您现有的函数始终 returns 恰好是它传递的 String(如果它 returns 任何 String);但这个假设对我来说似乎并不遥远。