Haskell Caesar Cypher,我没有得到解释器错误



这是我在这里的第一个帖子:)

我正在尝试学习haskell的基础知识,甚至在我的屏幕上显示一些东西(())但当回事。我正试图实现凯撒的密码,但我不知道为什么我的舞蹈与ordchr不工作。我知道答案很简单,但我发现很难理解GHCI的错误信息。

import Data.Char
cipher :: [char] -> Int -> [char]
cipher [] _ = []
cipher ch n = (chr(( (ord (head ch)) - n) `mod` 26)) : (cipher (tail ch) n)

cipher.hs:4:16:
    Couldn't match expected type `char' with actual type `Char'
      `char' is a rigid type variable bound by
             the type signature for cipher :: [char] -> Int -> [char]
             at cipher.hs:2:11
    In the return type of a call of `chr'
    In the first argument of `(:)', namely
      `(chr (((ord (head ch)) - n) `mod` 26))'
    In the expression:
      (chr (((ord (head ch)) - n) `mod` 26)) : (cipher (tail ch) n)

正如Jeff Burka所说,您需要Char而不是char才能编译代码。

您还可以简化一些括号-使用HLint(它是内置在ide中,如EclipseFP)在这里非常有用:

cipher :: String -> Int -> String
cipher [] _ = []
cipher ch n = chr ((ord (head ch) - n) `mod` 26) : cipher (tail ch) n

您可以通过模式匹配非空输入列表'ch'来简化一点,这样您就不需要显式调用headtail:

cipher (h:t) n = chr ((ord h - n) `mod` 26) : cipher t n

或者只使用map而不显式递归,如下所示。

之后,主要问题是字符值不是从零开始的,所以您需要在应用mod 26之前减去偏移量,然后再次添加偏移量。比如:

cipher2 [] _ = []
cipher2 c n = map shift c
  where 
    a = ord 'A'
    shift ch = chr (((ord ch - a + n) `mod` 26) + a)

(假设我们只关心字符A-Z)。

> cipher2 "ABCDE" 1
"BCDEF"
> cipher2 "ABCDE" 26
"ABCDE"

最新更新