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.
A monadic lazy list, controlled by an arbitrary monad.
Equations
- MLList m α = MLList.Spec.listM (MLList.spec m) α
Instances For
Constructs a MLList
from head and tail.
Equations
- MLList.cons = MLList.Spec.cons (MLList.spec m)
Instances For
Embed a non-monadic thunk as a lazy list.
Equations
- MLList.thunk = MLList.Spec.thunk (MLList.spec m)
Instances For
Lift a monadic lazy list inside the monad to a monadic lazy list.
Equations
- MLList.squash = MLList.Spec.squash (MLList.spec m)
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.uncons (MLList.spec m)
Instances For
Equations
- MLList.instEmptyCollectionMLList = { emptyCollection := MLList.nil }
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 => 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 => 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 => 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
- MLList.cases xs hnil hcons = MLList.casesM xs (fun x => pure (hnil ())) fun x xs => pure (hcons x xs)
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 => MLList.nil) fun x l => 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 => 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 => 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 => 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 {α} => MLList.nil) fun {α} => MLList.append