Last active
November 15, 2016 22:03
-
-
Save groz/2efeafc7078bec98c47dfd5c5d6256d4 to your computer and use it in GitHub Desktop.
Luhn algorithm for credit card validation in Elm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Html exposing (..) | |
import Html.Events exposing (..) | |
import Html.Attributes exposing (..) | |
-- UI part | |
main = | |
beginnerProgram { model = { creditCardNumber = "", isValid = False } , view = view, update = update } | |
type alias Model = { creditCardNumber: String, isValid: Bool } | |
type Msg = UpdateNumber String | |
update : Msg -> Model -> Model | |
update msg model = | |
case msg of | |
UpdateNumber num -> | |
{ model | creditCardNumber = num, isValid = num |> validate } | |
view : Model -> Html Msg | |
view model = | |
div [] | |
[ input [onInput UpdateNumber, placeholder "Enter credit card..."] [] | |
, text (if model.isValid then " √" else " X") | |
] | |
-- Algorithmic part | |
validate : String -> Bool | |
validate ccNumber = | |
let | |
len = String.length ccNumber | |
getSum digits = digits |> transform |> List.sum | |
validateSum sum = sum % 10 == 0 | |
in | |
len > 12 && len < 20 && ( | |
ccNumber | |
|> toDigits | |
|> Result.map (getSum >> validateSum) | |
|> Result.withDefault False | |
) | |
toDigits : String -> Result String (List Int) | |
toDigits str = | |
str | |
|> String.toList | |
|> List.map (String.fromChar >> String.toInt) | |
|> List.foldr (Result.map2 (::)) (Result.Ok []) | |
transform : List Int -> List Int | |
transform digits = | |
let | |
flatten number = | |
if number > 9 then number - 9 else number | |
doubleOdd idx digit = | |
if idx % 2 /= 0 then flatten (digit * 2) else digit | |
in | |
digits | |
|> List.reverse | |
|> List.indexedMap doubleOdd | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment