on ea77dcf help sign in
elk/src/Data/Index.hs
100 lines 1.8 kB history raw
1module Data.Index
2 ( ZeroBased
3 , first
4 , second
5 , third
6 , toOneBased
7 , indexedMap
8 , indexedTraverse
9 , VerifiedList(..)
10 , indexedZipWith
11 , indexedZipWithA
12 )
13 where
18-- ZERO BASED
21newtype ZeroBased =
22 ZeroBased Int
25first :: ZeroBased
26first =
27 ZeroBased 0
30second :: ZeroBased
31second =
32 ZeroBased 1
35third :: ZeroBased
36third =
37 ZeroBased 2
41-- ONE BASED
44toOneBased :: ZeroBased -> Int
45toOneBased (ZeroBased index) =
46 index + 1
50-- INDEXED MAP
53{-# INLINE indexedMap #-}
54indexedMap :: (ZeroBased -> a -> b) -> [a] -> [b]
55indexedMap func list =
56 zipWith func (map ZeroBased [0 .. length list]) list
59{-# INLINE indexedTraverse #-}
60indexedTraverse :: (Applicative f) => (ZeroBased -> a -> f b) -> [a] -> f [b]
61indexedTraverse func list =
62 sequenceA (indexedMap func list)
66-- VERIFIED/INDEXED ZIP
69data VerifiedList a
70 = LengthMatch [a]
71 | LengthMismatch Int Int
74indexedZipWith :: (ZeroBased -> a -> b -> c) -> [a] -> [b] -> VerifiedList c
75indexedZipWith func listX listY =
76 indexedZipWithHelp func 0 listX listY []
79indexedZipWithHelp :: (ZeroBased -> a -> b -> c) -> Int -> [a] -> [b] -> [c] -> VerifiedList c
80indexedZipWithHelp func index listX listY revListZ =
81 case (listX, listY) of
82 ([], []) ->
83 LengthMatch (reverse revListZ)
85 (x:xs, y:ys) ->
86 indexedZipWithHelp func (index + 1) xs ys $
87 func (ZeroBased index) x y : revListZ
89 (_, _) ->
90 LengthMismatch (index + length listX) (index + length listY)
93indexedZipWithA :: (Applicative f) => (ZeroBased -> a -> b -> f c) -> [a] -> [b] -> f (VerifiedList c)
94indexedZipWithA func listX listY =
95 case indexedZipWith func listX listY of
96 LengthMatch list ->
97 LengthMatch <$> sequenceA list
99 LengthMismatch x y ->
100 pure (LengthMismatch x y)