如何在Haskell的另一个函数中将函数的结果用作变量?

Joe*_*nge 0 haskell

我正在尝试学习如何使用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))
Run Code Online (Sandbox Code Playgroud)

但是我无法编译它,因为它仍然给我同样的错误消息:

parse error (possibly incorrect indentation or mismatched brackets)
   |
28 |                     result ++ rotate (moving (text !! place))
   |                                                              ^
Run Code Online (Sandbox Code Playgroud)

But I can't see what's wrong with my syntax. I first thought it had something to do with using a Char as parameter for my function but I was wrong because text !! place should give a char and not a [char]. So what's wrong with what I'm doing?

After some edit I got this, but it still doesn't work:

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 ()
Run Code Online (Sandbox Code Playgroud)

luq*_*qui 5

眼前的问题是每个人都if必须有一个else。最后您会遇到解析错误,因为解析器期望更多,即elsefor if place == length text

解决此问题时,您会遇到更多问题,因为您将Haskell当作命令式语言对待,而这并不是她喜欢被对待的方式。好像在想

result ++ newstuff
Run Code Online (Sandbox Code Playgroud)

会突变result,并添加newstuff到末尾。但是Haskell不会变异。而是,此表达式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]
Run Code Online (Sandbox Code Playgroud)

rotatespecific必须返回旋转后的字符串,而不是尝试将其变异为存在。函数进行通信的唯一方法是返回从其参数计算得出的结果-它们可能不会操纵任何“全局”状态,例如result。返回的函数()保证是无用的。

rotatespecific :: Int -> String -> Int -> String
Run Code Online (Sandbox Code Playgroud)

删除result“全局变量”(这并不意味着您认为的意思),并专注于rotatespecific以其返回旋转字符串的方式进行定义。

我还建议注释掉maincaesar现在直到您rotatespecific编译和工作,当你在测试它ghci