Haskell 使用自定义数据类型在列表中筛选
我刚刚开始使用Haskell。我正在使用它进行日志解析,并尝试过滤日志。但获取与类型不匹配相关的错误 这就是我所做的 我的数据类型Haskell 使用自定义数据类型在列表中筛选,haskell,Haskell,我刚刚开始使用Haskell。我正在使用它进行日志解析,并尝试过滤日志。但获取与类型不匹配相关的错误 这就是我所做的 我的数据类型 data LogExStack = LogExStack { methodName :: String, className :: String, extraInfo :: String } | List [LogExStack] deriving Show data LogException = LogException { exF
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
我也尝试过不使用[],但也失败了。有人能帮我吗。
我从这里获取了实现的参考
有人能帮我吗?
谢谢
编辑
以下是我在阅读《阿农邮报》后所做的修改
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
parsexpr::解析器日志异常
parseExpr=
做
fstLine我只能假设您调用的筛选器错误:
您定义了自己的数据类型List[LogExStack]
,但您的filterStackTrace
只接受[LogExStack]
。因此,在调用filterStackTrace
之前,您需要从list
构造函数中“提取”实际列表,可能需要在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
modulemain其中
导入文本.Parsec
导入Text.Parsec.String
数据LogExStack=LogExStack{
methodName::String,
类名::字符串,
extraInfo::字符串
}衍生节目
exceptionParser::Parser LogExStack
异常分析器=
做
_你有确切的错误信息吗?这看起来不像是类型不匹配。一个不相关的错误是LogExStack可能没有methodName。您可能想处理这个问题。@PyRulez我已经添加了错误详细信息。我已经按照您所说的进行了更改,但仍然显示类型错误,我已经编辑了我的question@NixitPatel我更新了我的答案,看看那个例子
exceptionStackTraceParser :: Parser [LogExStack]
exceptionStackTraceParser =
sepBy exceptionParser newLinesTabEx
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