mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-18 16:51:51 +03:00
69 lines
1.6 KiB
Idris
69 lines
1.6 KiB
Idris
|
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
|
||
|
(::) : a -> Lazy (LazyList a) -> LazyList a
|
||
|
|
||
|
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 |]
|
||
|
|
||
|
-- This function is unsafe because it asserts
|
||
|
-- that the seed gets smaller in every iteration
|
||
|
-- but the type system does not check that.
|
||
|
--
|
||
|
-- Use cautiously.
|
||
|
public export
|
||
|
unsafeUnfoldr : (b -> Maybe (a, b)) -> b -> LazyList a
|
||
|
unsafeUnfoldr next seed =
|
||
|
case next seed of
|
||
|
Nothing => []
|
||
|
Just (x, seed') =>
|
||
|
x :: Delay (unsafeUnfoldr next $ assert_smaller seed seed')
|