我有一个函数,它的签名是 String -> String -> IO (Maybe String)
现在,我使用此函数为字典构建值,最终得到:[(String,IO (Maybe String))]

我必须分析字典中的值并根据结果返回适当的键。我希望只在 Map 上使用过滤器来逐步完成它,但我想不出一种方法来即时提取该 IO 操作。那么如何映射/过滤运行 IO 操作的字典并根据 IO 操作的值返回字典的适当键?有没有简单的方法可以做到,或者我只是把自己弄得一团糟?

谢谢。

最佳答案

也许解决方案是将 sequence 与类似的东西一起使用

sequence . map (\(a,mb) -> (mb >>= \b -> return (a,b)))

然后您可以简单地使用 liftM 将您的过滤器应用于生成的 IO [(String,Maybe String)]
liftM 在 Control.Monad 中。或者,在 do 符号中
myFilter :: (String,(Maybe String)) -> Bool)
            -> [(String,IO (Maybe String))]
            -> IO [(String,(Maybe String))]
myFilter f ml =
   do
       l <- sequence . map (\(a,mb) -> (mb >>= \b -> return (a,b))) $ ml
       return $ filter f ml

也许需要进行一些重构。通常在使用 monad 时,您想使用 mapM 而不是 map

Control.Monad 中还有一个 filterM 函数。它可能是你需要的。

编辑:评论中指出
sequence . map (\(a,mb) -> (mb >>= \b -> return (a,b))) $ ml

相当于
mapM (\(a,mb) -> fmap ((,) a) mb) ml

所以
myFiter' f = (liftM $ filter f) .  mapM (\(a,mb) -> fmap ((,) a) mb)

关于Haskell:使用 IO() 值过滤字典/哈希/映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9255521/

10-17 00:35