【发布时间】:2018-07-02 04:27:44
【问题描述】:
我尝试编写一个练习程序。如果它可以根据给定的语法解析字符串,它应该读取一个字符串并返回一个空列表。如果字符串不是有效的语法,它应该返回“Nothing”。喜欢这里:
>prog "c+c*c$"
Just""
>prog "c+c-c$"
Nothing
我编写了以下函数,它们在 GHCI 中加载和编译,但是当我使用任何参数运行 prog 时,我得到以下异常:*** Exception: Maybe.fromJust: Nothing
我想我以错误的方式访问或传递了 Maybe 字符串,但不确定在哪里。欢迎任何有关正确处理 Maybe 结构的帮助。
这是我的代码:
import Data.Maybe
match :: Char -> Maybe String -> Maybe String
match x input
| (isNothing input == False) && (x == head (fromJust(input))) = Just (tail (fromJust(input)))
| otherwise = Nothing
prog :: String -> Maybe String
prog x = match '$' (expr (Just (x)))
expr :: Maybe String -> Maybe String
expr x = ttail (term x)
term :: Maybe String -> Maybe String
term x = ftail (factor x)
ttail :: Maybe String -> Maybe String
ttail x
| fromJust(x) == [] = Just []
| otherwise = ttail (term (match '+' x))
factor :: Maybe String -> Maybe String
factor x = match 'c' x
ftail :: Maybe String -> Maybe String
ftail x
| fromJust(x) == [] = Just []
| otherwise = ftail ( factor ( match '*' x))
【问题讨论】:
-
异常中错误消息的哪一部分对您来说没有意义?
-
好吧,基本上它首先发生的原因。在我的理解中,当使用有效参数字符串“c+c*c$”执行 prog 时,它甚至不应该存在 Nothing 状态。如果字符串不正确,它不应该返回异常,只返回“Nothing”。
-
您正在使用很多偏函数,例如
head,tail,fromJust,应尽可能避免。最好使用模式匹配和打开警告,因为它通常允许编译器指出程序崩溃的情况。 -
这个逻辑有点难以理解,但如果你跟踪它,你会看到第一个
c匹配,但随后有一个match '*'其余返回Nothing和你最终在ftail Nothing。ftail定义中的第一个守卫尝试评估fromJust Nothing并且......你的例外!