我正在尝试学习如何使用Haskell,现在我必须编写一个程序,该程序需要一个整数n和一个字符串k,并且该字符串的每个字母都将在字母表的右侧移动n个位置。此时,我有了下一个代码:
import Data.Char
main = do
x <- read getLine :: Int
y <- getLine
caesar x y
result :: String
rotate :: Int -> Char -> [Char]
rotate a b = [chr ((a + ord b) `mod` ord 'z' + ord 'a')]
caesar :: Int -> String -> ()
caesar moving text= do
rotatespecific moving text 0
putStrLn result
rotatespecific :: Int -> String -> Int -> ()
rotatespecific moving text place = do
if place < length text
then
result ++ rotate (moving (text !! place))
rotatespecific (moving text (place + 1))
else
if place == length text
then
result ++ rotate (moving (text !! place))
但是我无法编译它,因为它仍然给我同样的错误消息:
parse error (possibly incorrect indentation or mismatched brackets)
|
28 | result ++ rotate (moving (text !! place))
| ^
但是我看不出语法有什么问题。我首先认为这与将Char作为函数的参数有关,但我错了,因为文本!地方应该给一个字符而不是一个[字符]。那我在做什么呢?
经过一些编辑后,我得到了它,但是仍然不起作用:
import Data.Char
main = do
xr <- getLine
let x = read xr :: Int
y <- getLine
putStrLn (rotatespecific (x y 0))
rotate :: Int -> Char -> [Char]
rotate a b = [chr ((a + ord b) `mod` ord 'z' + ord 'a')]
rotatespecific :: Int -> String -> Int -> String
rotatespecific moving text place = do
if place < length text
then do
help <- text !! place
h <- rotate (moving help)
a <- rotatespecific (moving text (place + 1))
b <- h ++ a
return b
else
if place == length text
then do
return rotate (moving (text !! place))
else
return ()
答案 0 :(得分:5)
直接的问题是,每个if
必须具有一个else
。最后,您遇到了解析错误,因为解析器期望的更多,即该else
的{{1}}。
解决此问题时,您会遇到更多问题,因为您将Haskell当作命令式语言对待,而这并不是她喜欢被对待的方式。好像你在想
if place == length text
将变异result ++ newstuff
,并在其末尾添加result
。但是Haskell不会变异。相反,此表达式newstuff
是将result ++ newstuff
和result
连接在一起时得到的列表,但是newstuff
本身保持不变。
result
ghci> let result = [1,2,3]
ghci> result ++ [4,5,6]
[1,2,3,4,5,6]
ghci> result
[1,2,3]
必须返回旋转后的字符串,而不是试图将其变异为存在。函数进行通信的唯一方法是返回从其参数计算得出的结果-它们不能操纵任何rotatespecific
之类的“全局”状态。返回result
的函数被保证是无用的。
()
删除rotatespecific :: Int -> String -> Int -> String
“全局变量”(这并不意味着您所认为的意思),并专注于以返回旋转字符串的方式定义result
。
我还建议暂时注释掉rotatespecific
和main
,直到在caesar
中测试rotatespecific
为止。{p}
答案 1 :(得分:0)
我觉得这是一个展示示例的适当时机,因为存在很多小问题。我不会修复逻辑错误,但已经修复了您的语法。希望这能使您摆脱困境。
rotatespecific :: Int -> String -> Int -> String
rotatespecific moving text place =
if place < length text then
-- use let .. in instead of do/bind (<-) in pure functions.
let help = text !! place
-- multiple arguments are given after the function, no parentheses
h = rotate moving help
-- use parentheses around an argument if it is a complex expression
-- (anything more than a variable name)
a = rotatespecific moving text (place+1)
b = h ++ a
in b
else
if place == length text then
rotate moving (text !! place)
else
undefined -- you must decide what String to return in this case.
使此功能正常工作后,然后再打开此密封的信封。 ♥️
rotatespecific :: Int -> String -> String rotatespecific moving text = concatMap (rotate moving) text