我刚开始使用Haskell。我正在使用它进行日志解析,我正在尝试过滤日志。但得到与TypeMismatch相关的错误。
这就是我所做的。
我的数据类型
data LogExStack = LogExStack {
methodName :: String,
className :: String,
extraInfo :: String
} | List [LogExStack] deriving Show
data LogException = LogException {
exFirstLine :: LogExFirstLine,
exMessage :: LogExMessage,
exStackTrace :: LogExStack
} deriving Show
我希望对LogExStack
类型数据进行过滤。
我创建该列表的功能看起来像这样
exceptionStackTraceParser :: Parser LogExStack
exceptionStackTraceParser =
M.liftM List $ sepBy exceptionParser newLinesTabEx
exceptionParser :: Parser LogExStack
exceptionParser =
do
string "at"
method <- many (noneOf "(")
string "("
className <- many (noneOf ")")
string ")"
extraInfo <- many (noneOf "\n")
string "\n"
return $ LogExStack method className extraInfo
到现在为止它很好,但是当我尝试使用列表进行过滤时它没有用。我想从LogExStack列表中对methodName进行过滤。
这是我的功能
filterStackTrace :: [LogExStack] -> [LogExStack]
filterStackTrace = filter (\r -> methodName r == "com.xyz.abc")
我也试过没有[],但也失败了。谁能帮我这个。 我从这里获取了我的实现参考
https://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing
任何人都可以帮我这个吗? 感谢
修改
这是我在阅读Arnon帖子后所做的更改
exceptionStackTraceParser :: Parser [LogExStack]
exceptionStackTraceParser =
sepBy exceptionParser newLinesTabEx
这是我如何调用过滤器
parseExpr :: Parser LogException
parseExpr =
do
fstLine <- exceptionFirstLineParser
msgLine <- exceptionMessageParser
stackTrace <- exceptionStackTraceParser
list <- filterStackTrace stackTrace
return $ LogException fstLine msgLine list
这是我的例外
H:\>ghc --make -O logparser.hs
[1 of 1] Compiling Main ( logparser.hs, logparser.o )
logparser.hs:69:25:
Couldn't match type `[]'
with `Text.Parsec.Prim.ParsecT
String () Data.Functor.Identity.Identity'
Expected type: Text.Parsec.Prim.ParsecT
String () Data.Functor.Identity.Identity LogExStack
Actual type: [LogExStack]
In a stmt of a 'do' block: list <- filterStackTrace stackTrace
In the expression:
do { fstLine <- exceptionFirstLineParser;
msgLine <- exceptionMessageParser;
stackTrace <- exceptionStackTraceParser;
list <- filterStackTrace stackTrace;
.... }
EDIT2 得到它我从错误的地方调用列表过滤器我不能从parseExpr函数调用,因为我不知道从某种程度上它认为调用函数必须有Parsec类型。
我不知道为什么?任何人都可以帮我理解吗?
答案 0 :(得分:2)
我只能假设你错误地调用了过滤器:
您定义了自己的数据类型List [LogExStack]
,但filterStackTrace
仅接受[LogExStack]
。因此,您需要提取&#39;调用List
之前filterStackTrace
构造函数中的实际列表,可能是通过filterStackTrace
子句中的模式匹配:
filterStackTrace :: LogExStack -> LogExStack
filterStackTrace (List l) = List $ filter (\r -> methodName r == "com.xyz.abc") l
编辑: 实际上,第二个想法是,在这里定义自己的列表类型有点奇怪。 为什么不将数据类型设为
data LogExStack = LogExStack {
methodName :: String,
className :: String,
extraInfo :: String
} deriving Show
然后更改解析器以返回LogExStack
exceptionStackTraceParser :: Parser [LogExStack]
exceptionStackTraceParser =
sepBy exceptionParser newLinesTabEx
然后在你最初写的时候调用filterStackTrace
?
编辑2,作为回复:
您错过了对parse
的来电。
这个简单的程序对我有用:
module Main where
import Text.Parsec
import Text.Parsec.String
data LogExStack = LogExStack {
methodName :: String,
className :: String,
extraInfo :: String
} deriving Show
exceptionParser :: Parser LogExStack
exceptionParser =
do
_ <- string "at"
method <- many (noneOf "(")
_ <- string "("
className' <- many (noneOf ")")
_ <- string ")"
extraInfo' <- many (noneOf "\n")
_ <- string "\n"
return $ LogExStack method className' extraInfo'
exceptionStackTraceParser :: Parser [LogExStack]
exceptionStackTraceParser =
exceptionParser `sepBy` newLinesTabEx
where
newLinesTabEx = oneOf "\t\r\n"
main :: IO ()
main = do
case (parse exceptionParser "example" "bla bla bla bla") of
Left err -> print $ "Error: " ++ show err
Right xs -> print xs