我的警惕表情有问题吗?
Wrong in my guard expression?
我正在编写一个小程序,其中 "builds up" 一个字符串来自另一个字符串(即 "input string"(参数))。但是我收到一个解析错误(在输入“=”时)。我怀疑我的守卫表情有问题?
checkCons :: Char -> Bool
checkCons x = notElem x ['a','e','i','o','u','y']
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
如果我打电话:rovarSprak "abc" []
。我预计 "abobcoc"
.
观察 checkCons
函数是否按预期运行。
我认为您的旧代码缩进不正确。如果我 运行 ghc
编译器在:
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
报错:
strep.hs:8:1: parse error on input ‘|’
重写为:
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
解决编译错误
此外,如果尝试重现它,结果是:
"cocboba"
守卫工作正常,您的代码唯一的问题是在递归调用中:
rovarSprak restOfStr (c:'o':c:res)
-- ^push in front
您将结果推到新列表的前面,而您可能希望它在尾部。
您可以通过不使用 累加器 而是直接发射元素来解决这个问题。例如:
rovarSprak :: [Char] -> [Char]
rovarSprak [] = []
rovarSprak (c:restOfStr)
| (checkCons c) == True = c : 'o' : c : (rovarSprak restOfStr)
| otherwise = c : rovarSprak restOfStr
(以粗体和笔画冗余代码元素发出)。这也允许惰性列表生成:也许你只对输出的前三个元素感兴趣,或者输入是一个无限列表。
我建议的最后一个优化是交换 rovarSprak
:
的两行
rovarSprak :: [Char] -> [Char]
rovarSprak (c:restOfStr)
| checkCons c = c : 'o' : c : (rovarSprak restOfStr)
| otherwise = c : rovarSprak restOfStr
rovarSprak [] = []
这是因为您更有可能在第一行找到匹配项:对于长度为 N 的列表,将有 N 调用第一个模式,one 调用第二个模式。
我正在编写一个小程序,其中 "builds up" 一个字符串来自另一个字符串(即 "input string"(参数))。但是我收到一个解析错误(在输入“=”时)。我怀疑我的守卫表情有问题?
checkCons :: Char -> Bool
checkCons x = notElem x ['a','e','i','o','u','y']
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
如果我打电话:rovarSprak "abc" []
。我预计 "abobcoc"
.
观察 checkCons
函数是否按预期运行。
我认为您的旧代码缩进不正确。如果我 运行 ghc
编译器在:
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
报错:
strep.hs:8:1: parse error on input ‘|’
重写为:
rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
| (checkCons c) == True = rovarSprak restOfStr (c:'o':c:res)
| otherwise = rovarSprak restOfStr (c:res)
解决编译错误
此外,如果尝试重现它,结果是:
"cocboba"
守卫工作正常,您的代码唯一的问题是在递归调用中:
rovarSprak restOfStr (c:'o':c:res)
-- ^push in front
您将结果推到新列表的前面,而您可能希望它在尾部。
您可以通过不使用 累加器 而是直接发射元素来解决这个问题。例如:
rovarSprak :: [Char] -> [Char] rovarSprak [] = [] rovarSprak (c:restOfStr) |(checkCons c) == True= c : 'o' : c : (rovarSprak restOfStr) | otherwise = c : rovarSprak restOfStr
(以粗体和笔画冗余代码元素发出)。这也允许惰性列表生成:也许你只对输出的前三个元素感兴趣,或者输入是一个无限列表。
我建议的最后一个优化是交换 rovarSprak
:
rovarSprak :: [Char] -> [Char] rovarSprak (c:restOfStr) | checkCons c = c : 'o' : c : (rovarSprak restOfStr) | otherwise = c : rovarSprak restOfStr rovarSprak [] = []
这是因为您更有可能在第一行找到匹配项:对于长度为 N 的列表,将有 N 调用第一个模式,one 调用第二个模式。