我有一个Linux文件夹,其中包含许多文件,其中一些是二进制文件,而其他文件是脚本文件,其中第一行包含#! /bin/bash或类似内容。我正在尝试读取此类文件的第一行,拆分该行并打印出最后一个成员的列表(指示使用的程序):
import Control.Exception(catch, IOException)
import System.IO(IOMode(ReadMode), withFile, hGetLine)
import Data.Maybe(catMaybes)
import Data.List
import System.Directory (getDirectoryContents, doesFileExist, getFileSize)
import System.FilePath ((</>))
import Control.Monad(filterM)
getAbsoluteDirContents :: String -> IO [FilePath]
getAbsoluteDirContents dir = do
contents <- getDirectoryContents dir
return $ map (dir </>) contents
readFirstLine :: FilePath -> IO (Maybe String)
readFirstLine fp = withFile fp ReadMode $
\h -> (catch (fmap Just (hGetLine h))
((const :: a -> IOException -> a) (return Nothing)))
hasSlash :: String -> Bool
hasSlash firline = do
elem '/' firline
-- main :: IO ()
main = do
print
$ map last -- get only last string
$ map splitOn "/" -- split first line
$ filter hasSlash -- filter out those that do not have '/'
$ catMaybes -- get Just ones
$ map readFirstLine -- read first line of each file
$ filter doesFileExist -- filter out dirs
$ getAbsoluteDirContents "." -- get a list of all files & dirs
Run Code Online (Sandbox Code Playgroud)
在主函数中,执行将从下往上进行!
但是,以上代码给出了多个类型不匹配的情况:
soq_firstline6.hs:28:11: error:
• Couldn't match expected type ‘[String] -> [[b0]]’
with actual type ‘[b1]’
• The first argument of ($) takes one argument,
but its type ‘[b1]’ has none
In the second argument of ‘($)’, namely
‘map splitOn "/"
$ filter hasSlash
$ catMaybes
$ map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
In the second argument of ‘($)’, namely
‘map last
$ map splitOn "/"
$ filter hasSlash
$ catMaybes
$ map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
soq_firstline6.hs:28:15: error:
• Variable not in scope: splitOn :: Char -> b1
• Perhaps you meant ‘splitAt’ (imported from Data.List)
soq_firstline6.hs:31:7: error:
• Couldn't match type ‘IO (Maybe String)’ with ‘Maybe String’
Expected type: [Maybe String]
Actual type: [IO (Maybe String)]
• In the second argument of ‘($)’, namely
‘map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
In the second argument of ‘($)’, namely
‘catMaybes
$ map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
In the second argument of ‘($)’, namely
‘filter hasSlash
$ catMaybes
$ map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
soq_firstline6.hs:32:14: error:
• Couldn't match type ‘IO Bool’ with ‘Bool’
Expected type: FilePath -> Bool
Actual type: FilePath -> IO Bool
• In the first argument of ‘filter’, namely ‘doesFileExist’
In the expression: filter doesFileExist
In the second argument of ‘($)’, namely
‘filter doesFileExist $ getAbsoluteDirContents "."’
soq_firstline6.hs:33:7: error:
• Couldn't match expected type ‘[FilePath]’
with actual type ‘IO [FilePath]’
• In the second argument of ‘($)’, namely
‘getAbsoluteDirContents "."’
In the second argument of ‘($)’, namely
‘filter doesFileExist $ getAbsoluteDirContents "."’
In the second argument of ‘($)’, namely
‘map readFirstLine
$ filter doesFileExist $ getAbsoluteDirContents "."’
Run Code Online (Sandbox Code Playgroud)
如何纠正这些错误。谢谢你的帮助。
您不能只filter doesFileExists在这里使用,因为它doesFileExists是一个FilePath -> IO Bool函数,而不是一个FilePath -> Bool函数,因此map readFirstLine通过使用map,您正在构建一个[IO (Maybe String)],而不是一个,也会发生同样的情况IO [Maybe String]。您还忘记了使用括号map (splitOn "/")。
您可以使用filterM和来解决此mapM问题:
main = do
fps <- getAbsoluteDirContents "."
fexists <- filterM doesFileExist fps
flines <- mapM readFirstLine fexists
print
$ map last -- get only last string
$ map (splitOn "/") -- split first line
$ filter hasSlash -- filter out those that do not have '/'
$ catMaybes flines -- get Just onesRun Code Online (Sandbox Code Playgroud)
或经过贬义的变体:
main :: IO ()
main = getAbsoluteDirContents "." >>= filterM doesFileExist >>= mapM readFirstLine >>= print . map (last . splitOn "/") . filter hasSlash . catMaybes
Run Code Online (Sandbox Code Playgroud)
您hasSlash使用了do,但是在这里根本不使用monad,因此最好将其写为简单的:
hasSlash :: String -> Bool
hasSlash = elem '/'Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |