8 | data SnocVect : Nat -> Type -> Type where
13 | (:<) : (SnocVect n a) -> a -> SnocVect (S n) a
15 | %name SnocVect
sx, sy, sz
19 | (<><) : SnocVect n a -> Vect m a -> SnocVect (n + m) a
20 | sx <>< [] = rewrite plusZeroRightNeutral n in sx
21 | sx <>< ((::) x xs {len}) =
22 | rewrite sym $
plusSuccRightSucc n len in
27 | (<>>) : SnocVect j a -> Vect k a -> Vect (j + k) a
29 | ((:<) sx x {n}) <>> xs =
30 | rewrite plusSuccRightSucc n k in
34 | Cast (SnocVect n a) (Vect n a) where
35 | cast sx = rewrite sym $
plusZeroRightNeutral n in
39 | Cast (Vect n a) (SnocVect n a) where
40 | cast xs = Lin <>< xs
44 | asVect : SnocVect n type -> Vect n type
45 | asVect = (reverse . cast)
48 | Eq a => Eq (SnocVect n a) where
50 | (==) (sx :< x) (sy :< y) = x == y && sx == sy
54 | Ord a => Ord (SnocVect n a) where
55 | compare Lin Lin = EQ
56 | compare (sx :< x) (sy :< y)
57 | = case compare sx sy of
63 | isLin : SnocVect n a -> Bool
65 | isLin (sx :< x) = False
69 | isSnoc : SnocVect n a -> Bool
71 | isSnoc (sx :< x) = True
74 | (++) : (sx : SnocVect j a) -> (sy : SnocVect k a) -> SnocVect (j + k) a
75 | (++) sx Lin = rewrite plusZeroRightNeutral j in sx
76 | (++) sx ((:<) sy y {n}) =
77 | rewrite sym $
plusSuccRightSucc j n in
81 | length : SnocVect n a -> Nat
83 | length (sx :< x) = S $
length sx
86 | lengthCorrect : (sx : SnocVect n a) -> length sx = n
87 | lengthCorrect [<] = Refl
88 | lengthCorrect (sx :< x) = cong S (lengthCorrect sx)
91 | replicate : (k : Nat) -> a -> SnocVect k a
93 | replicate (S k) x = replicate k x :< x
97 | deah : SnocVect (S n) a -> a
102 | liat : SnocVect (S n) a -> SnocVect n a
103 | liat (sx :< x) = sx
106 | Show a => Show (SnocVect n a) where
107 | show sx = concat ("[< " :: intersperse ", " (show' [] sx) ++ ["]"])
109 | show' : Vect j String -> SnocVect k a -> Vect (j + k) String
110 | show' acc Lin = rewrite plusZeroRightNeutral j in acc
111 | show' acc ((:<) xs x {n}) =
112 | rewrite sym $
plusSuccRightSucc j n in
113 | show' (show x :: acc) xs
116 | Functor (SnocVect n) where
118 | map f (sx :< x) = (map f sx) :< (f x)
121 | Zippable (SnocVect k) where
122 | zipWith _ [<] [<] = [<]
123 | zipWith f (sx :< x) (sy :< y) = zipWith f sx sy :< f x y
125 | zipWith3 _ [<] [<] [<] = [<]
126 | zipWith3 f (sx :< x) (sy :< y) (sz :< z) = zipWith3 f sx sy sz :< f x y z
128 | unzipWith f [<] = ([<], [<])
129 | unzipWith f (sx :< x) = let (b, c) = f x
130 | (sb, sc) = unzipWith f sx in
133 | unzipWith3 f [<] = ([<], [<], [<])
134 | unzipWith3 f (sx :< x) = let (b, c, d) = f x
135 | (sb, sc, sd) = unzipWith3 f sx in
136 | (sb :< b, sc :< c, sd :< d)
139 | Semigroup a => Semigroup (SnocVect n a) where
140 | (<+>) = zipWith (<+>)
143 | {k : Nat} -> Monoid a => Monoid (SnocVect k a) where
144 | neutral = replicate k neutral
147 | Foldable (SnocVect n) where
148 | foldr f z = foldr f z . (<>> [])
151 | foldl f z (xs:<x) = f (foldl f z xs) x
154 | null (_ :< _) = False
156 | toList = toList . (<>> [])
158 | foldMap f = foldl (\xs, x => xs <+> f x) neutral
161 | {k : Nat} -> Applicative (SnocVect k) where
163 | fs <*> sx = zipWith apply fs sx
167 | diag : SnocVect len (SnocVect len el) -> SnocVect len el
169 | diag (ssx :< (sx :< x)) = diag (map liat ssx) :< x
174 | {k : Nat} -> Monad (SnocVect k) where
175 | sx >>= f = diag (map f sx)
178 | Traversable (SnocVect k) where
179 | traverse _ Lin = pure Lin
180 | traverse f (xs :< x) = [| traverse f xs :< f x |]
184 | find : (a -> Bool) -> SnocVect k a -> Maybe a
185 | find p Lin = Nothing
186 | find p (xs :< x) = if p x then Just x else find p xs
193 | data InBounds : (k : Nat) -> (xs : SnocVect j a) -> Type where
195 | InFirst : InBounds Z (xs :< x)
197 | InLater : InBounds k xs -> InBounds (S k) (xs :< x)
202 | findIndex : (a -> Bool) -> (sx : SnocVect k a) -> Maybe $
Fin (length sx)
203 | findIndex _ Lin = Nothing
204 | findIndex p (xs :< x) = if p x
206 | else FS <$> findIndex p xs