Other Elm solutions.
module PhoneNumber exposing (getNumber)
subscriberNumber : Int -> Bool
subscriberNumber n =
List.member n <| List.range 2 9
parse10Digits : List Int -> Maybe String
parse10Digits digits =
let
subscriberN : List Int -> Bool
subscriberN ns =
case ns of
h :: _ ->
subscriberNumber h
[] ->
False
validArea =
subscriberN digits
validLocal =
subscriberN <| List.drop 3 digits
toStr digitL =
String.concat <| List.map String.fromInt digitL
in
if validArea && validLocal then
Just <| toStr digits
else
Nothing
getNumber : String -> Maybe String
getNumber phoneNumber =
let
parseChar c =
String.toInt <| String.fromList [ c ]
digits =
phoneNumber
|> String.toList
|> List.filterMap parseChar
in
if List.length digits == 11 then
case digits of
1 :: remaining ->
parse10Digits remaining
_ ->
Nothing
else if List.length digits == 10 then
parse10Digits digits
else
Nothing
Other Roc solutions.
module [clean]
clean : Str -> Result Str _
clean = \phoneNumber ->
phoneNumber
|> Str.toUtf8
|> List.keepIf \c -> c >= '0' && c <= '9'
|> validateLength
|> Result.try validateAreaCode
|> Result.try validateExchangeCode
|> Result.try Str.fromUtf8
validateAreaCode : List U8 -> Result (List U8) _
validateAreaCode = \phoneNumberBytes ->
when phoneNumberBytes is
[head, ..] if head >= '2' && head <= '9' -> Ok phoneNumberBytes
_ ->
Err Invalid
validateExchangeCode : List U8 -> Result (List U8) _
validateExchangeCode = \phoneNumberBytes ->
exchangeCode = List.get phoneNumberBytes 3
when exchangeCode is
Ok value if value >= '2' && value <= '9' -> Ok phoneNumberBytes
_ -> Err Invalid
validateLength : List U8 -> Result (List U8) _
validateLength = \phoneNumberBytes ->
len = List.len phoneNumberBytes
if len == 10 then
Ok phoneNumberBytes
else if len == 11 then
when phoneNumberBytes is
[first, .. as rest] if first == '1' -> Ok rest
_ -> Err Invalid
else
Err Invalid