Libs.hs:
--TAKE INPUT OF USER CARD DETAILS AND SEPERATE EACH DIGIT AND INTO A LIST
getCard :: Integer -> [Integer]
getCard x
| x <= 0 = []
| otherwise = lst_numb : getCard pre_numb
where
(pre_numb, lst_numb) = x `divMod` 10
--TAKE SEPERATED DIGITS LIST AND REVERSE
cardNumber :: Integer -> [Integer]
cardNumber = reverse . getCard
--DOUBLE EVERY OTHER NUMBER STARTING FROM THE RIGHT (TO THE LEFT OF CHECK NUMBER)
doubleNumber :: [Integer] -> [Integer]
doubleNumber [] = []
--doubleNumber (x:y:xs) = 2*x : y : doubleNumber xs //This is the partially working function for Q2
doubleNumber (x:y:xs)
| validFormat (x:y:xs) == True = 2*x : y : doubleNumber xs
|otherwise = []
--CHECKS ISSUER ID IS VALID & CARD NUMBER IS 16 DIGITS LONG
validFormat :: [Integer] -> Bool
validFormat x
| x == [] = False
| (head x == 3 || head x == 4 || head x == 5 || head x == 6) && length x == 16 = True
| otherwise = False
--ADDITION OF ALL DIGITS INSIDE THE LIST
addNumbers :: [Integer] -> Integer
addNumbers xs = sum xs
--SUBTRACT NINE FROM DOUBBLE DIGIT NUMBERS
subDoubles :: [Integer] -> [Integer]
subDoubles [] = []
subDoubles (x:xs)
| x > 9 = x - 9 : subDoubles xs
| otherwise = x : subDoubles xs
--COMBINED FUNCTION TO VALIDATE A CREDIT CARD NUMBER
validateCard :: Integer -> Bool
validateCard x = compute x `mod` 10 == 0
where
compute :: Integer -> Integer
compute = addNumbers . subDoubles . doubleNumber . cardNumber
--DISPLAY USER MSG IF CARD IS VALID OR NOT
isValid card
| card == True = "This is a valid credit card!"
| otherwise = "This card is invalid"
Main.hs:
main :: IO ()
main = do
putStrLn "Please enter a credit card number:"
input <- getLine
let card = read input :: Integer
isValid . validateCard card
所以这是两个单独的问题,但是关于我的相同代码,所以我将它们一起发布。我有一个Haskell项目,该项目可从用户输入中验证信用卡号(如Libs.hs中所述):
Q1。我可以在ghci中使用带有数字的validateCard函数,它会产生true或false。我希望用户在Main.hs文件中输入一个信用卡号,并得到一个字符串,提示他们输入的内容是有效还是无效,但是,我不知道我是否在我的main中正确调用了validateCard函数。有人可以解释我的方法出了什么问题吗?
Q2。在我的doubleNumber函数中,如果返回的列表为奇数,则函数崩溃(即函数中的注释行)。由于信用卡号是16位数字,因此我创建了一个函数(validFormat),该函数检查列表的格式以确保它是16位数字并具有正确的品牌起始号码。但是,这是在警告我无法通过validateCard验证的卡号,但是如果我在ghci中使用validFormat函数,则对于相同的数字列表,结果将返回True。这与我在函数中设置where块的方式有关吗?
在此使用了一段时间,所以任何建议或建议都将不胜感激。预先谢谢!
编辑:我上传的代码是我正在尝试的代码,但这是我尝试的初始方式,但无法正常工作
[罗宾·齐格蒙德(Robin Zigmond)在他的评论中说过这一点,但您正在寻找getLine
:
getLine :: IO string
从main
开始,您将像这样使用它:
main = do
input <- getLine
您在以下位置混合了优先级规则:
isValid . validateCard card
此解析为
isValid . (validateCard card)
但是那不起作用,因为validateCard card
不是函数。您需要改写其中之一:
isValid . validateCard $ card
isValid $ validateCard card