Haskell Data。也许是***例外:也许来自from:仅此而已

音速

我尝试编写一个练习程序。如果它可以根据给定的语法解析String,则它应该读取一个String并返回一个空列表。如果字符串的语法无效,则应返回“ 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))
开支

OP的代码中有几种反模式。我只讨论这个片段。

match :: Char -> Maybe String -> Maybe String
match x input
  | (isNothing input == False) && (x == head (fromJust(input))) = Just (tail (fromJust(input)))
  | otherwise = Nothing
  • 使用isNothing, fromJust是一种反模式,因为后者是一个部分函数,​​当使用时会导致程序崩溃Nothing程序员必须小心,要始终isJust事先检查,这很容易忘记。完全忘记这些功能,而改为依靠模式匹配要容易得多(请参见下文)。
  • .. == False 应该改写为 not ..
  • not (isNothing ..)应该是isJust ..(但同样,模式匹配使这一点毫无意义)
  • head,tail,!!也是部分函数,​​应在可能的情况下将其替换为模式匹配。上面head可能会调用[],因此我们需要事先进行检查。模式匹配避免了需要。
  • .. == []可以使用null ..(或者更好的是模式匹配)代替
  • 切勿f(x)为函数调用而,括号在此处无用。
  • 使用该-Wall标志打开警告:编译器经常发现代码中的问题。

如果您正在学习Haskell,我强烈建议您不要使用危险的部分函数,​​而是阅读有关模式修补的教程,使用它可以防止代码中的几乎所有问题。

为了进行比较,可以将以上代码重写为:

match :: Char -> Maybe String -> Maybe String
match x (Just (y:ys)) | x==y = Just ys
match _ _                    = Nothing

请注意,模式匹配如何同时检查参数是否为a Just,且内部具有非空列表,并提取构造函数内部的数据。如果失败,则采用下一种匹配情况(而不是使程序崩溃)。

在没有模式匹配的语言中(例如Java),通常库会迫使我们记住x.hasNext()访问数据之前检查数据是否存在x.next()忘记检查会导致运行时错误/异常。使用模式匹配时,这两个步骤以相同的语言结构组合在一起,因此无法“忘记”检查并使程序崩溃。

与原始代码不同,match x (Just [])不会崩溃,而是返回Nothing

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章