【问题标题】:Haskell - binding a mapped monadic functionHaskell - 绑定映射的单子函数
【发布时间】:2019-05-03 00:08:11
【问题描述】:

在这里的这段代码中,我有一个函数 tagsort,它接受一个 FilePath 并返回一个 IO 字符串。

   builddir xs = do
    writeto  <- lastest getArgs
    let folderl b = searchable <$> (getPermissions b)
    let filel   c = ((lastlookup mlookup c) &&) <$> ((not <$> folderl c))
    a <- listDirectory xs
    listdirs <- filterM (folderl) (map ((xs ++ "/") ++) a)
    filedirs <- filterM (filel)   (map ((xs ++ "/") ++) a)
    tagfiles <- tagsort <$> filedirs
--testprint to terminal
    putStrLn $ concat listdirs
    putStrLn $ concat tagfiles


tagsort :: Control.Monad.IO.Class.MonadIO m => FilePath -> m [Char]
tagsort xs = do
    nsartist <- getTags xs artistGetter
    nsalbum  <- getTags xs albumGetter
    let artist = init $ drop 8 $ show nsartist
    let album  = init $ drop 7 $ show nsalbum
    pure (artist ++ " - " ++ album)

我想使用这个函数并将它映射到一个目录列表上。运行时出现此错误。

• Couldn't match type ‘[]’ with ‘IO’
      Expected type: IO (t0 [Char])
        Actual type: [t0 [Char]]
    • In a stmt of a 'do' block: tagfiles <- tagsort <$> filedirs

我相信我明白这里发生了什么。为了以我希望的方式绑定到标记文件,我想要一个IO [String],但是将标记排序映射到文件目录列表会产生[IO String]。我不完全确定如何规避这一点,或者它是否甚至可以被规避。也许映射不是正确的方法?任何帮助将不胜感激。

【问题讨论】:

  • 听起来你需要sequence。或者只使用mapM 而不是fmap / &lt;$&gt;
  • 我发誓我尝试了 mapM,它给出了与 map 相同的错误,但我错了。我觉得很傻。
  • 您能否将它现在有效的信息添加到问题中或回答您自己的问题或接受已发布的答案,而不是仅仅说您在 cmets 中解决了它

标签: haskell io monads


【解决方案1】:

这是因为函数 tagsort 的类型是 String -&gt; IO String
注意:为了简单起见,我使用IOString 用于[Char]FilePath

但是,当将其映射到 filedir :: [String] 时,使用

(<$>) = fmap :: Functor f => (a -> b) -> f a -> f b

IO [String] 和 `[IO String] 之间发生冲突 - 前者是编译器期望 do 块中的表达式。

乍一看,这并不是很有用。然而,haskell 有一个名为sequence 的函数来完成这个确切的任务。它的约束现在并不重要,因为Foldable 是完全不同的东西。现在,知道它的类型可以是[IO a] -&gt; IO [a]

再次幸运的是,有一个非常有用的预定义实用函数,mapM 仅用于 sequence . map f

最终代码为:

mapM tagSort fileDirs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多