2015-06-30 47 views
2

我剛開始使用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

Filter a haskell data type

誰能幫助我? 感謝

編輯

這裏是看完之後我所做的更改嫩發佈

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函數調用,因爲我不知道莫名其妙地自以爲它調用的函數從必有秒差距類型。

我不知道爲什麼?任何人都可以幫助我理解這一點嗎?

+1

你是否有具體的錯誤信息?它看起來不像類型不匹配。 – PyRulez

+1

與此無關的錯誤是LogExStack可能沒有methodName。你會想要處理這個。 – PyRulez

+0

@PyRulez我添加了錯誤的詳細信息。 –

回答

2

我只能假設,您所呼叫的過濾器錯誤:

你定義自己的數據類型List [LogExStack],但你filterStackTrace只接受[LogExStack]。因此,你需要有「提取」從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 
+0

我已經做出了你所說的修改,但它仍然顯示Type error,我編輯了我的問題 –

+0

@NixitPatel我更新了我的答案,看看這個例子 – Arnon