Skip to main content
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
deleted 112 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

How idiomatic is this Haskell Luhn Algorithm?

Trying to get to grips with Haskell. Any feedback on my first steps, would be appreciated!

The problem is taken from http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbershere.

{-
Given Credit Card number: 49927398716 

• Reverse the digits: 61789372994 
• Sum the odd digits: 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1 
• The even digits: 1, 8, 3, 2, 9 
•  Two times each even digit: 2, 16, 6, 4, 18 
•  Sum the digits of each multiplication: 2, 7, 6, 4, 9 
•  Sum the last: 2 + 7 + 6 + 4 + 9 = 28 = s2
• s1 + s2 = 70 
• which, as it ends in zero, means that 49927398716 passes the Luhn test
-}

import Data.Char

data Validity = Valid | Invalid deriving Eq
type CardNumber = String

luhnCheck :: CardNumber -> Validity
luhnCheck s = 
    let r = revDigits s
        (os,es) = oddsAndEvens r
        s1 = sum os
        s2 = sum $ map sumDigits $ map (*2) es 
    in if (s1 + s2) `mod` 10 == 0 then Valid
       else Invalid

revDigits :: CardNumber -> [Int]
revDigits s = map digitToInt (reverse s)    

oddsAndEvens :: [Int] -> ([Int],[Int])
oddsAndEvens is = 
    let digitsWithIdx = zip is (cycle [1,2])
        odds = map fst $ filter (\d -> (snd d) == 1) digitsWithIdx
        evens = map fst $ filter (\d -> (snd d) == 2) digitsWithIdx
    in (odds,evens)     

sumDigits:: Int -> Int
sumDigits i = sum $ map digitToInt $ show i

test :: Bool
test = let testData = ["49927398716", "49927398717", "1234567812345678","1234567812345670"]
    in  (map luhnCheck testData) == [Valid,Invalid,Invalid,Valid]

How idiomatic is this Haskell Luhn Algorithm?

Trying to get to grips with Haskell. Any feedback on my first steps, would be appreciated!

The problem is taken from http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers

{-
Given Credit Card number: 49927398716 

• Reverse the digits: 61789372994 
• Sum the odd digits: 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1 
• The even digits: 1, 8, 3, 2, 9 
•  Two times each even digit: 2, 16, 6, 4, 18 
•  Sum the digits of each multiplication: 2, 7, 6, 4, 9 
•  Sum the last: 2 + 7 + 6 + 4 + 9 = 28 = s2
• s1 + s2 = 70 
• which, as it ends in zero, means that 49927398716 passes the Luhn test
-}

import Data.Char

data Validity = Valid | Invalid deriving Eq
type CardNumber = String

luhnCheck :: CardNumber -> Validity
luhnCheck s = 
    let r = revDigits s
        (os,es) = oddsAndEvens r
        s1 = sum os
        s2 = sum $ map sumDigits $ map (*2) es 
    in if (s1 + s2) `mod` 10 == 0 then Valid
       else Invalid

revDigits :: CardNumber -> [Int]
revDigits s = map digitToInt (reverse s)    

oddsAndEvens :: [Int] -> ([Int],[Int])
oddsAndEvens is = 
    let digitsWithIdx = zip is (cycle [1,2])
        odds = map fst $ filter (\d -> (snd d) == 1) digitsWithIdx
        evens = map fst $ filter (\d -> (snd d) == 2) digitsWithIdx
    in (odds,evens)     

sumDigits:: Int -> Int
sumDigits i = sum $ map digitToInt $ show i

test :: Bool
test = let testData = ["49927398716", "49927398717", "1234567812345678","1234567812345670"]
    in  (map luhnCheck testData) == [Valid,Invalid,Invalid,Valid]

Haskell Luhn Algorithm

Trying to get to grips with Haskell. The problem is taken from here.

{-
Given Credit Card number: 49927398716 

• Reverse the digits: 61789372994 
• Sum the odd digits: 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1 
• The even digits: 1, 8, 3, 2, 9 
•  Two times each even digit: 2, 16, 6, 4, 18 
•  Sum the digits of each multiplication: 2, 7, 6, 4, 9 
•  Sum the last: 2 + 7 + 6 + 4 + 9 = 28 = s2
• s1 + s2 = 70 
• which, as it ends in zero, means that 49927398716 passes the Luhn test
-}

import Data.Char

data Validity = Valid | Invalid deriving Eq
type CardNumber = String

luhnCheck :: CardNumber -> Validity
luhnCheck s = 
    let r = revDigits s
        (os,es) = oddsAndEvens r
        s1 = sum os
        s2 = sum $ map sumDigits $ map (*2) es 
    in if (s1 + s2) `mod` 10 == 0 then Valid
       else Invalid

revDigits :: CardNumber -> [Int]
revDigits s = map digitToInt (reverse s)    

oddsAndEvens :: [Int] -> ([Int],[Int])
oddsAndEvens is = 
    let digitsWithIdx = zip is (cycle [1,2])
        odds = map fst $ filter (\d -> (snd d) == 1) digitsWithIdx
        evens = map fst $ filter (\d -> (snd d) == 2) digitsWithIdx
    in (odds,evens)     

sumDigits:: Int -> Int
sumDigits i = sum $ map digitToInt $ show i

test :: Bool
test = let testData = ["49927398716", "49927398717", "1234567812345678","1234567812345670"]
    in  (map luhnCheck testData) == [Valid,Invalid,Invalid,Valid]
Source Link
jb77
  • 85
  • 3

How idiomatic is this Haskell Luhn Algorithm?

Trying to get to grips with Haskell. Any feedback on my first steps, would be appreciated!

The problem is taken from http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers

{-
Given Credit Card number: 49927398716 

• Reverse the digits: 61789372994 
• Sum the odd digits: 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1 
• The even digits: 1, 8, 3, 2, 9 
•  Two times each even digit: 2, 16, 6, 4, 18 
•  Sum the digits of each multiplication: 2, 7, 6, 4, 9 
•  Sum the last: 2 + 7 + 6 + 4 + 9 = 28 = s2
• s1 + s2 = 70 
• which, as it ends in zero, means that 49927398716 passes the Luhn test
-}

import Data.Char

data Validity = Valid | Invalid deriving Eq
type CardNumber = String

luhnCheck :: CardNumber -> Validity
luhnCheck s = 
    let r = revDigits s
        (os,es) = oddsAndEvens r
        s1 = sum os
        s2 = sum $ map sumDigits $ map (*2) es 
    in if (s1 + s2) `mod` 10 == 0 then Valid
       else Invalid

revDigits :: CardNumber -> [Int]
revDigits s = map digitToInt (reverse s)    

oddsAndEvens :: [Int] -> ([Int],[Int])
oddsAndEvens is = 
    let digitsWithIdx = zip is (cycle [1,2])
        odds = map fst $ filter (\d -> (snd d) == 1) digitsWithIdx
        evens = map fst $ filter (\d -> (snd d) == 2) digitsWithIdx
    in (odds,evens)     

sumDigits:: Int -> Int
sumDigits i = sum $ map digitToInt $ show i

test :: Bool
test = let testData = ["49927398716", "49927398717", "1234567812345678","1234567812345670"]
    in  (map luhnCheck testData) == [Valid,Invalid,Invalid,Valid]