是否可以在haskell中存储已删除的值

时间:2018-04-20 00:15:22

标签: haskell

您好我是haskell的新手,我只是想知道是否可以存储已删除的值:

这是我的代码

input :: Integer -> String
input x = checklength $ intolist x

intolist 0 = []
intolist x = intolist (x `div` 10) ++ [x `mod` 10] 

checklength x = if length(x) >= 13 && length(x) <= 16 then doubleall 
(init(x)) else "Not valid length of credit card number" 

doubleall x = finalcheck $ final $ double (reverse (x))

double x = case x of
[]   -> []
[x]  -> if (x*2 < 10) then [x*2] else [x*2 `div` 10 + x*2 `mod` 10]
x:y:xs -> (if (x*2 < 10) then [x*2] else [x*2 `div` 10 + x*2 `mod` 10]) ++ 
y:double xs

final x = (sum x) * 9

finalcheck x = if (x `mod` 10 == ...... ) then "True" else "False"  

我的代码基本上将输入作为整数(例如987564736264535)。然后将此整数变为数字列表,如[9,8,7..5]。然后它检查长度必须在13到16位之间。如果没有,您会收到错误声明。如果数字在所需数量之间,它将进入doubeall函数并使用(init)删除最后一个数字。 删除的数字为5 ,其中数字会翻倍并反转列表顺序。然后它将数字加在一起并且乘以9。我已经完成的最后一步是将已经被加在一起的数字的最后一位数乘以9.然后让我们举例说让我得到456然后我使用mod 10取最后一个数字是6. **现在这里是我遇到的问题,我想检查这个6是否等于我在checklength函数中删除的相同数字用过init。所以在checklength函数中我删除了数字5 **

由于

1 个答案:

答案 0 :(得分:2)

删除数据后,您无法再次访问它。您需要一个功能来保留您正在剥离的最终格式。

由于订单(大部分)无关紧要,请考虑:

validate :: Integer -> Bool
validate x = let digits = toDigits x
             in  if   checkLength digits
                 then doesMatch . splitCheckdigit $ digits
                 else False
  where
  toDigits 0 = [0]
  toDigits x = go x
    where
    go 0 = []
    go x = let (d, m) = x `divMod` 10
           in  m : toDigits d
  -- reverses order
  checkLength x = let l = length x
                  in  13 <= l && l <= 16
  splitCheckdigit (checkdigit:rest) = (checkdigit, rest)
  -- remember we reversed in toDigits, so the *first* digit is the checkdigit!
  doesMatch (checkdigit, rest) = let total    = (*9) . sum . reduce $ rest
                                     shouldBe = total `mod` 10
                                 in  checkdigit == shouldBe
    where
    reduce (x:y:xs) = (sum . toDigits $ x) : y : reduce xs
    reduce [x]      = [sum . toDigits $ x]
    reduce []       = []
    -- note how @toDigits@ is reused here rather than redefined.

如果您更喜欢箭头,validate可以写成:

toDigits >>> ((doesMatch <<< splitCheckdigit) &&& checkLength) >>> uncurry (&&)