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

时间:2016-04-28 16:41:22

标签: haskell monads

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

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

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

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

我正在学习Haskell并尝试了解如何使用标准库的不同功能。我的解决方案有效,但我想有一种更清洁的方式。

2 个答案:

答案 0 :(得分:10)

简短的解决方案是

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

你不需要>>=运营商。

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

答案 1 :(得分:3)

根据您在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

本讨论假定您现有的函数总是返回它传递的String(如果它返回任何String);但这个假设对我来说似乎并不那么遥远。