[英]*** Exception: Prelude.read: no parse in Haskell - Parsing, Expressions and Recursion
[英]Haskell *** Exception: Prelude.read: no parse
嗨,我收到錯誤消息時正試圖完成CIS194 Spring 13 *** Exception: Prelude.read: no parse
我的函數之一*** Exception: Prelude.read: no parse
。 函數所在的文件稱為LogAnalysis.hs
,函數名為parseMessage
,但該文件也從Log.hs
。 為什么會收到此錯誤消息,我該如何解決?
這是我的代碼: https : //github.com/Adam-Morris/CIS194/tree/master/Homework-2
read
是一個類型為read :: Read a => String -> a
的函數read :: Read a => String -> a
。 這意味着, read
取String
作為輸入,並對於一些類型返回一個值a
提供a
實現該Read
類型的類。 read
必須知道要返回哪種特定類型,並且可以通過以下兩種方式之一來知道:明確給該類型(例如, read "123" :: Int
或read "True" :: Bool
),或者推斷從上下文來看。 在您的情況下, read
推斷它必須返回一個Int
因為LogMessage
希望將Int
作為其第二個參數。 因此,在這種情況下,表達式read [y]
意思是:將Char
y
轉換為一個單元素字符串,然后嘗試通過解析將其轉換為Int
。 現在,如果y
恰巧包含不是十進制數字的字符,則它將失敗(通過引發異常),因為它將不知道如何將其轉換為整數。
現在您如何處理該問題? 調用之前,必須檢查要read
的輸入是否正確。 例如,您可以檢查y
是一個數字(使用適當的函數 ):
parseMessage (x:y:z)
| x == 'I' && isDigit y = LogMessage Info (read [y]) (unwords [z])
...
另外,您可以使用Text.Read中的readMaybe ,就像read
一樣,但是如果失敗則不會引發異常,而是返回無值:
parseMessage (x:y:z)
| x == 'I', Just n <- readMaybe [y] = LogMessage Info n (unwords [z])
問題是您輸入的消息格式。 您正在將一行作為字符串讀取,然后匹配字符串中的字符(因為字符串是[Char]
類型別名)。 在您的sample.log
,第一行( I 6 Completed armadillo processing
)將作為字符串傳遞給parseMessage
,並且參數將采用以下值:
x
= 'I'
y
= ' ' --single white space character
z
= "6 Completed armadillo processing"
read
獲取空格字符並拋出*** Exception: Prelude.read: no parse
為了獲取值,您可以執行以下操作:
parseMessage :: String -> LogMessage
parseMessage msg =
case words msg of
"I":y:z -> LogMessage Info (read y :: TimeStamp) (unwords z)
"W":y:z -> undefined
"E":y:z -> undefined
_ -> undefined
這樣,可以輕松提取前兩個有效單詞(在這種情況下為MessageType
和TimeStamp
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.