我编写了以下 Haskell 程序,其目的是像凯撒密码一样运行:
1 import System.IO
2 import System.Environment
3 import System.Exit
4 import Data.Char
5
6 shiftRight :: Int -> Char -> Char
7 shiftRight shift char = do
8 if isAsciiLower char
9 then if (toEnum (fromEnum char + shift) :: Char) > 'z'
10 then shiftRight (shift - 26) char
11 else toEnum (fromEnum char + shift) :: Char
12 else if isAsciiUpper char
13 then if (toEnum (fromEnum char + shift) :: Char) > 'Z'
14 then shiftRight (shift - 26) char
15 else toEnum (fromEnum char + shift) :: Char
16 else char
17
18 shiftLeft :: Int -> Char -> Char
19 shiftLeft shift char = do
20 if isAsciiLower char
21 then if (toEnum (fromEnum char - shift) :: Char) < 'a'
22 then shiftLeft (shift + 26) char
23 else toEnum (fromEnum char - shift) :: Char
24 else if isAsciiUpper char
25 then if (toEnum (fromEnum char - shift) :: Char) < 'A'
26 then shiftLeft (shift + 26) char
27 else toEnum (fromEnum char - shift) :: Char
28 else char
29
30 main = do
31 args <- getArgs
32 message <- getLine
33 case args of
34 [aString, aInt] ->
35 if aString == "-encode"
36 -- `read` converts aInt from string to int
37 -- `map` is used to apply `shiftRight` to each char in the string `message`
38 then putStrLn $ show $ map (shiftRight $ read $ aInt) message
39 else
40 if aString == "-decode"
41 then putStrLn $ show $ map (shiftLeft $ read $ aInt) message
42 else do
43 putStrLn ("Second argument should be either '-decode' or '-encode'!")
44 exitFailure
45 _ -> do
46 progName <- getProgName
47 putStrLn ("Usage: " ++ progName ++ " [-encode|-decode] [0-9]")
48 exitFailure
我的ghc
版本如下:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5
我在macos(Catalina)上编译Haskell:
$ ghc Prog1d.hs -o Prog1d
Loaded package environment from $HOME/.ghc/x86_64-darwin-8.6.5/environments/default
[1 of 1] Compiling Main ( Prog1d.hs, Prog1d.o )
Linking Prog1d ...
然后我运行我的代码:
$ echo "ABCXYZabcxyz" | ./Prog1d -encode 1
"BCDYZAbcdyza"
$ echo "ABCXYZabcxyz" | ./Prog1d -encode 2
"CDEZABcdezab"
$ echo "ABCXYZabcxyz" | ./Prog1d -encode 4
"EFGBCDefgbcd"
$ echo "ABCXYZabcxyz" | ./Prog1d -encode 100
"WXYTUVwxytuv"
$ echo "ABCXYZabcxyz" | ./Prog1d -decode 1
Prog1d: Prelude.chr: bad argument: (-14)
$ echo "ABCXYZabcxyz" | ./Prog1d -decode 2
Prog1d: Prelude.chr: bad argument: (-15)
$ echo "ABCXYZabcxyz" | ./Prog1d -decode 4
Prog1d: Prelude.chr: bad argument: (-17)
$ echo "ABCXYZabcxyz" | ./Prog1d -decode 100
Prog1d: Prelude.chr: bad argument: (-35)
为什么我会得到Prelude.chr: bad argument
?是什么原因造成的,我能做些什么来解决这个问题?
我读过其他人遇到此错误,但在他们的情况下,删除*.hi
文件解决了问题。我已删除Prog1d.hi
(以及Prog1d.o
and Prog1d
),但没有效果。我觉得这可能是由我的代码中的某些内容引起的,可能是第 41 行:
then putStrLn $ show $ map (shiftLeft $ read $ aInt) message
但是这条线就像第 38 行一样,它适用于-encode
用例。我一定遗漏了一些明显的东西。
我是Haskell的新手,所以请帮助我。我主要习惯于用 C++、python、Java 等命令式语言编写代码,还不熟悉 Haskell 和其他函数式语言的思想和语法。
感谢您阅读本文!