[英]Haskell syntax, parse errors for dummies
今天我读了很多关于Haskell的内容,但这种格式化让我发疯。 我想尽快理解我的基本错误,这样我就可以正常开始编码了。 这里的函数应该返回一个以下一个“math Sign”示例字符串(2sdwds+asd)+3
字符串(2sdwds+asd)+3
应该返回+asd)+3
。 这是代码
getToNextSign :: String -> String
getToNextSign str = do
let mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
let a = head str
if a `elem` mathSigns
then str
else if tail str /= []
then getToNextSign $ tail str
else []
main = do
putStrLn $ getToNextSign "(2sdwds+asd)+3"
它给了我“输入上的解析错误=”。 我也不确定如何在main中调用它,我真的需要putStrLn函数。 我不认为我需要它,但我尝试了2874种不同的方式来写这个,现在我放弃了,需要帮助。
除了Stephen Diehl提供的格式改进之外,还可以进行其他改进。 正如Carl指出的那样,你可以用守卫替换if-else if-else,如下所示:
getToNextSign :: String -> String
getToNextSign str
| a `elem` mathSigns = str
| tail str /= [] = getToNextSign $ tail str
| otherwise = []
where
a = head str
mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
当你在它时,你也可以用模式匹配替换头/尾,如
getToNextSign :: String -> String
getToNextSign (c:cs)
| c `elem` mathSigns = c:cs
| not (null cs) = getToNextSign cs
| otherwise = []
where
mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
如果你要进行模式匹配,你也可以一直采用它。
getToNextSign :: String -> String
getToNextSign str = case str of
c:_ | c `elem` mathSigns -> str
c:[] -> []
_:cs -> getToNextSign cs
where mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
当你这样做时,你会发现当getToNextSign
获取一个空列表作为参数时你还没有真正处理过这种情况,这可能是你想要做的事情。
这是使用Prelude列表函数dropWhile
和elem
一个更简单的替代方法,它有一个sig类型(a -> Bool) -> [a] -> [a]
。 它需要一个函数,只要函数提供的条件为真,就会从列表中删除元素。
因此,您的功能可以重写如下。
let getNextSign x = dropWhile ( not . `elem` "+-*/^)" ) x
尽可能避免显式递归,并将它们放在更高阶函数中以便充分利用。 Prelude有大量的列表操作功能,它们总是派上用场。
Haskell,对空白敏感,必须让函数的主体缩进到顶层之外。 对原始代码的直接修复将是:
getToNextSign :: String -> String
getToNextSign str = do
let mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
let a = head str
if a `elem` mathSigns
then str
else if tail str /= []
then getToNextSign $ tail str
else []
main = do
putStrLn $ getToNextSign "(2sdwds+asd)+3"
正如评论中指出的那样,因为你没有使用monad,所以你不需要在这里做表示法。 let语句可以写成where语句。
getToNextSign :: String -> String
getToNextSign str =
if a `elem` mathSigns
then str
else if tail str /= []
then getToNextSign $ tail str
else []
where
a = head str
mathSigns = ['+' , '-' , '*' , '/' , '^' , ')']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.