您好我正在尝试完成CIS194 Spring 13,当我在其中一个函数上收到错误消息*** Exception: Prelude.read: no parse
时。函数所在的文件名为LogAnalysis.hs
,函数为parseMessage
,但该文件也从Log.hs
导入。为什么我会发现此错误消息以及如何解决?
这是我的代码: https://github.com/Adam-Morris/CIS194/tree/master/Homework-2
答案 0 :(得分:2)
read
是类型为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
是否为数字(使用appropriate function):
parseMessage (x:y:z)
| x == 'I' && isDigit y = LogMessage Info (read [y]) (unwords [z])
...
或者,您可以使用readMaybe中的Text.Read read
,但如果失败则不会抛出异常,而是返回任何值:
parseMessage (x:y:z)
| x == 'I', Just n <- readMaybe [y] = LogMessage Info n (unwords [z])
答案 1 :(得分:0)
问题是您的输入消息格式。您正在以字符串形式读取一行,然后匹配字符串中的字符(因为字符串是[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
)。