Validate International Securities Identification Number: Difference between revisions

m
Line 1,485:
 
Or, making alternative choices from the standard libraries:
<lang haskell>import qualified Data.Map asBifunctor M(first)
import qualified Data.BifunctorMap as (first)M
import Data.Maybe (fromMaybe)
 
-------------------- VALID ISIN STRING -------------------
validISIN, isinPattern, luhn :: String -> Bool
validISIN = (&&) . isinPattern <*> (luhn . (show =<<) . stringInts)
 
validISIN :: String -> Bool
validISIN =
(&&) . isinPattern
validISIN = (&&) . isinPattern <*> (luhn . (show =<<) . stringInts)
 
validISIN, isinPattern, luhn :: String -> Bool
isinPattern s =
12 == length s &&
&& all (`elem` capitals) l &&
&& all (`elem` (capitals ++ digits)) m && head r `elem` digits
&& head r `elem` digits
where
[l, m, r] = bites [2, 9, 1] s
 
luhn :: String -> Bool
luhn x = 0 == rem (s1 + s2) 10
where
odds = [(: []), const []]
evens = reverse odds
stream f =
stream f = concat $ zipWith ($) (cycle f) (stringInts $ reverse x)
concat $
zipWith
($)
(cycle f)
stream f = concat $ zipWith ($) (cycle f) (stringInts $ reverse x)
s1 = sum (stream odds)
s2 =
s2 = sum $ sum . stringInts . show . (2 *) <$> stream evens
sum $
sum . stringInts . show
s2 = sum $ sum . stringInts . show . (2 *) <$> stream evens
 
charMap :: M.Map Char Int
charMap = M.fromList $ zip (digits ++<> capitals) [0 ..]
 
stringInts :: String -> [Int]
Line 1,516 ⟶ 1,531:
bites ns xs =
(reverse . fst) $
foldr
foldr (\x (a, r) -> first (: a) (splitAt x r)) ([], xs) (reverse ns)
([], xs)
(reverse ns)
 
capitals, digits :: String
capitals = ['A' .. 'Z']
 
digits = ['0' .. '9']
 
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_
(print . ((,) <*> validISIN))
[ "US0378331005",
, "US0373831005",
, "U50378331005",
, "US03378331005",
, "AU0000XVGZA3",
, "AU0000VXGZA3",
, "FR0000988040"
]</lang>
{{Out}}
9,655

edits