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
176 | leftMost : SnocList a -> Maybe a
177 | leftMost [<] = Nothing
178 | leftMost [<x] = Just x
179 | leftMost (xs :< _) = leftMost xs
186 | Zippable SnocList where
187 | zipWith _ [<] _ = [<]
188 | zipWith _ _ [<] = [<]
189 | zipWith f (xs :< x) (ys :< y) = zipWith f xs ys :< f x y
191 | zipWith3 _ [<] _ _ = [<]
192 | zipWith3 _ _ [<] _ = [<]
193 | zipWith3 _ _ _ [<] = [<]
194 | zipWith3 f (xs :< x) (ys :< y) (zs :< z) = zipWith3 f xs ys zs :< f x y z
196 | unzipWith f [<] = ([<], [<])
197 | unzipWith f (xs :< x) = let (bs, cs) = unzipWith f xs
199 | in (bs :< b, cs :< c)
201 | unzipWith3 f [<] = ([<], [<], [<])
202 | unzipWith3 f (xs :< x) = let (bs, cs, ds) = unzipWith3 f xs
204 | in (bs :< b, cs :< c, ds :< d)
213 | appendAssociative : (l, c, r : SnocList a) -> l ++ (c ++ r) = (l ++ c) ++ r
214 | appendAssociative l c [<] = Refl
215 | appendAssociative l c (sx :< _) = rewrite appendAssociative l c sx in Refl
218 | appendLinLeftNeutral : (sx : SnocList a) -> [<] ++ sx = sx
219 | appendLinLeftNeutral [<] = Refl
220 | appendLinLeftNeutral (sx :< _) = rewrite appendLinLeftNeutral sx in Refl
225 | fishAsSnocAppend : (xs : SnocList a) -> (ys : List a) -> xs <>< ys = xs ++ cast ys
226 | fishAsSnocAppend xs [] = Refl
227 | fishAsSnocAppend xs (y :: ys) = do
228 | rewrite fishAsSnocAppend (xs :< y) ys
229 | rewrite fishAsSnocAppend [<y] ys
230 | rewrite appendAssociative xs [<y] (cast ys)
234 | chipsAsListAppend : (xs : SnocList a) -> (ys : List a) -> xs <>> ys = cast xs ++ ys
235 | chipsAsListAppend [<] ys = Refl
236 | chipsAsListAppend (sx :< x) ys = do
237 | rewrite chipsAsListAppend sx (x :: ys)
238 | rewrite chipsAsListAppend sx [x]
239 | rewrite sym $
appendAssociative (cast sx) [x] ys
245 | toListAppend : (sx, sy : SnocList a) -> toList (sx ++ sy) = toList sx ++ toList sy
246 | toListAppend sx [<] = rewrite appendNilRightNeutral $
toList sx in Refl
247 | toListAppend sx (sy :< y) = do
248 | rewrite chipsAsListAppend sy [y]
249 | rewrite appendAssociative (cast sx) (cast sy) [y]
250 | rewrite chipsAsListAppend (sx ++ sy) [y]
251 | rewrite toListAppend sx sy
255 | castListAppend : (xs, ys : List a) -> cast {to=SnocList a} (xs ++ ys) === cast xs ++ cast ys
256 | castListAppend [] ys = rewrite appendLinLeftNeutral $
[<] <>< ys in Refl
257 | castListAppend (x::xs) ys = do
258 | rewrite fishAsSnocAppend [<x] (xs ++ ys)
259 | rewrite castListAppend xs ys
260 | rewrite appendAssociative [<x] (cast xs) (cast ys)
261 | rewrite sym $
fishAsSnocAppend [<x] xs
267 | castToList : (sx : SnocList a) -> cast (toList sx) === sx
268 | castToList [<] = Refl
269 | castToList (sx :< x) = do
270 | rewrite chipsAsListAppend sx [x]
271 | rewrite castListAppend (cast sx) [x]
272 | rewrite castToList sx
276 | toListCast : (xs : List a) -> toList (cast {to=SnocList a} xs) === xs
277 | toListCast [] = Refl
278 | toListCast (x::xs) = do
279 | rewrite fishAsSnocAppend [<x] xs
280 | rewrite toListAppend [<x] (cast xs)
281 | rewrite toListCast xs
287 | cons : a -> SnocList a -> SnocList a
288 | cons x sx = [< x] ++ sx
293 | foldAppend : (f : acc -> a -> acc) -> (init : acc) -> (sx, sy : SnocList a) -> foldl f init (sx ++ sy) = foldl f (foldl f init sx) sy
294 | foldAppend f init sx [<] = Refl
295 | foldAppend f init sx (sy :< x) = rewrite foldAppend f init sx sy in Refl
298 | snocFoldlAsListFoldl : (f : acc -> a -> acc) -> (init : acc) -> (xs : SnocList a) -> foldl f init xs = foldl f init (toList xs)
299 | snocFoldlAsListFoldl f init [<] = Refl
300 | snocFoldlAsListFoldl f init (sx :< x) = do
301 | rewrite chipsAsListAppend sx [x]
302 | rewrite snocFoldlAsListFoldl f init sx
303 | rewrite foldlAppend f init (cast sx) [x]
309 | filterAppend : (f : a -> Bool) -> (sx, sy : SnocList a) -> filter f (sx ++ sy) = filter f sx ++ filter f sy
310 | filterAppend f sx [<] = Refl
311 | filterAppend f sx (sy :< x) with (f x)
312 | _ | False = filterAppend f sx sy
313 | _ | True = rewrite filterAppend f sx sy in Refl
316 | toListFilter : (f : a -> Bool) -> (sx : SnocList a) -> toList (filter f sx) = filter f (toList sx)
317 | toListFilter f [<] = Refl
318 | toListFilter f (sx :< x) = do
319 | rewrite chipsAsListAppend sx [x]
320 | rewrite filterAppend f (cast sx) [x]
321 | rewrite filterStepLemma
322 | rewrite toListFilter f sx
325 | filterStepLemma : toList (filter f (sx :< x)) = toList (filter f sx) ++ filter f [x]
326 | filterStepLemma with (f x)
327 | _ | False = rewrite appendNilRightNeutral $
toList $
filter f sx in Refl
328 | _ | True = rewrite chipsAsListAppend (filter f sx) [x] in Refl
331 | filterCast : (f : a -> Bool) -> (xs : List a) -> filter f (cast {to=SnocList a} xs) = cast (filter f xs)
332 | filterCast f [] = Refl
333 | filterCast f (x::xs) = do
334 | rewrite fishAsSnocAppend [<x] xs
335 | rewrite filterAppend f [<x] (cast xs)
336 | rewrite filterStepLemma
337 | rewrite filterCast f xs
340 | filterStepLemma : cast (filter f (x::xs)) = filter f [<x] ++ cast (filter f xs)
341 | filterStepLemma with (f x)
342 | _ | False = rewrite appendLinLeftNeutral $
[<] <>< filter f xs in Refl
343 | _ | True = rewrite fishAsSnocAppend [<x] (filter f xs) in Refl
348 | mapFusion : (g : b -> c) -> (f : a -> b) -> (sx : SnocList a) -> map g (map f sx) = map (g . f) sx
349 | mapFusion g f [<] = Refl
350 | mapFusion g f (sx :< x) = rewrite mapFusion g f sx in Refl
353 | mapAppend : (f : a -> b) -> (sx, sy : SnocList a) -> map f (sx ++ sy) = map f sx ++ map f sy
354 | mapAppend f sx [<] = Refl
355 | mapAppend f sx (sy :< x) = rewrite mapAppend f sx sy in Refl
358 | toListMap : (f : a -> b) -> (sx : SnocList a) -> toList (map f sx) = map f (toList sx)
359 | toListMap f [<] = Refl
360 | toListMap f (sx :< x) = do
361 | rewrite chipsAsListAppend (map f sx) [f x]
362 | rewrite chipsAsListAppend sx [x]
363 | rewrite mapAppend f (toList sx) [x]
364 | rewrite toListMap f sx
368 | mapCast : (f : a -> b) -> (xs : List a) -> map f (cast {to=SnocList a} xs) = cast (map f xs)
369 | mapCast f [] = Refl
370 | mapCast f (x::xs) = do
371 | rewrite fishAsSnocAppend [<f x] (map f xs)
372 | rewrite fishAsSnocAppend [<x] xs
373 | rewrite mapAppend f [<x] (cast xs)
374 | rewrite mapCast f xs
380 | mapMaybeFusion : (g : b -> Maybe c) -> (f : a -> Maybe b) -> (sx : SnocList a) -> mapMaybe g (mapMaybe f sx) = mapMaybe (f >=> g) sx
381 | mapMaybeFusion g f [<] = Refl
382 | mapMaybeFusion g f (sx :< x) with (f x)
383 | _ | Nothing = mapMaybeFusion g f sx
384 | _ | (Just y) with (g y)
385 | _ | Nothing = mapMaybeFusion g f sx
386 | _ | (Just z) = rewrite mapMaybeFusion g f sx in Refl
389 | mapMaybeAppend : (f : a -> Maybe b) -> (sx, sy : SnocList a) -> mapMaybe f (sx ++ sy) = mapMaybe f sx ++ mapMaybe f sy
390 | mapMaybeAppend f sx [<] = Refl
391 | mapMaybeAppend f sx (sy :< x) with (f x)
392 | _ | Nothing = mapMaybeAppend f sx sy
393 | _ | (Just y) = rewrite mapMaybeAppend f sx sy in Refl
396 | toListMapMaybe : (f : a -> Maybe b) -> (sx : SnocList a) -> toList (mapMaybe f sx) = mapMaybe f (toList sx)
397 | toListMapMaybe f [<] = Refl
398 | toListMapMaybe f (sx :< x) = do
399 | rewrite chipsAsListAppend sx [x]
400 | rewrite mapMaybeAppend f (toList sx) [x]
401 | rewrite mapMaybeStepLemma
402 | rewrite toListMapMaybe f sx
405 | mapMaybeStepLemma : toList (mapMaybe f (sx :< x)) = toList (mapMaybe f sx) ++ mapMaybe f [x]
406 | mapMaybeStepLemma with (f x)
407 | _ | Nothing = rewrite appendNilRightNeutral $
toList $
mapMaybe f sx in Refl
408 | _ | (Just y) = rewrite chipsAsListAppend (mapMaybe f sx) [y] in Refl
411 | mapMaybeCast : (f : a -> Maybe b) -> (xs : List a) -> mapMaybe f (cast {to=SnocList a} xs) = cast (mapMaybe f xs)
412 | mapMaybeCast f [] = Refl
413 | mapMaybeCast f (x::xs) = do
414 | rewrite fishAsSnocAppend [<x] xs
415 | rewrite mapMaybeAppend f [<x] (cast xs)
416 | rewrite mapMaybeStepLemma
417 | rewrite mapMaybeCast f xs
420 | mapMaybeStepLemma : cast (mapMaybe f (x::xs)) = mapMaybe f [<x] ++ cast (mapMaybe f xs)
421 | mapMaybeStepLemma with (f x)
422 | _ | Nothing = rewrite appendLinLeftNeutral $
[<] <>< mapMaybe f xs in Refl
423 | _ | (Just y) = rewrite fishAsSnocAppend [<y] (mapMaybe f xs) in Refl
425 | 0 mapTRIsMap : (f : a -> b) -> (sa : SnocList a) -> mapTR f sa === map f sa
426 | mapTRIsMap f = lemma []
427 | where lemma : (bs : List b)
428 | -> (sa : SnocList a)
429 | -> mapTR' bs f sa === (map f sa <>< bs)
430 | lemma bs Lin = Refl
431 | lemma bs (sx :< x) = lemma (f x :: bs) sx
434 | 0 mapMaybeTRIsMapMaybe : (f : a -> Maybe b)
435 | -> (sa : SnocList a)
436 | -> mapMaybeTR f sa === mapMaybe f sa
437 | mapMaybeTRIsMapMaybe f = lemma []
438 | where lemma : (bs : List b)
439 | -> (sa : SnocList a)
440 | -> mapMaybeAppend bs f sa === (mapMaybe f sa <>< bs)
441 | lemma bs Lin = Refl
442 | lemma bs (sx :< x) with (f x)
443 | lemma bs (sx :< x) | Nothing = lemma bs sx
444 | lemma bs (sx :< x) | Just v = lemma (v :: bs) sx
446 | 0 filterTRIsFilter : (f : a -> Bool)
447 | -> (sa : SnocList a)
448 | -> filterTR f sa === filter f sa
449 | filterTRIsFilter f = lemma []
450 | where lemma : (as : List a)
451 | -> (sa : SnocList a)
452 | -> filterAppend as f sa === (filter f sa <>< as)
453 | lemma as Lin = Refl
454 | lemma as (sx :< x) with (f x)
455 | lemma as (sx :< x) | False = lemma as sx
456 | lemma as (sx :< x) | True = lemma (x :: as) sx
460 | reverseReverseOnto : (l, r : SnocList a) ->
461 | reverse (reverseOnto l r) = reverseOnto r l
462 | reverseReverseOnto _ Lin = Refl
463 | reverseReverseOnto l (sx :< x) = reverseReverseOnto (l :< x) sx
467 | reverseInvolutive : (sx : SnocList a) -> reverse (reverse sx) = sx
468 | reverseInvolutive = reverseReverseOnto Lin
472 | snocReverse : (x : a) -> (l, r : SnocList a) ->
473 | reverseOnto r l :< x = reverseOnto r (reverseOnto [<x] (reverse l))
474 | snocReverse _ Lin _ = Refl
475 | snocReverse x (sy :< y) r
476 | = rewrite snocReverse x sy (r :< y) in
477 | rewrite cong (reverseOnto r . reverse) $
snocReverse x sy [<y] in
478 | rewrite reverseInvolutive (reverseOnto [<x] (reverse sy) :< y) in
483 | snocTailRecAppend : (x : a) -> (l, r : SnocList a) ->
484 | tailRecAppend l (r :< x) = (tailRecAppend l r) :< x
485 | snocTailRecAppend x l r =
486 | rewrite snocReverse x (reverse r) l in
487 | rewrite reverseInvolutive r in
492 | tailRecAppendIsAppend : (sx, sy : SnocList a) -> tailRecAppend sx sy = sx ++ sy
493 | tailRecAppendIsAppend sx Lin = Refl
494 | tailRecAppendIsAppend sx (sy :< y) =
495 | trans (snocTailRecAppend y sx sy) (cong (:< y) $
tailRecAppendIsAppend sx sy)
499 | revOnto : (xs, vs : SnocList a) -> reverseOnto xs vs = xs ++ reverse vs
500 | revOnto _ [<] = Refl
501 | revOnto xs (vs :< v) =
502 | do rewrite revOnto (xs :< v) vs
503 | rewrite sym $
appendAssociative xs [<v] (reverse vs)
504 | rewrite revOnto [<v] vs