这是我在这里发表的第一篇文章:)
我正在尝试学习haskell的基础知识甚至在我的屏幕上显示的内容(͡°͜ʖ͡°)
不过实话说。我正在尝试实施Caesar的Cipher,但我不知道为什么我与ord
和chr
的舞蹈不起作用。我意识到答案很简单,但我发现很难理解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)
答案 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'的模式简化一点,这样您就不需要显式调用head
和tail
:
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"