这是我在这里的第一个帖子:)
我正在尝试学习haskell的基础知识,甚至在我的屏幕上显示一些东西(())但当回事。我正试图实现凯撒的密码,但我不知道为什么我的舞蹈与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)
正如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'来简化一点,这样您就不需要显式调用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"