0 | module Data.CheckedEmpty.List.Lazy
2 | import Control.Function
5 | import Data.List.Lazy
9 | import public Language.Implicits.IfUnsolved
16 | data LazyLst : (definitelyNotEmpty : Bool) -> Type -> Type where
17 | Nil : LazyLst False a
18 | (::) : (0 _ : True `IfUnsolved` ine) => (0 _ : True `IfUnsolved` ne) =>
19 | a -> Lazy (LazyLst ine a) -> LazyLst ne a
21 | %name LazyLst
xs, ys, zs
25 | public export %inline
26 | LazyLst0 : Type -> Type
27 | LazyLst0 = LazyLst False
29 | public export %inline
30 | LazyLst1 : Type -> Type
31 | LazyLst1 = LazyLst True
36 | length : LazyLst ne a -> Nat
38 | length (_::xs) = S $
length xs
40 | public export %inline
41 | (.length) : LazyLst ne a -> Nat
42 | xs.length = length xs
45 | (++) : LazyLst nel a -> Lazy (LazyLst ner a) -> LazyLst (nel || ner) a
47 | (x::xs) ++ ys = x :: xs ++ ys
50 | Semigroup (LazyLst ne a) where
51 | xs <+> ys = rewrite sym $
orSameNeutral ne in xs ++ ys
54 | Monoid (LazyLst0 a) where
58 | index' : (xs : LazyLst ne a) -> Fin xs.length -> a
59 | index' (x::_ ) FZ = x
60 | index' (_::xs) (FS i) = index' xs i
62 | public export %inline
63 | index : Fin n -> (xs : LazyLst ne a) -> (0 _ : n = xs.length) => a
64 | index i xs @{Refl} = index' xs i
69 | iterateN : (n : Nat) -> (a -> a) -> a -> LazyLst (n /= 0) a
71 | iterateN (S n) f x = x :: iterateN n f (f x)
74 | tabulateN : (n : Nat) -> (Fin n -> a) -> LazyLst (n /= 0) a
76 | tabulateN (S k) f = f FZ :: tabulateN k (f . FS)
79 | replicate : (n : Nat) -> a -> LazyLst (n /= 0) a
81 | replicate (S k) x = x :: replicate k x
85 | iterate : (a -> Maybe a) -> a -> LazyLst0 a
86 | iterate f x = x :: case f x of
88 | Just y => iterate f y
92 | unfoldr : (b -> Maybe (a, b)) -> b -> LazyLst0 a
93 | unfoldr f c = case f c of
95 | Just (a, n) => a :: unfoldr f n
102 | relaxF : LazyLst ne a -> LazyLst0 a
104 | relaxF (x::xs) = x::xs
106 | public export %inline
107 | relaxT : LazyLst1 a -> LazyLst ne a
108 | relaxT (x::xs) = x::xs
111 | relaxAnd : LazyLst ne a -> LazyLst (ne && nx) a
113 | relaxAnd (x::xs) = x::xs
115 | %transform "relaxF=id"
relaxF {ne} {a} = believe_me (\x => the (LazyLst ne a) x)
116 | %transform "relaxT=id"
relaxT {ne} {a} = believe_me (\x => the (LazyLst ne a) x)
117 | %transform "relaxAnd=id"
relaxAnd {ne} {a} = believe_me (\x => the (LazyLst ne a) x)
122 | strengthen : LazyLst ne a -> Maybe $
LazyLst1 a
123 | strengthen [] = Nothing
124 | strengthen (x::xs) = Just $
x::xs
129 | Functor (LazyLst ne) where
131 | map f (x::xs) = f x :: map f xs
133 | namespace NEHeteroOps
136 | bind : LazyLst nel a -> (a -> LazyLst ner b) -> LazyLst (nel && ner) b
138 | bind wh@(x::xs) f = do
139 | rewrite andCommutative nel ner
140 | let Just nxs = strengthen xs
141 | | Nothing => relaxAnd $
f x
142 | rewrite sym $
orSameNeutral ner
143 | relaxAnd $
f x ++ (assert_smaller wh nxs `bind` f)
145 | public export %inline
146 | bind' : LazyLst nel a -> LazyLst ner b -> LazyLst (nel && ner) b
147 | bind' xs ys = xs `bind` \_ => ys
149 | public export %inline
150 | join' : LazyLst nel (LazyLst ner a) -> LazyLst (nel && ner) a
151 | join' xs = xs `bind` id
153 | public export %inline
154 | ap : LazyLst nel (a -> b) -> LazyLst ner a -> LazyLst (nel && ner) b
155 | ap xs ys = xs `bind` (<$> ys)
157 | public export %inline
158 | Applicative (LazyLst ne) where
160 | xs <*> ys = rewrite sym $
andSameNeutral ne in xs `ap` ys
162 | public export %inline
163 | Alternative LazyLst0 where
167 | public export %inline
168 | Monad (LazyLst ne) where
169 | xs >>= f = rewrite sym $
andSameNeutral ne in xs `bind` f
174 | foldrLazy : (op : a -> Lazy b -> b) -> (init : Lazy b) -> LazyLst ne a -> b
175 | foldrLazy _ init [] = init
176 | foldrLazy op init (x::xs) = x `op` foldrLazy op init xs
179 | Foldable (LazyLst ne) where
181 | foldr c n (x::xs) = c x (foldr c n xs)
184 | foldl f q (x::xs) = foldl f (f q x) xs
187 | null (_::_) = False
189 | foldlM op init [] = pure init
190 | foldlM op init (x::xs) = op init x >>= \next => foldlM op next xs
193 | toList (x::xs) = x :: toList xs
195 | foldMap f = foldl (\acc, elem => acc <+> f elem) neutral
198 | foldl1 : (a -> a -> a) -> LazyLst1 a -> a
199 | foldl1 f (x::xs) = foldl f x xs
202 | foldr1 : (a -> Lazy a -> a) -> LazyLst1 a -> a
204 | foldr1 op (x::xs@(y::ys)) = op x $
foldr1 op $
assert_smaller xs (y::ys)
207 | traverse_ : Monad m => (a -> m b) -> LazyLst ne a -> m Unit
208 | traverse_ f = foldrLazy ((>>) . ignore . f) (pure ())
210 | public export %inline
211 | for_ : Monad m => LazyLst ne a -> (a -> m b) -> m Unit
212 | for_ = flip Lazy.traverse_
214 | public export %inline
215 | sequence_ : Monad m => LazyLst ne (m a) -> m Unit
216 | sequence_ = Lazy.traverse_ id
221 | head : LazyLst1 a -> a
225 | head' : LazyLst ne a -> Maybe a
226 | head' = map head . strengthen
229 | tail : LazyLst1 a -> LazyLst0 a
230 | tail (_::xs) = relaxF xs
233 | tail' : LazyLst ne a -> Maybe $
LazyLst0 a
234 | tail' = map tail . strengthen
237 | last : LazyLst1 a -> a
239 | last wh@(_::(y::ys)) = last $
assert_smaller wh $
y::ys
242 | last' : LazyLst ne a -> Maybe a
243 | last' = map last . strengthen
246 | init : LazyLst1 a -> LazyLst0 a
248 | init wh@(x::(y::ys)) = x :: init (assert_smaller wh $
y::ys)
251 | init' : LazyLst ne a -> Maybe $
LazyLst0 a
252 | init' = map init . strengthen
256 | tails : LazyLst ne a -> LazyLst1 $
LazyLst0 a
258 | tails xxs@(x::xs) = relaxF xxs :: tails (assert_smaller xxs xs)
262 | tails1 : LazyLst ne a -> LazyLst ne $
LazyLst1 a
264 | tails1 xxs@(x::xs) = (x::xs) :: case strengthen xs of
266 | Just xs' => relaxF $
tails1 $
assert_smaller xxs xs'
270 | inits : LazyLst ne a -> LazyLst1 $
LazyLst0 a
272 | inits (x::xs) = [] :: ((x::) <$> inits xs)
276 | inits1 : LazyLst ne a -> LazyLst ne $
LazyLst1 a
278 | inits1 (x::xs) = [x] :: ((x::) <$> inits1 xs)
283 | take : (n : Nat) -> LazyLst ne a -> LazyLst (ne && n /= 0) a
284 | take Z _ = rewrite andFalseFalse ne in []
286 | take (S k) (x::xs) = x :: take k xs
289 | drop : (n : Nat) -> LazyLst ne a -> LazyLst0 a
290 | drop Z xs = relaxF xs
292 | drop (S n) (_::xs) = drop n $
relaxF xs
295 | takeWhile : (a -> Bool) -> LazyLst ne a -> LazyLst0 a
296 | takeWhile p [] = []
297 | takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
300 | dropWhile : (a -> Bool) -> LazyLst ne a -> LazyLst0 a
301 | dropWhile p [] = []
302 | dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
307 | Zippable (LazyLst ne) where
308 | zipWith _ [] _ = []
309 | zipWith _ _ [] = []
310 | zipWith f xxs@((x::xs) @{_} @{ine}) (y::ys) =
311 | (f x y :: zipWith f (assert_smaller xxs $
relaxF xs) (relaxF ys)) @{%search} @{ine}
313 | zipWith3 _ [] _ _ = []
314 | zipWith3 _ _ [] _ = []
315 | zipWith3 _ _ _ [] = []
316 | zipWith3 f xxs@((x::xs) @{_} @{ine}) (y::ys) (z::zs) =
317 | (f x y z :: zipWith3 f (assert_smaller xxs $
relaxF xs) (relaxF ys) (relaxF zs)) @{%search} @{ine}
319 | unzipWith f xs = (xs <&> fst . f, xs <&> snd . f)
320 | unzipWith3 f xs = (xs <&> fst . f, xs <&> fst . snd . f, xs <&> snd . snd . f)
323 | zipWithStream : (a -> b -> c) -> Stream a -> LazyLst ne b -> LazyLst ne c
324 | zipWithStream _ _ [] = []
325 | zipWithStream f (x::xs) (y::ys) = f x y :: zipWithStream f xs ys
327 | public export %inline
328 | zipStream : Stream a -> LazyLst ne b -> LazyLst ne (a, b)
329 | zipStream = zipWithStream (,)
334 | filter : (a -> Bool) -> LazyLst ne a -> LazyLst0 a
336 | filter f (x::xs) = if f x then x :: filter f xs else filter f xs
339 | mapMaybe : (a -> Maybe b) -> LazyLst ne a -> LazyLst0 b
341 | mapMaybe f (x::xs) = case f x of
342 | Just y => y :: mapMaybe f xs
343 | Nothing => mapMaybe f xs
350 | fromFoldable : Foldable f => f a -> LazyLst0 a
351 | fromFoldable = foldr (\x, xs => x :: xs) []
356 | fromList : (xs : List a) -> LazyLst (not $
null xs) a
358 | fromList (x::xs) = x :: fromList xs
361 | Cast (List a) (LazyLst0 a) where
362 | cast xs = relaxF $
fromList xs
367 | fromLazyList : (xs : LazyList a) -> LazyLst (not $
null xs) a
368 | fromLazyList [] = []
369 | fromLazyList (x::xs) = x :: fromLazyList xs
372 | Cast (LazyList a) (LazyLst0 a) where
373 | cast xs = relaxF $
fromLazyList xs
376 | toLazyList : LazyLst ne a -> LazyList a
378 | toLazyList (x::xs) = x :: toLazyList xs
381 | Cast (LazyLst ne a) (LazyList a) where
388 | fromStream : Stream a -> LazyLst1 a
389 | fromStream $
x::xs = x :: fromStream xs
394 | public export %inline
395 | rangeFromTo : Range a => a -> a -> LazyLst0 a
396 | rangeFromTo l r = relaxF $
fromList $
rangeFromTo l r
399 | public export %inline
400 | rangeFromThenTo : Range a => a -> a -> a -> LazyLst0 a
401 | rangeFromThenTo x y z = relaxF $
fromList $
rangeFromThenTo x y z
404 | public export %inline
405 | rangeFrom : Range a => (0 _ : IfUnsolved ne True) => a -> LazyLst ne a
406 | rangeFrom = relaxT . fromStream . rangeFrom
409 | public export %inline
410 | rangeFromThen : Range a => (0 _ : IfUnsolved ne True) => a -> a -> LazyLst ne a
411 | rangeFromThen = relaxT .: fromStream .: rangeFromThen
416 | Show a => Show (LazyLst ne a) where
417 | show = show . toList
420 | [DoNotEval] Show a => Show (LazyLst ne a) where
422 | show (x::_) = "\{show x} :: <lazy>"
429 | {0 xs : LazyLst _ _} -> {0 uns0 : _} -> {0 uns1 : _} ->
430 | Uninhabited ([] = (::) @{uns0} @{uns1} x xs) where
431 | uninhabited Refl
impossible
434 | {0 xs : LazyLst _ _} -> {0 uns0 : _} -> {0 uns1 : _} ->
435 | Uninhabited ((::) @{uns0} @{uns1} x xs = []) where
436 | uninhabited Refl
impossible
440 | {0 xs : LazyLst _ _} ->
441 | {0 unsL0 : _} -> {0 unsL1 : _} ->
442 | {0 unsR0 : _} -> {0 unsR1 : _} ->
443 | Either (Uninhabited $
x === y) (Uninhabited $
xs === ys) =>
444 | Uninhabited ((::) @{unsL0} @{unsL1} x xs === (::) @{unsR0} @{unsR1} y ys) where
445 | uninhabited @{Left z} Refl = uninhabited @{z} Refl
446 | uninhabited @{Right z} Refl = uninhabited @{z} Refl
451 | Biinjective (with CheckedEmpty.List.Lazy.(::) \x, y => x :: y) where
452 | biinjective Refl = (Refl, Refl)
455 | mapFusion : (g : b -> c) -> (f : a -> b) -> (xs : LazyLst ne a) -> map g (map f xs) = map (g . f) xs
456 | mapFusion g f [] = Refl
457 | mapFusion g f (x::xs) = rewrite mapFusion g f xs in Refl
460 | mapExt : (xs : LazyLst ne _) -> ((x : _) -> f x = g x) -> map f xs = map g xs
462 | mapExt (x::xs) fg = rewrite fg x in cong (g x ::) $
mapExt _ fg