9 | Cast (SnocList a) (List a) where
13 | Cast (List a) (SnocList a) where
14 | cast xs = Lin <>< xs
16 | %transform "fastConcat"
concat {t = SnocList} {a = String} = fastConcat . cast
20 | asList : SnocList type -> List type
21 | asList = (reverse . cast)
24 | Uninhabited (Lin = x :< xs) where
25 | uninhabited Refl
impossible
28 | Uninhabited (x :< xs = Lin) where
29 | uninhabited Refl
impossible
33 | isLin : SnocList a -> Bool
35 | isLin (sx :< x) = False
39 | isSnoc : SnocList a -> Bool
41 | isSnoc (sx :< x) = True
47 | spanBy : (a -> Maybe b) -> SnocList a -> (SnocList a, SnocList b)
48 | spanBy p [<] = ([<], [<])
49 | spanBy p (xs :< x) = case p x of
51 | let (as, bs) = spanBy p xs in
53 | Nothing => (xs :< x, [<])
56 | Show a => Show (SnocList a) where
57 | show xs = concat ("[< " :: intersperse ", " (show' [] xs) ++ ["]"])
59 | show' : List String -> SnocList a -> List String
61 | show' acc (xs :< x) = show' (show x :: acc) xs
64 | mapImpl : (a -> b) -> SnocList a -> SnocList b
66 | mapImpl f (sx :< x) = (mapImpl f sx) :< (f x)
69 | mapTR' : List b -> (a -> b) -> SnocList a -> SnocList b
70 | mapTR' xs f (sx :< x) = mapTR' (f x :: xs) f sx
71 | mapTR' xs f Lin = Lin <>< xs
75 | mapTR : (a -> b) -> SnocList a -> SnocList b
79 | %transform "tailRecMapSnocList"
SnocList.mapImpl = SnocList.mapTR
81 | public export %inline
82 | Functor SnocList where
86 | Semigroup (SnocList a) where
90 | Monoid (SnocList a) where
94 | Foldable SnocList where
96 | foldr f z (sx :< x) = foldr f (f x z) sx
99 | foldl f z (xs :< x) = f (foldl f z xs) x
102 | null (_ :< _) = False
106 | foldMap f = foldr (\v,acc => f v <+> acc) neutral
109 | Applicative SnocList where
111 | fs <*> xs = concatMap (flip map xs) fs
114 | Monad SnocList where
115 | xs >>= k = concatMap k xs
118 | Traversable SnocList where
119 | traverse _ Lin = pure Lin
120 | traverse f (xs :< x) = [| traverse f xs :< f x |]
123 | Alternative SnocList where
125 | xs <|> ys = xs ++ ys
129 | SnocBiinjective : Biinjective (:<)
130 | SnocBiinjective = MkBiinjective $
\case Refl => (Refl, Refl)
134 | find : (a -> Bool) -> SnocList a -> Maybe a
135 | find p Lin = Nothing
136 | find p (xs :< x) = if p x then Just x else find p xs
143 | data InBounds : (k : Nat) -> (xs : SnocList a) -> Type where
145 | InFirst : InBounds Z (xs :< x)
147 | InLater : InBounds k xs -> InBounds (S k) (xs :< x)
152 | findIndex : (a -> Bool) -> (xs : SnocList a) -> Maybe $
Fin (length xs)
153 | findIndex _ Lin = Nothing
154 | findIndex p (xs :< x) = if p x
156 | else FS <$> findIndex p xs
163 | Zippable SnocList where
164 | zipWith _ [<] _ = [<]
165 | zipWith _ _ [<] = [<]
166 | zipWith f (xs :< x) (ys :< y) = zipWith f xs ys :< f x y
168 | zipWith3 _ [<] _ _ = [<]
169 | zipWith3 _ _ [<] _ = [<]
170 | zipWith3 _ _ _ [<] = [<]
171 | zipWith3 f (xs :< x) (ys :< y) (zs :< z) = zipWith3 f xs ys zs :< f x y z
173 | unzipWith f [<] = ([<], [<])
174 | unzipWith f (xs :< x) = let (bs, cs) = unzipWith f xs
176 | in (bs :< b, cs :< c)
178 | unzipWith3 f [<] = ([<], [<], [<])
179 | unzipWith3 f (xs :< x) = let (bs, cs, ds) = unzipWith3 f xs
181 | in (bs :< b, cs :< c, ds :< d)
190 | appendAssociative : (l, c, r : SnocList a) -> l ++ (c ++ r) = (l ++ c) ++ r
191 | appendAssociative l c [<] = Refl
192 | appendAssociative l c (sx :< _) = rewrite appendAssociative l c sx in Refl
195 | appendLinLeftNeutral : (sx : SnocList a) -> [<] ++ sx = sx
196 | appendLinLeftNeutral [<] = Refl
197 | appendLinLeftNeutral (sx :< _) = rewrite appendLinLeftNeutral sx in Refl
202 | fishAsSnocAppend : (xs : SnocList a) -> (ys : List a) -> xs <>< ys = xs ++ cast ys
203 | fishAsSnocAppend xs [] = Refl
204 | fishAsSnocAppend xs (y :: ys) = do
205 | rewrite fishAsSnocAppend (xs :< y) ys
206 | rewrite fishAsSnocAppend [<y] ys
207 | rewrite appendAssociative xs [<y] (cast ys)
211 | chipsAsListAppend : (xs : SnocList a) -> (ys : List a) -> xs <>> ys = cast xs ++ ys
212 | chipsAsListAppend [<] ys = Refl
213 | chipsAsListAppend (sx :< x) ys = do
214 | rewrite chipsAsListAppend sx (x :: ys)
215 | rewrite chipsAsListAppend sx [x]
216 | rewrite sym $
appendAssociative (cast sx) [x] ys
222 | toListAppend : (sx, sy : SnocList a) -> toList (sx ++ sy) = toList sx ++ toList sy
223 | toListAppend sx [<] = rewrite appendNilRightNeutral $
toList sx in Refl
224 | toListAppend sx (sy :< y) = do
225 | rewrite chipsAsListAppend sy [y]
226 | rewrite appendAssociative (cast sx) (cast sy) [y]
227 | rewrite chipsAsListAppend (sx ++ sy) [y]
228 | rewrite toListAppend sx sy
232 | castListAppend : (xs, ys : List a) -> cast {to=SnocList a} (xs ++ ys) === cast xs ++ cast ys
233 | castListAppend [] ys = rewrite appendLinLeftNeutral $
[<] <>< ys in Refl
234 | castListAppend (x::xs) ys = do
235 | rewrite fishAsSnocAppend [<x] (xs ++ ys)
236 | rewrite castListAppend xs ys
237 | rewrite appendAssociative [<x] (cast xs) (cast ys)
238 | rewrite sym $
fishAsSnocAppend [<x] xs
244 | castToList : (sx : SnocList a) -> cast (toList sx) === sx
245 | castToList [<] = Refl
246 | castToList (sx :< x) = do
247 | rewrite chipsAsListAppend sx [x]
248 | rewrite castListAppend (cast sx) [x]
249 | rewrite castToList sx
253 | toListCast : (xs : List a) -> toList (cast {to=SnocList a} xs) === xs
254 | toListCast [] = Refl
255 | toListCast (x::xs) = do
256 | rewrite fishAsSnocAppend [<x] xs
257 | rewrite toListAppend [<x] (cast xs)
258 | rewrite toListCast xs
264 | cons : a -> SnocList a -> SnocList a
265 | cons x sx = [< x] ++ sx
270 | foldAppend : (f : acc -> a -> acc) -> (init : acc) -> (sx, sy : SnocList a) -> foldl f init (sx ++ sy) = foldl f (foldl f init sx) sy
271 | foldAppend f init sx [<] = Refl
272 | foldAppend f init sx (sy :< x) = rewrite foldAppend f init sx sy in Refl
275 | snocFoldlAsListFoldl : (f : acc -> a -> acc) -> (init : acc) -> (xs : SnocList a) -> foldl f init xs = foldl f init (toList xs)
276 | snocFoldlAsListFoldl f init [<] = Refl
277 | snocFoldlAsListFoldl f init (sx :< x) = do
278 | rewrite chipsAsListAppend sx [x]
279 | rewrite snocFoldlAsListFoldl f init sx
280 | rewrite foldlAppend f init (cast sx) [x]
286 | filterAppend : (f : a -> Bool) -> (sx, sy : SnocList a) -> filter f (sx ++ sy) = filter f sx ++ filter f sy
287 | filterAppend f sx [<] = Refl
288 | filterAppend f sx (sy :< x) with (f x)
289 | _ | False = filterAppend f sx sy
290 | _ | True = rewrite filterAppend f sx sy in Refl
293 | toListFilter : (f : a -> Bool) -> (sx : SnocList a) -> toList (filter f sx) = filter f (toList sx)
294 | toListFilter f [<] = Refl
295 | toListFilter f (sx :< x) = do
296 | rewrite chipsAsListAppend sx [x]
297 | rewrite filterAppend f (cast sx) [x]
298 | rewrite filterStepLemma
299 | rewrite toListFilter f sx
302 | filterStepLemma : toList (filter f (sx :< x)) = toList (filter f sx) ++ filter f [x]
303 | filterStepLemma with (f x)
304 | _ | False = rewrite appendNilRightNeutral $
toList $
filter f sx in Refl
305 | _ | True = rewrite chipsAsListAppend (filter f sx) [x] in Refl
308 | filterCast : (f : a -> Bool) -> (xs : List a) -> filter f (cast {to=SnocList a} xs) = cast (filter f xs)
309 | filterCast f [] = Refl
310 | filterCast f (x::xs) = do
311 | rewrite fishAsSnocAppend [<x] xs
312 | rewrite filterAppend f [<x] (cast xs)
313 | rewrite filterStepLemma
314 | rewrite filterCast f xs
317 | filterStepLemma : cast (filter f (x::xs)) = filter f [<x] ++ cast (filter f xs)
318 | filterStepLemma with (f x)
319 | _ | False = rewrite appendLinLeftNeutral $
[<] <>< filter f xs in Refl
320 | _ | True = rewrite fishAsSnocAppend [<x] (filter f xs) in Refl
325 | mapFusion : (g : b -> c) -> (f : a -> b) -> (sx : SnocList a) -> map g (map f sx) = map (g . f) sx
326 | mapFusion g f [<] = Refl
327 | mapFusion g f (sx :< x) = rewrite mapFusion g f sx in Refl
330 | mapAppend : (f : a -> b) -> (sx, sy : SnocList a) -> map f (sx ++ sy) = map f sx ++ map f sy
331 | mapAppend f sx [<] = Refl
332 | mapAppend f sx (sy :< x) = rewrite mapAppend f sx sy in Refl
335 | toListMap : (f : a -> b) -> (sx : SnocList a) -> toList (map f sx) = map f (toList sx)
336 | toListMap f [<] = Refl
337 | toListMap f (sx :< x) = do
338 | rewrite chipsAsListAppend (map f sx) [f x]
339 | rewrite chipsAsListAppend sx [x]
340 | rewrite mapAppend f (toList sx) [x]
341 | rewrite toListMap f sx
345 | mapCast : (f : a -> b) -> (xs : List a) -> map f (cast {to=SnocList a} xs) = cast (map f xs)
346 | mapCast f [] = Refl
347 | mapCast f (x::xs) = do
348 | rewrite fishAsSnocAppend [<f x] (map f xs)
349 | rewrite fishAsSnocAppend [<x] xs
350 | rewrite mapAppend f [<x] (cast xs)
351 | rewrite mapCast f xs
357 | mapMaybeFusion : (g : b -> Maybe c) -> (f : a -> Maybe b) -> (sx : SnocList a) -> mapMaybe g (mapMaybe f sx) = mapMaybe (f >=> g) sx
358 | mapMaybeFusion g f [<] = Refl
359 | mapMaybeFusion g f (sx :< x) with (f x)
360 | _ | Nothing = mapMaybeFusion g f sx
361 | _ | (Just y) with (g y)
362 | _ | Nothing = mapMaybeFusion g f sx
363 | _ | (Just z) = rewrite mapMaybeFusion g f sx in Refl
366 | mapMaybeAppend : (f : a -> Maybe b) -> (sx, sy : SnocList a) -> mapMaybe f (sx ++ sy) = mapMaybe f sx ++ mapMaybe f sy
367 | mapMaybeAppend f sx [<] = Refl
368 | mapMaybeAppend f sx (sy :< x) with (f x)
369 | _ | Nothing = mapMaybeAppend f sx sy
370 | _ | (Just y) = rewrite mapMaybeAppend f sx sy in Refl
373 | toListMapMaybe : (f : a -> Maybe b) -> (sx : SnocList a) -> toList (mapMaybe f sx) = mapMaybe f (toList sx)
374 | toListMapMaybe f [<] = Refl
375 | toListMapMaybe f (sx :< x) = do
376 | rewrite chipsAsListAppend sx [x]
377 | rewrite mapMaybeAppend f (toList sx) [x]
378 | rewrite mapMaybeStepLemma
379 | rewrite toListMapMaybe f sx
382 | mapMaybeStepLemma : toList (mapMaybe f (sx :< x)) = toList (mapMaybe f sx) ++ mapMaybe f [x]
383 | mapMaybeStepLemma with (f x)
384 | _ | Nothing = rewrite appendNilRightNeutral $
toList $
mapMaybe f sx in Refl
385 | _ | (Just y) = rewrite chipsAsListAppend (mapMaybe f sx) [y] in Refl
388 | mapMaybeCast : (f : a -> Maybe b) -> (xs : List a) -> mapMaybe f (cast {to=SnocList a} xs) = cast (mapMaybe f xs)
389 | mapMaybeCast f [] = Refl
390 | mapMaybeCast f (x::xs) = do
391 | rewrite fishAsSnocAppend [<x] xs
392 | rewrite mapMaybeAppend f [<x] (cast xs)
393 | rewrite mapMaybeStepLemma
394 | rewrite mapMaybeCast f xs
397 | mapMaybeStepLemma : cast (mapMaybe f (x::xs)) = mapMaybe f [<x] ++ cast (mapMaybe f xs)
398 | mapMaybeStepLemma with (f x)
399 | _ | Nothing = rewrite appendLinLeftNeutral $
[<] <>< mapMaybe f xs in Refl
400 | _ | (Just y) = rewrite fishAsSnocAppend [<y] (mapMaybe f xs) in Refl
402 | 0 mapTRIsMap : (f : a -> b) -> (sa : SnocList a) -> mapTR f sa === map f sa
403 | mapTRIsMap f = lemma []
404 | where lemma : (bs : List b)
405 | -> (sa : SnocList a)
406 | -> mapTR' bs f sa === (map f sa <>< bs)
407 | lemma bs Lin = Refl
408 | lemma bs (sx :< x) = lemma (f x :: bs) sx
411 | 0 mapMaybeTRIsMapMaybe : (f : a -> Maybe b)
412 | -> (sa : SnocList a)
413 | -> mapMaybeTR f sa === mapMaybe f sa
414 | mapMaybeTRIsMapMaybe f = lemma []
415 | where lemma : (bs : List b)
416 | -> (sa : SnocList a)
417 | -> mapMaybeAppend bs f sa === (mapMaybe f sa <>< bs)
418 | lemma bs Lin = Refl
419 | lemma bs (sx :< x) with (f x)
420 | lemma bs (sx :< x) | Nothing = lemma bs sx
421 | lemma bs (sx :< x) | Just v = lemma (v :: bs) sx
423 | 0 filterTRIsFilter : (f : a -> Bool)
424 | -> (sa : SnocList a)
425 | -> filterTR f sa === filter f sa
426 | filterTRIsFilter f = lemma []
427 | where lemma : (as : List a)
428 | -> (sa : SnocList a)
429 | -> filterAppend as f sa === (filter f sa <>< as)
430 | lemma as Lin = Refl
431 | lemma as (sx :< x) with (f x)
432 | lemma as (sx :< x) | False = lemma as sx
433 | lemma as (sx :< x) | True = lemma (x :: as) sx
437 | reverseReverseOnto : (l, r : SnocList a) ->
438 | reverse (reverseOnto l r) = reverseOnto r l
439 | reverseReverseOnto _ Lin = Refl
440 | reverseReverseOnto l (sx :< x) = reverseReverseOnto (l :< x) sx
444 | reverseInvolutive : (sx : SnocList a) -> reverse (reverse sx) = sx
445 | reverseInvolutive = reverseReverseOnto Lin
449 | snocReverse : (x : a) -> (l, r : SnocList a) ->
450 | reverseOnto r l :< x = reverseOnto r (reverseOnto [<x] (reverse l))
451 | snocReverse _ Lin _ = Refl
452 | snocReverse x (sy :< y) r
453 | = rewrite snocReverse x sy (r :< y) in
454 | rewrite cong (reverseOnto r . reverse) $
snocReverse x sy [<y] in
455 | rewrite reverseInvolutive (reverseOnto [<x] (reverse sy) :< y) in
460 | snocTailRecAppend : (x : a) -> (l, r : SnocList a) ->
461 | tailRecAppend l (r :< x) = (tailRecAppend l r) :< x
462 | snocTailRecAppend x l r =
463 | rewrite snocReverse x (reverse r) l in
464 | rewrite reverseInvolutive r in
469 | tailRecAppendIsAppend : (sx, sy : SnocList a) -> tailRecAppend sx sy = sx ++ sy
470 | tailRecAppendIsAppend sx Lin = Refl
471 | tailRecAppendIsAppend sx (sy :< y) =
472 | trans (snocTailRecAppend y sx sy) (cong (:< y) $
tailRecAppendIsAppend sx sy)
476 | revOnto : (xs, vs : SnocList a) -> reverseOnto xs vs = xs ++ reverse vs
477 | revOnto _ [<] = Refl
478 | revOnto xs (vs :< v) =
479 | do rewrite revOnto (xs :< v) vs
480 | rewrite sym $
appendAssociative xs [<v] (reverse vs)
481 | rewrite revOnto [<v] vs