2020-09-19 23:46:46 +03:00
|
|
|
module Data.List.Lazy
|
|
|
|
|
|
|
|
%default total
|
|
|
|
|
|
|
|
-- All functions here are public export
|
|
|
|
-- because their definitions are pretty much the specification.
|
|
|
|
|
|
|
|
public export
|
|
|
|
data LazyList : Type -> Type where
|
|
|
|
Nil : LazyList a
|
2020-09-20 10:56:58 +03:00
|
|
|
(::) : (1 x : a) -> (1 xs : Lazy (LazyList a)) -> LazyList a
|
2020-09-19 23:46:46 +03:00
|
|
|
|
2020-12-18 13:33:56 +03:00
|
|
|
--- Interface implementations ---
|
|
|
|
|
2020-09-19 23:46:46 +03:00
|
|
|
public export
|
|
|
|
Semigroup (LazyList a) where
|
|
|
|
[] <+> ys = ys
|
|
|
|
(x :: xs) <+> ys = x :: (xs <+> ys)
|
|
|
|
|
|
|
|
public export
|
|
|
|
Monoid (LazyList a) where
|
|
|
|
neutral = []
|
|
|
|
|
|
|
|
public export
|
|
|
|
Foldable LazyList where
|
|
|
|
foldr op nil [] = nil
|
|
|
|
foldr op nil (x :: xs) = x `op` foldr op nil xs
|
|
|
|
|
|
|
|
foldl op acc [] = acc
|
|
|
|
foldl op acc (x :: xs) = foldl op (acc `op` x) xs
|
|
|
|
|
|
|
|
public export
|
|
|
|
Functor LazyList where
|
|
|
|
map f [] = []
|
|
|
|
map f (x :: xs) = f x :: map f xs
|
|
|
|
|
|
|
|
public export
|
|
|
|
Applicative LazyList where
|
|
|
|
pure x = [x]
|
|
|
|
fs <*> vs = concatMap (\f => map f vs) fs
|
|
|
|
|
|
|
|
public export
|
|
|
|
Alternative LazyList where
|
|
|
|
empty = []
|
|
|
|
(<|>) = (<+>)
|
|
|
|
|
|
|
|
public export
|
|
|
|
Monad LazyList where
|
|
|
|
m >>= f = concatMap f m
|
|
|
|
|
|
|
|
-- There is no Traversable instance for lazy lists.
|
|
|
|
-- The result of a traversal will be a non-lazy list in general
|
|
|
|
-- (you can't delay the "effect" of an applicative functor).
|
|
|
|
public export
|
|
|
|
traverse : Applicative f => (a -> f b) -> LazyList a -> f (List b)
|
|
|
|
traverse g [] = pure []
|
|
|
|
traverse g (x :: xs) = [| g x :: traverse g xs |]
|
2020-12-18 13:33:56 +03:00
|
|
|
|
|
|
|
public export
|
|
|
|
sequence : Applicative f => LazyList (f a) -> f (List a)
|
|
|
|
sequence = traverse id
|
|
|
|
|
|
|
|
--- Lists creation ---
|
|
|
|
|
|
|
|
public export
|
|
|
|
fromList : List a -> LazyList a
|
|
|
|
fromList [] = []
|
|
|
|
fromList (x::xs) = x :: fromList xs
|
|
|
|
|
|
|
|
covering
|
|
|
|
public export
|
|
|
|
iterate : (f : a -> Maybe a) -> (x : a) -> LazyList a
|
|
|
|
iterate f x = x :: case f x of
|
|
|
|
Nothing => []
|
|
|
|
Just y => iterate f y
|
|
|
|
|
|
|
|
public export
|
|
|
|
iterateN : Nat -> (a -> a) -> a -> LazyList a
|
|
|
|
iterateN Z _ _ = []
|
|
|
|
iterateN (S n) f x = x :: iterateN n f (f x)
|
|
|
|
|
|
|
|
public export
|
|
|
|
replicate : (n : Nat) -> (x : a) -> LazyList a
|
|
|
|
replicate Z _ = []
|
|
|
|
replicate (S n) x = x :: replicate n x
|
|
|
|
|
|
|
|
--- Functions for acquiring different types of sublists ---
|
|
|
|
|
|
|
|
public export
|
|
|
|
take : Nat -> LazyList a -> LazyList a
|
|
|
|
take (S k) (x::xs) = x :: take k xs
|
|
|
|
take _ _ = []
|
|
|
|
|
|
|
|
public export
|
|
|
|
drop : Nat -> LazyList a -> LazyList a
|
|
|
|
drop Z xs = xs
|
|
|
|
drop (S _) [] = []
|
|
|
|
drop (S n) (_::xs) = drop n xs
|
|
|
|
|
|
|
|
public export
|
|
|
|
takeWhile : (a -> Bool) -> LazyList a -> LazyList a
|
|
|
|
takeWhile p [] = []
|
|
|
|
takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
|
|
|
|
|
|
|
|
public export
|
|
|
|
dropWhile : (a -> Bool) -> LazyList a -> LazyList a
|
|
|
|
dropWhile p [] = []
|
|
|
|
dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
|
|
|
|
|
|
|
|
public export
|
|
|
|
filter : (a -> Bool) -> LazyList a -> LazyList a
|
|
|
|
filter p [] = []
|
|
|
|
filter p (x::xs) = if p x then x :: filter p xs else filter p xs
|