Monadic lazy lists. #
Lazy lists with "laziness" controlled by an arbitrary monad.
In an initial section we describe the specification of MLList
,
and provide a private unsafe implementation,
and then a public opaque
wrapper of this implementation, satisfying the specification.
Equations
- ⋯ = ⋯
Constructs a MLList
from head and tail.
Equations
- MLList.cons = (MLList.spec m).cons
Instances For
Embed a non-monadic thunk as a lazy list.
Equations
- MLList.thunk = (MLList.spec m).thunk
Instances For
Lift a monadic lazy list inside the monad to a monadic lazy list.
Equations
- MLList.squash = (MLList.spec m).squash
Instances For
Deconstruct a MLList
, returning inside the monad an optional pair α × MLList m α
representing the head and tail of the list.
Equations
- MLList.uncons = (MLList.spec m).uncons
Instances For
Try to deconstruct a MLList
, returning an optional pair α × MLList m α
representing the head and tail of the list if it is already evaluated, and none
otherwise.
Equations
- MLList.uncons? = (MLList.spec m).uncons?
Instances For
Equations
- MLList.instEmptyCollectionMLList = { emptyCollection := MLList.nil }
Construct a singleton monadic lazy list from a single monadic value.
Equations
- MLList.singletonM x = MLList.squash fun (x_1 : Unit) => do let __do_lift ← x pure (MLList.cons __do_lift MLList.nil)
Instances For
Construct a singleton monadic lazy list from a single value.
Equations
Instances For
Constructs an MLList
recursively, with state in α
, recording terms from β
.
If f
returns none
the list will terminate.
Variant of MLList.fix?
that allows returning values of a different type.
Repeatedly apply a function f : α → m (α × List β)
to an initial a : α
,
accumulating the elements of the resulting List β
as a single monadic lazy list.
(This variant allows starting with a specified List β
of elements, as well. )
Repeatedly apply a function f : α → m (α × List β)
to an initial a : α
,
accumulating the elements of the resulting List β
as a single monadic lazy list.
Equations
- MLList.fixl f s = MLList.fixlWith f s []
Instances For
Compute, inside the monad, whether a MLList
is empty.
Equations
- MLList.isEmpty xs = (ULift.up ∘ Option.isSome) <$> MLList.uncons xs
Instances For
Equations
- MLList.ofList [] = MLList.nil
- MLList.ofList (h :: t) = MLList.cons h (MLList.thunk fun (x : Unit) => MLList.ofList t)
Instances For
Convert a List
of values inside the monad into a MLList
.
Equations
- MLList.ofListM [] = MLList.nil
- MLList.ofListM (h :: t) = MLList.squash fun (x : Unit) => do let __do_lift ← h pure (MLList.cons __do_lift (MLList.ofListM t))
Instances For
Performs a monadic case distinction on a MLList
when the motive is a MLList
as well.
Equations
- MLList.casesM xs hnil hcons = MLList.squash fun (x : Unit) => do let __do_lift ← MLList.uncons xs match __do_lift with | none => hnil () | some (x, xs) => hcons x xs
Instances For
Performs a case distinction on a MLList
when the motive is a MLList
as well.
(We need to be in a monadic context to distinguish a nil from a cons.)
Equations
- One or more equations did not get rendered due to their size.
Instances For
Gives the monadic lazy list consisting all of folds of a function on a given initial element.
Thus [a₀, a₁, ...].foldsM f b
will give [b, ← f b a₀, ← f (← f b a₀) a₁, ...]
.
Gives the monadic lazy list consisting all of folds of a function on a given initial element.
Thus [a₀, a₁, ...].foldsM f b
will give [b, f b a₀, f (f b a₀) a₁, ...]
.
Equations
- MLList.folds f init L = MLList.foldsM (fun (b : β) (a : α) => pure (f b a)) init L
Instances For
Take the first n
elements, as a list inside the monad.
Equations
- MLList.takeAsList xs n = MLList.takeAsList.go n [] xs
Instances For
Take the first n
elements, as an array inside the monad.
Equations
- MLList.takeAsArray xs n = MLList.takeAsArray.go n #[] xs
Instances For
Drop the first n
elements.
Equations
- MLList.drop xs 0 = xs
- MLList.drop xs (Nat.succ r_1) = MLList.cases xs (fun (x : Unit) => MLList.nil) fun (x : α) (l : MLList m α) => MLList.drop l r_1
Instances For
Apply a function to every element of a MLList
.
Equations
- MLList.map f L = MLList.mapM (fun (a : α) => pure (f a)) L
Instances For
Filter a MLList
.
Equations
- MLList.filter p L = MLList.filterM (fun (a : α) => pure { down := p a }) L
Instances For
Take the initial segment of the lazy list, until the function f
first returns false
.
Equations
- MLList.takeWhile f = MLList.takeWhileM fun (a : α) => pure { down := f a }
Instances For
Implementation of MLList.fin
.
Convert an array to a monadic lazy list.
Equations
- MLList.ofArray L = MLList.ofArray.go L 0
Instances For
Implementation of MLList.ofArray
.
Group the elements of a lazy list into chunks of a given size. If the lazy list is finite, the last chunk may be smaller (possibly even length 0).
Equations
- MLList.chunk L n = MLList.chunk.go n n #[] L
Instances For
Add one element to the end of a monadic lazy list.
Equations
- MLList.concat L a = MLList.append L fun (x : Unit) => MLList.cons a MLList.nil
Instances For
Convert any value in the monad to the singleton monadic lazy list.
Equations
- MLList.monadLift x = MLList.squash fun (x_1 : Unit) => do let __do_lift ← x pure (MLList.cons __do_lift MLList.nil)
Instances For
Given a lazy list in a state monad, run it on some initial state.
Equations
- MLList.runState' L s = MLList.map (fun (x : α × σ) => x.fst) (MLList.runState L s)
Instances For
Run a lazy list in a StateRefT'
monad on some initial state.
Return the head of a monadic lazy list if it exists, as an Option
in the monad.
Equations
- MLList.head? L = do let __do_lift ← MLList.uncons L pure (Option.map (fun (x : α × MLList m α) => x.fst) __do_lift)
Instances For
Take the initial segment of the lazy list,
up to and including the first place where f
gives true
.
Equations
- MLList.takeUpToFirst L f = MLList.takeUpToFirstM L fun (a : α) => pure { down := f a }
Instances For
Gets the last element of a monadic lazy list, as an option in the monad. This will run forever if the list is infinite.
Equations
- MLList.getLast? L = do let __do_lift ← MLList.uncons L match __do_lift with | none => pure none | some (x, xs) => MLList.getLast?.aux x xs
Instances For
Gets the last element of a monadic lazy list, or the default value if the list is empty. This will run forever if the list is infinite.
Equations
- MLList.getLast! L = Option.get! <$> MLList.getLast? L
Instances For
Folds a binary function across a monadic lazy list, from an initial starting value. This will run forever if the list is infinite.
Equations
- MLList.foldM f init L = do let __do_lift ← MLList.getLast? (MLList.foldsM f init L) pure (Option.getD __do_lift init)
Instances For
Folds a binary function across a monadic lazy list, from an initial starting value. This will run forever if the list is infinite.
Equations
- MLList.fold f init L = MLList.foldM (fun (b : β) (a : α) => pure (f b a)) init L
Instances For
Return the head of a monadic lazy list, as a value in the monad. Fails if the list is empty.
Equations
- MLList.head L = do let __discr ← MLList.uncons L match __discr with | some (r, snd) => pure r | x => failure
Instances For
Apply a function returning values inside the monad to a monadic lazy list, returning only the first successful result.
Equations
- MLList.firstM L f = MLList.head (MLList.filterMapM f L)
Instances For
Return the first value on which a predicate returns true.
Equations
- MLList.first L p = MLList.head (MLList.filter p L)
Instances For
Equations
- MLList.instAlternativeMLList = Alternative.mk (fun {α : Type u_1} => MLList.nil) fun {α : Type u_1} => MLList.append