6 | ||| An empty type for tagging linear computations that can be wrapped in `IO`
10 | --------------------------------------------------------------------------------
11 | -- T1
12 | --------------------------------------------------------------------------------
14 | ||| A linear token used in computations with mutable linear state.
15 | |||
16 | ||| The idea is that mutable state (mutable references, arrays, pointers,
17 | ||| and so on) can only be accessed in the presence of the linear token
18 | ||| that was used to create the mutable resource.
19 | |||
20 | ||| The advantage of using linear types over the `ST` monad: They come
21 | ||| without the (significant) performance overhead of monadic code in
22 | ||| Idris. Like the `ST` monad, this provides safe resource handling, because
23 | ||| the function for running linear computations over a `T1` (function
24 | ||| `run1`) must work with function argument `f` of type
25 | ||| `forall s . (1 t : T1 s) -> R1 s a`, that is, mutable references cannot
26 | ||| leak out of the linear computation and remain usable.
31 | ||| The result of a stateful linear computation.
32 | |||
33 | ||| It pairs the result value with a new linear token.
38 | ||| `R1` is a functor, but since `map` does not have the correct
39 | ||| quantities, this is what we use instead.
44 | ||| A linear computation operating on resources `rs` that produces a
45 | ||| result of type `a` with a new token operating on resources `ss`.
50 | ||| Convenience alias for `F1 s ()`.
55 | ||| The dummy action that performs no effect at all.
60 | ||| `F1` is a functor, but since it is a function type, we cannot
61 | ||| implement an interface for it (but see `Control.Monad.Pure`).
66 | ||| Runs a linear computation by providing it with its own linear token.
67 | |||
68 | ||| Since this is universally quantified over `s`, it is impossible that
69 | ||| callers can freely choose the tag for the state thread and thus reuse
70 | ||| their mutable references.
71 | |||
72 | ||| It is also not possible that the linear token paired with the
73 | ||| corresponding mutable state leaks into the outer world, because
74 | ||| the result value must have quantity omega (see the definition of `R1`).
79 | ||| Runs a linear computation tagged with `[World]` as a primitive
80 | ||| `IO` action.
85 | ||| Convenience wrapper around `primRun`.
90 | ||| Safely uses a primitive `IO` action in `F1 [World]`.
95 | ||| Safely uses an `IO` action in `F1 [World]`.
100 | ||| Run the given stateful computation if the boolean value is `True`.
101 | export
106 | ||| Run a stateful computation `n` times
107 | export
114 | --------------------------------------------------------------------------------
115 | -- FFI
116 | --------------------------------------------------------------------------------
118 | ||| Use this to convert a primitive FFI call to a linear function
119 | ||| of type `F1 rs a`.
120 | |||
121 | ||| This is typically used for running effectful computations that
122 | ||| do not produce an interesting result.
123 | ||| See `Data.Linear.Ref1.prim__writeRef` and
124 | ||| the corresponding `Data.Linear.Ref1.write1` for a usage example.
129 | --------------------------------------------------------------------------------
130 | -- Lift1
131 | --------------------------------------------------------------------------------
133 | ||| An interface for wrapping linear computations in a monadic context.
134 | |||
135 | ||| This allows us to deal with pure as well as effectful computations.
136 | ||| Effectful computations should use `World` as the tag for `s`, while
137 | ||| pure computations should use universal quantification.
150 | ||| Convenience alias for `Lift1 World`
155 | --------------------------------------------------------------------------------
156 | -- Debugging
157 | --------------------------------------------------------------------------------
161 | [noHints]
165 | ||| This is a utility for debugging complex linear algorithms
166 | ||| similar to but more convenient than the one find in module
167 | ||| `Debug.Trace`.
168 | |||
169 | ||| Strictly speaking, using this breaks referential transparency.
174 | ||| Like `debug1` but can be conveniently turned on and off via an
175 | ||| auto-implicit flag.