Haskell Caesar Cypher,我不会得到翻译错误

时间:2014-07-07 22:08:34

标签: haskell

这是我在这里发表的第一篇文章:)

我正在尝试学习haskell的基础知识甚至在我的屏幕上显示的内容(͡°͜ʖ͡°) 不过实话说。我正在尝试实施Caesar的Cipher,但我不知道为什么我与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)

1 个答案:

答案 0 :(得分:7)

正如Jeff Burka所说,您需要Char而不是char来获取要编译的代码。

您还可以简化一些括号 - 使用HLint(内置于像EclipseFP这样的IDE中)非常有用:

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"