今天我读了很多关于Haskell的内容,但这种格式化让我发疯。我想尽快理解我的基本错误,这样我就可以正常开始编码了。这里的函数应该返回一个字符串,该字符串以下一个“math Sign”示例字符串(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"
它给了我“input =的解析错误”。我也不确定如何在main中调用它,我真的需要putStrLn函数。我不认为我需要它,但我尝试了2874种不同的方法来写这个,现在我放弃了,需要帮助。
答案 0 :(得分:3)
除了Stephen Diehl提供的格式改进之外,您还可以进行其他改进。正如卡尔指出的那样,你可以用警卫替换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
获得一个空列表作为参数时你还没有真正处理过这种情况,这可能是你想做的事情。
答案 1 :(得分:3)
使用Prelude列表函数dropWhile
和elem
,这是一个更简单的替代问题,其函数类型为(a -> Bool) -> [a] -> [a]
。只要函数提供的条件为真,它就会从列表中删除元素。
因此,您的功能可以按如下方式重写。
let getNextSign x = dropWhile ( not . `elem` "+-*/^)" ) x
尽可能避免显式递归,并将它们放在更高阶函数中以便充分利用。 Prelude有大量的列表操作功能,它们总是派上用场。
答案 2 :(得分:2)
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 = ['+' , '-' , '*' , '/' , '^' , ')']