[英]Haskell: how to write a monadic variadic function, with parameters using the monadic context
[英]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.