4 | %hide Prelude.Types.elem
10 | data SnocVect : Nat -> Type -> Type where
15 | (:<) : (SnocVect n a) -> a -> SnocVect (S n) a
17 | %name SnocVect
sx, sy, sz
24 | (<><) : SnocVect n a -> Vect m a -> SnocVect (n + m) a
25 | sx <>< [] = rewrite plusZeroRightNeutral n in sx
26 | sx <>< ((::) x xs {len}) =
27 | rewrite sym $
plusSuccRightSucc n len in
32 | (<>>) : SnocVect j a -> Vect k a -> Vect (j + k) a
34 | ((:<) sx x {n}) <>> xs =
35 | rewrite plusSuccRightSucc n k in
39 | Cast (SnocVect n a) (Vect n a) where
40 | cast sx = rewrite sym $
plusZeroRightNeutral n in
44 | Cast (Vect n a) (SnocVect n a) where
45 | cast xs = Lin <>< xs
49 | asVect : SnocVect n type -> Vect n type
50 | asVect = (reverse . cast)
53 | Eq a => Eq (SnocVect n a) where
55 | (==) (sx :< x) (sy :< y) = x == y && sx == sy
59 | Ord a => Ord (SnocVect n a) where
60 | compare Lin Lin = EQ
61 | compare (sx :< x) (sy :< y)
62 | = case compare sx sy of
68 | isLin : SnocVect n a -> Bool
70 | isLin (sx :< x) = False
74 | isSnoc : SnocVect n a -> Bool
76 | isSnoc (sx :< x) = True
79 | (++) : (sx : SnocVect j a) -> (sy : SnocVect k a) -> SnocVect (j + k) a
80 | (++) sx Lin = rewrite plusZeroRightNeutral j in sx
81 | (++) sx ((:<) sy y {n}) =
82 | rewrite sym $
plusSuccRightSucc j n in
86 | length : SnocVect n a -> Nat
88 | length (sx :< x) = S $
length sx
91 | lengthCorrect : (sx : SnocVect n a) -> length sx = n
92 | lengthCorrect [<] = Refl
93 | lengthCorrect (sx :< x) = cong S (lengthCorrect sx)
96 | replicate : (k : Nat) -> a -> SnocVect k a
98 | replicate (S k) x = replicate k x :< x
102 | deah : SnocVect (S n) a -> a
107 | liat : SnocVect (S n) a -> SnocVect n a
108 | liat (sx :< x) = sx
111 | Show a => Show (SnocVect n a) where
112 | show sx = concat ("[< " :: intersperse ", " (show' [] sx) ++ ["]"])
114 | show' : Vect j String -> SnocVect k a -> Vect (j + k) String
115 | show' acc Lin = rewrite plusZeroRightNeutral j in acc
116 | show' acc ((:<) xs x {n}) =
117 | rewrite sym $
plusSuccRightSucc j n in
118 | show' (show x :: acc) xs
121 | Functor (SnocVect n) where
123 | map f (sx :< x) = (map f sx) :< (f x)
126 | Zippable (SnocVect k) where
127 | zipWith _ [<] [<] = [<]
128 | zipWith f (sx :< x) (sy :< y) = zipWith f sx sy :< f x y
130 | zipWith3 _ [<] [<] [<] = [<]
131 | zipWith3 f (sx :< x) (sy :< y) (sz :< z) = zipWith3 f sx sy sz :< f x y z
133 | unzipWith f [<] = ([<], [<])
134 | unzipWith f (sx :< x) = let (b, c) = f x
135 | (sb, sc) = unzipWith f sx in
138 | unzipWith3 f [<] = ([<], [<], [<])
139 | unzipWith3 f (sx :< x) = let (b, c, d) = f x
140 | (sb, sc, sd) = unzipWith3 f sx in
141 | (sb :< b, sc :< c, sd :< d)
144 | Semigroup a => Semigroup (SnocVect n a) where
145 | (<+>) = zipWith (<+>)
148 | {k : Nat} -> Monoid a => Monoid (SnocVect k a) where
149 | neutral = replicate k neutral
152 | Foldable (SnocVect n) where
153 | foldr f z = foldr f z . (<>> [])
155 | foldl f z xs = h xs where
156 | h : SnocVect k elem -> acc
158 | h (xs :< x) = f (h xs) x
161 | null (_ :< _) = False
163 | toList = toList . (<>> [])
165 | foldMap f = foldl (\xs, x => xs <+> f x) neutral
168 | {k : Nat} -> Applicative (SnocVect k) where
170 | fs <*> sx = zipWith apply fs sx
174 | diag : SnocVect len (SnocVect len elem) -> SnocVect len elem
176 | diag (ssx :< (sx :< x)) = diag (map liat ssx) :< x
181 | {k : Nat} -> Monad (SnocVect k) where
182 | sx >>= f = diag (map f sx)
185 | Traversable (SnocVect k) where
186 | traverse _ Lin = pure Lin
187 | traverse f (xs :< x) = [| traverse f xs :< f x |]
191 | elem : Eq a => a -> SnocVect k a -> Bool
193 | elem x (sx :< y) = x == y || elem x sx
197 | find : (a -> Bool) -> SnocVect k a -> Maybe a
198 | find p Lin = Nothing
199 | find p (xs :< x) = if p x then Just x else find p xs
206 | data InBounds : (k : Nat) -> (xs : SnocVect j a) -> Type where
208 | InFirst : InBounds Z (xs :< x)
210 | InLater : InBounds k xs -> InBounds (S k) (xs :< x)
215 | findIndex : (a -> Bool) -> (sx : SnocVect k a) -> Maybe $
Fin (length sx)
216 | findIndex _ Lin = Nothing
217 | findIndex p (xs :< x) = if p x
219 | else FS <$> findIndex p xs