Validate International Securities Identification Number: Difference between revisions

→‎{{header|Haskell}}: Tidied the second variant
(→‎{{header|Haskell}}: Tidied the second variant)
Line 1,451:
FR0000988040 is valid</pre>
 
Or, making alternative choices from the standard libraries:
<lang haskell>import qualified Data.Map as M
import Data.Bifunctor (first)
import Data.Maybe (fromMaybe)
 
validISIN, isinPattern, luhn :: String -> Bool
validISIN = (&&) <$>. isinPattern <*> (luhn . (show =<<) . stringInts)
 
isinPattern s =
12 == length s &&
all (`elem` (capitals ++ digits)) ml && head r `elem` digits
let [l, m, r] = bites [2, 9, 1] s
in all (`elem` (capitals ++ digits)) lm && head r `elem` digits
where
all (`elem` (capitals ++ digits)) m && head r `elem` digits
let [l, m, r] = bites [2, 9, 1] s
 
luhn x = 0 == rem (s1 + s2) 10
where
let odd = [(: []), const []]
odds = even[(: =[]), reverseconst odd[]]
stream fevens = concat $ zipWith ($) (cycle f) (stringInts $ reverse x)odds
stream f = concat $ zipWith ($) (cycle f) (stringInts $ reverse x)
s1 = sum (stream oddodds)
s2 = sum $ sum . stringInts . show . (2 *) <$> stream evenevens
in rem (s1 + s2) 10 == 0
 
charMap :: M.Map Char Int
Line 1,476 ⟶ 1,478:
 
stringInts :: String -> [Int]
stringInts = fromMaybe [] . sequence . fmaptraverse (`M.lookup` charMap)
 
bites :: [Int] -> [a] -> [[a]]
bites ns xs =
(reverse . fst) $
foldr (\x (a, r) -> first (: a) (splitAt x r)) ([], xs) (reverse ns)
foldr
(\x (a, r) ->
let (b, r_) = splitAt x r
in (b : a, r_))
([], xs)
(reverse ns)
 
capitals, digits :: String
9,655

edits