我的程序应该遍历给定目录中的所有文件,并使用扩展名" .vm"附加计数器到每个文件的内容。然而,它有一个错误"不能用马赫类型[]与IO"在附加。 如果有人可以帮助我,那将是geatfull
我的代码:
import System.IO
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Applicative
import Data.List
import System.Directory
import System.FilePath
main = do
files <- getDirectoryContents "c:/program file"
let filtered = filter ( vmExtention ) files
[ appendFile x y| x<-filtered, y <- [0..] ]
print filtered
print files
vmExtention :: FilePath-> Bool
vmExtention s =
if ( takeExtension s )== ".vm" then True else False
答案 0 :(得分:3)
[ appendFile x y| x<-filtered, y <- [0..] ]
如果[IO ()]
有效(它不是),那就是appendFile x y
类型的迷路列表理解。您必须使用sequence
或类似的:
sequence [ appendFile x y| x<-filtered, y <- [0..] ]
但是,这不会奏效,因为y
必须是String
,而[0..]
是无限列表,所以最终会得到
appendFile x 0
appendFile x 1
appendFile x 2
appendFile x 3
...
你想要的东西
sequence [appendFile file (show counter) | (file, counter) <- zip filtered [0..]]
答案 1 :(得分:0)
在您的代码中,files
是IO操作列表([IO ()]
),因此要在列表中执行IO操作,您只需调用sequence files
即可。但是,您还需要更正列表理解 - 现在,它将尝试将范围[0..]
中的所有整数添加到第一个文件的末尾(列表推导中的范围从左到右嵌套) ,即,给定x<-A, y<-B
,对于每个x,我们从B中取a,直到B耗尽,然后取下一个x)。更好的列表理解将是
let files = [appendFile (path </> x) (show y) | zip filtered [0..] ]
请注意,您还需要将路径添加到文件名的开头(我将let path = "c:\program file"
添加到主函数的开头),您需要show
整数将其转换为appendFile的字符串。
答案 2 :(得分:0)
import System.IO
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Applicative
import Data.List
import System.Directory
import System.FilePath
import Debug.Trace
debug = flip trace
main = do
let path = "/tmp/test"
files <- getDirectoryContents path
let filtered = filter ( vmExtention ) files
let filteredWithIndex = zip filtered [0..]
sequence_ [ appendFile' (path </> fp) (show i) | (fp,i) <- filteredWithIndex ]
appendFile' fp s =
-- note that the path was relative but is now fixed
appendFile fp s `debug` ("filepath: " ++ fp)
vmExtention :: FilePath-> Bool
vmExtention s =
takeExtension s == ".vm"