簡體   English   中英

Haskell-綁定映射的單子函數

[英]Haskell - binding a mapped monadic function

在這里的這段代碼中,我有一個函數tagsort,它使用FilePath並返回IO String。

   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] ,但是將tagsort映射到列表filedirs會生成[IO String] 我不太確定如何規避它,甚至根本無法規避它。 也許映射不是執行此操作的正確方法? 任何幫助,將不勝感激。

這是因為函數tagsort的類型為tagsort String -> IO String
注意:為了簡單起見,我使用IO ,對於[Char]FilePath都使用String

但是,將其映射到filedir :: [String]使用

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

IO [String]和`[IO String]之間發生沖突-前者是編譯器期望do塊中的表達式所期望的。

乍一看,這不是很有用。 但是,haskell具有用於此精確任務的稱為sequence的功能。 現在,它的約束不再重要,因為Foldable是完全不同的東西。 現在,知道它的類型可以是[IO a] -> IO [a]

再次幸運的是,有一個非常有用的預定義實用程序功能, mapM僅用於sequence . map f sequence . map f

最終代碼將是:

mapM tagSort fileDirs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM