Idris2Doc : FS.Core

FS.Core

(source)

Reexports

importpublic Data.Linear.ELift1
importpublic FS.Scope

Definitions

dataPull : (ListType->Type->Type) ->Type->ListType->Type->Type
  A `Pull f o es r` is a - possibly infinite - series of effectful
computations running in monad `f`, producing an arbitrary sequence
of chunks of values of type `c o` along the way, that eventually
terminates either with an error of type `HSum es` or with a result
of type `r`.

A `Pull` is a monad with relation to `r`, so a sequencing of `Pull`s
via bind `(>>=)` means a sequencing of the chunks of output generated
along the way. For instance, the following `Pull` will produce the
values `[1,2,3,4,5,6]` when being run:

```idris2
emit [1,2,3] >> emit [4,5,6]
```

A `Pull` provides capabilities for safe resource management via
`FS.Scope`s, allowing us to release allocated resources as soon as

* the pull is exhausted and produces no more output.
* evaluating the pull aborts with an error.
* a pull will not longer be asked to produce additional values
because an outer pull has been exhaused.

The last case occurs for instance when we stop evaluating a `Stream`
via `take` or `takeWhile`.

About the effect type `f`: Most non-trivial `Pull`s and `Stream`s come
with the potential of failure. In addition, running a `Pull` to completion
requires (thread-local) mutable state to keep tracks of the evaluation
scopes. Effect type `f` must therefore implement interface `Data.Linear.ELift1`
at the very least. This still allows us to run a `Pull` or `Stream`
as a pure computation, for instance when using `Control.Monad.Elin`.

Most of the time, however, we are interested in streams that produce
arbitrary side-effects, and an I/O monad such as `IO.Async` is required.

A note on totality: Theoretically, we should be able define `Bind` as follows:

```idris
Bind : Pull f o es r -> Inf (r -> Pull f o es s) -> Pull f o es s
```

This would allow us to safely generate total, infinite streams of output
and only running a `Pull` would be a non-total function. In practice, however,
I found this approach to have various shortcomings: We'd need a custom
bind operator for defining infinite pulls. That's not hard to implement, but
I found it to be fairly limited and cumbersome to use, especially since
type inference got very erratic. For the time being, I therefore decided
to resort to `assert_total` when defining potentially infinite streams.
It's not pretty, but it gets the job done.

Totality: total
Visibility: export
Constructors:
Val : r->Pullfoesr
  Constructor for producing value of type `r`
Err : HSumes->Pullfoesr
  Constructor for failing with an exception
Cons : o-> Inf (Pullfoesr) ->Pullfoesr
  Constructor for producing a chunk of output values
Act : Actionfesr->Pullfoesr
  Wraps an arbitrary effectful computation in a `Pull`
Uncons : Pullfoesr->Pullfqes (Eitherr (o, Pullfoesr))
  Unwraps the given child `Pull` until it either produces
a result or a chunk of output.
Att : Pullfoesr->Pullfofs (Resultesr)
  Attempts to evaluate the underlying `Pull`, returning any error
wrapped in a `Left` and a successful result in a `Right`. This is
the primitive used for error handling.
Bind : Pullfoesr-> (r->Pullfoest) ->Pullfoest
  Sequencing of `Pull`s via monadic bind `(>>=)`.
OScope : Interruptf->Pullfoesr->Pullfoesr
  Runs the given `Pull` in a new child scope. The optional second argument
is used to check, if the scope has been interrupted.
GScope : Pullfoes (Scopef)
  Internal: A pull for returning the current scope
IScope : Scopef->Bool->Pullfoesr->Pullfoesr
  Internal: Forces the given pull to be evaluated in the given scope.

This is used when evaluating pulls in parallel (for instance, when zipping
or merging streams): Both pulls must be run in the outer scope to prevent
the resources of the second pull to be release early when the first once
is exhausted. See `stepLeg` and `StepLeg`.
OnIntr : Pullfoesr-> Lazy (Pullfoesr) ->Pullfoesr
  Continues with the second pull in case the first is interrupted.

Hints:
ELift1sf=>ELift1s (Pullfo)
HasIO (fes) =>HasIO (Pullfoes)
MErr (Pullfo)
0Stream : (ListType->Type->Type) ->ListType->Type->Type
  Alias for a `Pull` with a trivial return type.

Totality: total
Visibility: public export
0EmptyPull : (ListType->Type->Type) ->ListType->Type->Type
  Alias for a `Pull` that cannot produce any output.

Totality: total
Visibility: public export
0EmptyStream : (ListType->Type->Type) ->ListType->Type
  Alias for a `Pull` that cannot produce any output.

Totality: total
Visibility: public export
recordStepLeg : (ListType->Type->Type) ->ListType->Type->Type
  A (partially evaluated) `Pull` plus the scope it should be
evaluated in.

Totality: total
Visibility: public export
Constructor: 
SL : o->Pullfoes () ->Scopef->StepLegfeso

Projections:
.out : StepLegfeso->o
.pull : StepLegfeso->Pullfoes ()
.scope : StepLegfeso->Scopef
.out : StepLegfeso->o
Totality: total
Visibility: public export
out : StepLegfeso->o
Totality: total
Visibility: public export
.pull : StepLegfeso->Pullfoes ()
Totality: total
Visibility: public export
pull : StepLegfeso->Pullfoes ()
Totality: total
Visibility: public export
.scope : StepLegfeso->Scopef
Totality: total
Visibility: public export
scope : StepLegfeso->Scopef
Totality: total
Visibility: public export
exec : fesr->Pullfoesr
  Lifts the given effectful computation into a `Pull`.

Totality: total
Visibility: export
acquire : fesr-> (r->f [] ()) ->Pullfoesr
  Acquires a resource that will be released once the current
scope is cleaned up.

Totality: total
Visibility: export
cons : o-> Inf (Pullfoesr) ->Pullfoesr
  Prepends the given output to a pull.

Totality: total
Visibility: export
emit : o->Streamfeso
  Emits a single chunk of output.

Totality: total
Visibility: export
uncons : Pullfoesr->Pullfqes (Eitherr (o, Pullfoesr))
  Unwraps a `pull` either returning its final result or
its first output together with the remainder of the pull.

Totality: total
Visibility: export
scope : Pullfoes (Scopef)
  Returns the current evaluation scope.

This is an internal primitive that can be used to implement
new combinators and topologies.

Totality: total
Visibility: export
newScope : Pullfoesr->Pullfoesr
  Creates a new scope for running the given `Pull` in

Totality: total
Visibility: export
inScope : Scopef->Pullfoesr->Pullfoesr
  Forces the given `Pull` to be evaluated in the given scope.

This is an internal primitive that can be used to implement
new combinators and topologies.

Totality: total
Visibility: export
att : Pullfoesr->Pullfofs (Resultesr)
  Error handling primitive: Wraps a successful result in a `Right`
and an error in a `Left`.

Totality: total
Visibility: export
interruptOn : DeferredWorld (Resultes ()) ->Stream (Asynce) eso->Stream (Asynce) eso
  Runs the given pull in a new child scope and interrupts
its evaluation once the given `Deferred` is completed.

Totality: total
Visibility: export
interruptOnAny : DeferredWorlda->Stream (Asynce) eso->Stream (Asynce) eso
  Runs the given pull in a new child scope and interrupts
its evaluation once the given `Deferred` is completed.

Totality: total
Visibility: export
pull : MCancelf=>Targetsf=>PullfVoidesr->f [] (Outcomeesr)
  Runs a `Pull` to completion, eventually producing
a value of type `r`.

Note: In case of an infinite stream, this will loop forever.
In order to cancel the evaluation, consider using
`Async` and racing it with a cancelation thread (for instance,
by waiting for an operating system signal).

Visibility: export
mpull : MCancelf=>Targetsf=>Monoidr=>PullfVoid [] r->f [] r
  Like `pull` but without the possibility of failure. Returns `neutral`
in case the stream was interrupted.

Visibility: export
pullIn : Scopef->PullfVoidesr->f [] (Outcomeesr)
  Runs a Pull to completion in the given scope, without
closing the scope. Use this when the pull was generated from
an outer scope that is still in use.

Visibility: export