我是Haskell的新手,我在尝试让这个脚本工作时遇到了问题。此脚本从命令行读取参数,并在单独的文本文件中查找它们。
cat.txt | ./scramble A123456A123456 (in compiler)
输出应该是这样的:
The cat was very sad ...etc.
++++++++++++++++++++
A123456A123456A123456 ...etc.
因此它无限地用“A123456”替换文本文件中的任何内容。
module Main where
import System
import Data.Char (chr, ord, isLower)
import Data.Bits
let2int :: Char -> Int
let2int c = ord c - ord 'a'
int2let :: Int -> Char
int2let n = chr (ord 'a' + n)
shift :: Int -> Char -> Char
shift n c | isLower c = int2let ((let2int c + n) `mod` 26)
| otherwise = c
main = do
arg1 <- getArgs
txt <- getContents
putStr (scramble txt arg1)
scramble :: Int -> String -> String
scramble shift msg =
let ords = map ord msg
shifted = map (+ shift) ords
in map chr shifted
但是,当我尝试编译它时,GHCi会返回错误:
redact.hs:19:26:
Couldn't match expected type 'Int' with actual type '[Char]'
Expected type: Int
Actual type: [String]
In the second argument of 'scramble', namely 'txt'
In the first of 'putStr', namely '<redact txt arg1>'
Failed, module loaded: none.
所以代码:
putStr (scramble txt arg1)
造成了这个问题。 我也尝试过:
arg1:_ <- getArgs
但它无济于事
提前感谢您提供任何帮助,如果您可以改进代码,那就太棒了。
答案 0 :(得分:2)
我可以看到三件事:
您的参数是scramble
main
以错误的方式传递给getContents
。
您还没有在任何地方定义getArgs
。
您未按要求使用getArgs :: IO [String]
。
正如您猜测的那样,您只需要获得第一个参数(arg1:_ <- getArgs
);使用arg1 :: String
确实会得到第一个参数(假设至少有一个,否则会出现错误)。但是,您将拥有Int
,并且需要scramble
,因此您需要String -> Int
类型的函数。
这是我的理解,基于您如何定义{{1}}(似乎类似于Vigenere密码),这与您定义初始问题的方式完全不同。
答案 1 :(得分:1)
试试这对我有用
(keys:_) <- getArgs
是scramble的完整代码