我想查看当前目录,只打印.zip
个文件。
我的策略(如下所示)是将FilePaths作为IO [FilePath]
。我以为我可以抬起IO
,以便可以过滤字符串元素。
我的想法有什么问题?我想知道我在liftIO
而不是IO [FilePath]
上使用IO FilePath
是否存在问题。
import System.Directory
import System.FilePath.Glob
import Control.Monad.IO.Class
main :: IO()
listCompressedImages folder =
filter (match (compile ".zip")) (liftIO (getDirectoryContents folder))
main = listCompressedImages "." >>= print
答案 0 :(得分:6)
您不想在此使用liftIO
,这是为了将IO
操作提升到更复杂的monad,而不是用于从IO
操作中提取值。简而言之,您无法将IO a
变为a
。 IO
的重点是阻止你这样做。不过,您可以使用a
表示法直接使用do
值:
listCompressedImages :: FilePath -> IO [FilePath]
listCompressedImages folder = do
-- getDirectoryContents :: FilePath -> IO [FilePath]
-- contents :: [FilePath]
contents <- getDirectoryContents folder
-- filter (match (compile ".zip")) :: [FilePath] -> [FilePath]
return $ filter (match (compile ".zip")) contents
main :: IO ()
main = do
-- compressedImages :: [FilePath]
compresssedImages <- listCompressedImages "."
print compressedImages
每当您拥有类型为IO a
的内容并且希望从中获取a
类型的值时,请使用do
表示法并使用<-
将其解压缩。如需更深入的解释,我将遵从Learn You a Haskell。
答案 1 :(得分:3)
您无法从IO
中提取任何内容,但您可以调整其他功能以处理IO
值
listCompressedImages folder =
filter (match (compile ".zip")) `fmap` getDirectoryContents folder
以上fmap
将纯函数(filter ...
)应用于某个IO
值。请注意,结果类型仍为IO
- 再次,您永远无法逃脱IO
monad。