pure-borrow
Safe HaskellNone
LanguageGHC2021

Control.Monad.Borrow.Pure

Description

This module is meant to be the prelude module of Pure Borrow, a Rust-style borrow realization in Linear Haskell. This module provides only the basic pieces of the API, and you may want to import other modules, e.g. Control.Monad.Borrow.Pure.BO, Data.Ref.Linear.Borrow, or Data.Vector.Mutable.Linear.Borrow, for more utilities.

Synopsis

Documentation

Pure Borrow: An Overview

This module provides the main API of Pure Borrow, the pure realization of Rust-style borrowing in Linear Haskell.

The core idea is that mutable resources are accessed through lifetime-indexed borrows:

  • Linearly proves that we are in a context where linear resources can be allocated and used safely.
  • BO α a is a computation that may use borrows valid during the lifetime α. It also provides pure API with the concurrency primitive.
  • Mut α a is a mutable borrow of an a valid during α.
  • Share α a is an immutable borrow of an a valid during α.
  • Lend α a is the capability to recover the original a after α ends.
  • After α a describes post-processing that runs after α ends, such as reclaiming a Lend.

Examples

You need the following language extensions to use this module:

  • BlockArguments
  • LinearTypes
  • NoImplicitPrelude
  • ImpredicativeTypes
  • QualifiedDo

...and import these modules:

import Prelude.Linear
import Control.Monad.Borrow.Pure
import qualified Data.Vector.Mutable.Linear.Borrow as VL
import Control.Syntax.DataFlow qualified as DataFlow
import Control.Functor.Linear qualified as Control

The examples use qualified do-notation. DataFlow.do is convenient for rebiding pure values, and Control.do is the do-notation for linear functors and monads.

The following example initializes a mutable vector, modifies it coordinate-wise, and then reads one element and the final contents:

>>> :{
  example1 :: (Int, [Int])
  example1 = linearly \lin -> DataFlow.do
    (lin, lin') <- dup lin
    vec <- VL.fromList [0, 1, 2] lin
    runBO lin' Control.do
      (mvec, lend) <- borrowM vec
      mvec <- VL.modify 0 (+ 3) mvec
      mvec <- VL.modify 2 (+ 5) mvec
      mvec <- VL.modify 0 (* 4) mvec
      let !(Ur svec) = share mvec
      Ur n <- VL.copyAt 0 svec
      pureAfter (n, unur $ VL.toList (reclaim lend))
:}
>>> example1
(12,[12,1,7])

This just returns (12, [12, 1, 7]) as expected, which is not so surprising. But what if you want to modify non-overlapping segments of the vectors in-parallel? In particular, while you have to do two modifications to index 0 sequentially, you can modify the segment containing original index 2 in parallel with the first modification to index 0. This is where pure concurrency with parBO comes in:

>>> :{
  example2 :: (Int, [Int])
  example2 = linearly \lin -> DataFlow.do
    (lin, lin') <- dup lin
    vec <- VL.fromList [0, 1, 2] lin
    runBO lin' Control.do
      (mvec, lend) <- borrowM vec
      let !(mvec1, mvec2) = VL.splitAt 1 mvec -- (*)
      (mvec, ()) <-
        parBO
          ( Control.do
              mvec1 <- VL.modify 0 (+ 3) mvec1
              VL.modify 0 (* 4) mvec1
          )
          (consume Control.<$> VL.modify 1 (+ 5) mvec2)
      let !(Ur svec) = share mvec
      Ur n <- VL.copyAt 0 svec
      pureAfter (n, unur $ VL.toList (reclaim lend))
:}
>>> example2
(12,[12,1,7])

The line after (*) splits the mutable vector into two non-overlapping mutable borrows, which can be safely used in parallel with parBO. The left branch returns the modified first slice, while the right branch consumes its slice and returns (). The whole original vector is later recovered through lend.

Manual discarding of split resources becomes tedious quickly. This is where the borrow-based affine API helps: reborrowing lets you work in a shorter lifetime without manually reclaiming the original borrow.

>>> :{
  example3 :: (Int, [Int])
  example3 = linearly \lin -> DataFlow.do
    (lin, lin') <- dup lin
    vec <- VL.fromList [0, 1, 2] lin
    runBO lin' Control.do
      (mvec, lend) <- borrowM vec
      -- (!)
      mvec <- reborrowing_ mvec \mvec -> Control.do
        let !(mvec1, mvec2) = VL.splitAt 1 mvec
        -- (!!)
        consume
          Control.<$> parBO
            ( Control.do
                mvec1 <- VL.modify 0 (+ 3) mvec1
                VL.modify 0 (* 4) mvec1
            )
            (VL.modify 1 (+ 5) mvec2)
      let !(Ur svec) = share mvec -- (!!!)
      Ur n <- VL.copyAt 0 svec
      pureAfter (n, unur $ VL.toList (reclaim lend))
:}
>>> example3
(12,[12,1,7])

The line after (!) opens a new sublifetime with reborrowing_. Within this sublifetime, the new mutable borrow mvec is divided into two pieces, and then both slices are modified in parallel after (!!). This time, the split mvec1 and mvec2 are consumed after parBO returns. Once the sublifetime ends, the original mutable borrow to the whole vector is recovered and used at (!!!).

This way, you can treat and split mutable and immutable borrows freely without manually dropping or reuniting them into the original resources.

Core BO monad

data BO (α :: Lifetime) a Source #

Computation returning a that can be performed only during the lifetime α. Internally it is a linear ST monad.

Instances

Instances details
(α >= β, a <: b) => (BO α a :: Type) <: (BO β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (BO α a) (BO β b) Source #

Applicative (BO α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

pure :: a %1 -> BO α a #

(<*>) :: BO α (a %1 -> b) %1 -> BO α a %1 -> BO α b #

liftA2 :: (a %1 -> b %1 -> c) %1 -> BO α a %1 -> BO α b %1 -> BO α c #

Functor (BO α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

fmap :: (a %1 -> b) %1 -> BO α a %1 -> BO α b #

Monad (BO α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

(>>=) :: BO α a %1 -> (a %1 -> BO α b) %1 -> BO α b #

(>>) :: BO α () %1 -> BO α a %1 -> BO α a #

Applicative (BO α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

pure :: a -> BO α a #

(<*>) :: BO α (a %1 -> b) %1 -> BO α a %1 -> BO α b #

liftA2 :: (a %1 -> b %1 -> c) -> BO α a %1 -> BO α b %1 -> BO α c #

Functor (BO α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

fmap :: (a %1 -> b) -> BO α a %1 -> BO α b #

Monoid w => Monoid (BO α w) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

mempty :: BO α w #

Semigroup w => Semigroup (BO α w) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

(<>) :: BO α w %1 -> BO α w %1 -> BO α w #

runBO :: Linearly %1 -> (forall (α :: Lifetime). BO α (After α a)) %1 -> a Source #

Runs a BO computation and returns the result of postprocessing After the lifetime has ended.

See also: runBOLend and runBO_.

runBOLend :: Linearly %1 -> (forall (α :: Lifetime). BO α (Lend α a)) %1 -> a Source #

A variant of runBO that returns the original rsource retained by the Lender

runBO_ :: Linearly %1 -> (forall (α :: Lifetime). BO α a) %1 -> a Source #

A variant of runBO that returns the direct value of BO computation.

srunBO :: forall (β :: Lifetime) a. (forall (α :: Lifetime). BO/\ β) (After α a)) %1 -> BO β a Source #

Runs a BO computation within the ephemeral sublifetime and returns the result.

srunBO_ :: forall (β :: Lifetime) a. (forall (α :: Lifetime). BO/\ β) a) %1 -> BO β a Source #

A variant of srunBO that returns the direct value of BO computation.

Lifetimes and Subtyping

Lifetime is a key concept in borrowing. You can understand it as a version of the thread parameter s in ST s, but refined with the subtyping relation (<=) (or outlives-relation (>=)).

Every BO α computation is parametrized with lifetime, and ordinary borrows, such as Mut α a or Share α a, and lenders Lend α a also have the lifetime for which they are valid. To accommodate casting between different lifetimes, we also provide the upcast operator that has a lifetime parameter according to the sublifetime relation. The upcast operator casts a given type along (<:) relation, which extends (<=) to the other types appropriately.

Any two lifetimes α and β have the meet α /\ β, which is the longest lifetime that is shorter than both α and β; i.e. α /\ β is the most generic lifetime such that α /\ β <= α and α /\ β <= β. We use some tricks with /\ to work around type-checking higher-level combinators. For example, consider the type of srunBO_:

srunBO_ :: (forall β. BO/\ α) a) %1 -> BO α a

At first glance, the type forall β. BO/\ α) a might look rather cryptic. But essentially, the above type is morally equivalent to the following:

srunBO_ :: (forall β <= α. BO β a) %1 -> BO α a

That is, all srunBO_ does is open an ephemeral sublifetime β <= α and run the computation inside it. However, without involved hacking or type-checker plugins, the type system is not good at treating transitivity of subtyping relation. By quantifying over all lifetimes and combining them with /\, we can make the type-checker happy without losing generality.

So, if you see a pattern that binds other lifetimes with forall and combines them with /\, you can think of it as quantifying over a sublifetime of the current lifetime.

Lifetime

data Lifetime Source #

The kind (type) of lifetimes.

type (/\) = '(:/\) infixr 3 Source #

The meet of the two lifetimes. It is the longest lifetime that is shorter than both of them.

class (α :: Lifetime) <= (β :: Lifetime) infix 2 Source #

Minimal complete definition

witness

Instances

Instances details
α <= Static Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Internal

Methods

witness :: Witness α Static

α <=! β => α <= β Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Internal

Methods

witness :: Witness α β

(α <= β, α <= γ) => α <=/\ γ) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Internal

Methods

witness :: Witness α (β /\ γ)

type (>=) (α :: Lifetime) (β :: Lifetime) = β <= α Source #

Flipped version of <=.

type Static = 'Static Source #

Static lifetime, which lives forever and neverEnds.

neverEnds :: (HasCallStack, End Static) => a Source #

Static lifetime lasts forever.

Subtyping and upcasting

upcast :: a <: b => a %1 -> b Source #

class (a :: k) <: (b :: k1) infix 4 Source #

Minimal complete definition

subtype

Instances

Instances details
Coercible a b => (a :: k) <: (b :: k) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

GenericSubtype a b => (a :: Type) <: (Generically b :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Coercible a b => (a :: Type) <: (AsCoercible b :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

α >= β => (EndToken α :: Type) <: (EndToken β :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

a <: b => ([a] :: Type) <: ([b] :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Methods

subtype :: SubtypeWitness [a] [b] Source #

(a <: a', b <: b') => (Either a b :: Type) <: (Either a' b' :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Methods

subtype :: SubtypeWitness (Either a b) (Either a' b') Source #

(α >= β, a <: b) => (BO α a :: Type) <: (BO β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (BO α a) (BO β b) Source #

(α <= β, a <: b) => (Lend α a :: Type) <: (Lend β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Lend α a) (Lend β b) Source #

(α >= β, a <: b, b <: a) => (Mut α a :: Type) <: (Mut β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Mut α a) (Mut β b) Source #

(α >= β, a <: b) => (Share α a :: Type) <: (Share β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Share α a) (Share β b) Source #

(α <= β, a <: b) => (After α a :: Type) <: (After β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

subtype :: SubtypeWitness (After α a) (After β b) Source #

(a <: a', b <: b') => ((a, b) :: Type) <: ((a', b') :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Methods

subtype :: SubtypeWitness (a, b) (a', b') Source #

(a' <: a, b <: b', p <= q) => (a %p -> b :: Type) <: (a' %q -> b' :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Methods

subtype :: SubtypeWitness (a %p -> b) (a' %q -> b') Source #

β <= α => (Borrows bk α xs :: Type) <: (Borrows bk' β xs :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Experimental.Borrows

Methods

subtype :: SubtypeWitness (Borrows bk α xs) (Borrows bk' β xs) Source #

(a <: a', b <: b', c <: c') => ((a, b, c) :: Type) <: ((a', b', c') :: Type) Source # 
Instance details

Defined in Data.Coerce.Directed.Internal

Methods

subtype :: SubtypeWitness (a, b, c) (a', b', c') Source #

Linearity witnesses

When you allocate mutable resources, you must ensure that they are used only linearly; i.e. they are used exactly once. In Linear Haskell, we use linear arrow %1 -> to express this invariant. More precisely, a %1 -> b reads that if the application of the function is consumed exactly once, then the argument is consumed exactly once. This definition poses a subtle problem: the resource is guaranteed to be used linearly only when the resource is bound under some linear arrow context. Hence, we must know that we are under a linear context before allocating mutable references, otherwise the mutable state can leak outside.

The Linearly token witnesses exactly this invariant. The important point is that it can be introduced into the context only by linearly combinator:

linearly :: Movable a => (Linearly %1 -> a) %1 -> a

This assures that Linearly can be used as a linearity witness when mutable resources are allocated. You can duplicate a Linearly token as many times as you want with dup and drop it with consume.

fromList :: [a] %1 -> Linearly %1 -> Vector a

See Linear Constraints: the Problem with Scopes for more details.

Those mutable datatypes can only be introduced via a Linearly witness, so they can be seen as carrying the Linearly witness inside. LinearOnly is a type class for such datatypes and we can use it to recover a Linearly witness from such values.

withLinearly :: (LinearOnly a) => a %1 -> (Linearly, a)

Further, running the BO computation also requires Linearly:

runBO_ :: Linearly %1 -> (forall α. BO α a) %1 -> a

Hence, you can retrieve a Linearly token inside BO via askLinearly, asksLinearlyM, etc.

data Linearly Source #

Witness that the current computation is in a linear context.

linearly :: Movable a => (Linearly %1 -> a) %1 -> a Source #

class LinearOnly (a :: TYPE rep) Source #

A (non-bottom) value of the type a can only live in a linear context.

Minimal complete definition

linearOnly

withLinearly :: LinearOnly a => a %1 -> (Linearly, a) Source #

askLinearly :: forall (α :: Lifetime). BO α Linearly Source #

asksLinearly :: forall r (α :: Lifetime). (Linearly %1 -> r) %1 -> BO α r Source #

asksLinearlyM :: forall (α :: Lifetime) r. (Linearly %1 -> BO α r) %1 -> BO α r Source #

Parallel computation

parBO :: forall (α :: Lifetime) a b. BO α a %1 -> BO α b %1 -> BO α (a, b) Source #

Run two computations in parallel, returning their results as a tuple.

Borrowing

To treat a linear resource inside BO monad, you have to borrow it first. The most typical introduction form is borrowM:

borrowM :: a %1 -> BO α (Mut α a, Lend α a)

This borrows a linear resource into the same lifetime as the ambient BO, returning a Mutable borrow and a Lender of the original resource. Or, you can do the linear allocation of the resource and borrow it at the same time with borrowLinearlyM:

borrowLinearlyM :: (Linearly %1 -> a) %1 -> BO α (Mut α a, Lend α a)

In any case, the main computation with possible destructive updates is done on Mutable borrows, and the original resource will be reclaimed from the Lender at the end of the lifetime α. More precisely, Lend α a must be processed in an appropriate After α r value that is returned to runBO, srunBO, or the reborrowing operators described later. After α a is a kind of finalizer that will be run after the lifetime α has Ended, and it can be used to reclaim the original resource from a Lender and do further final computation such as conversion or consumption.

One can share the Mutable borrow into Shared borrow:

share :: Mut α a %1 -> Ur (Share α a)

As Share is an immutable borrow, it can be freely duplicated and dropped, as witnessed by the Ur wrapper. Shared borrows are always introduced nonlinearly, so that you can freely use them multiple times or drop them at any time. Note that share consumes the original Mut. If you want to share the resource temporarily into a sublifetime and then continue mutating afterwards, you can use the sharing combinator (and its variants sharing' and sharing_):

sharing ::
  forall α α' a r.
  Mut α a %1 ->
  (forall β. Share/\ α) a -> BO/\ α') r) %1 ->
  BO α' (r, Mut α a)

Analogously, you can reborrow mutable borrows into sublifetimes using the reborrowing combinator (and its variants reborrowing' and reborrowing_).

reborrowing ::
  forall α α' a r.
  Mut α a %1 ->
  (forall β. Mut/\ α) a -> BO/\ α') r) %1 ->
  BO α' (r, Mut α a)

There is an experimental interface abstracting the reborrowable borrows in Control.Monad.Borrow.Pure.Experimental.Reborrowable.

Borrow polymorphism

Mut, Share, and Lend are all specific instantiations of the Alias type:

type Mut α a = Borrow 'Mut α a
type Share α a = Borrow 'Share α a
type Borrow bk α a = Alias ('Borrow bk) α a
type Lend α a = Alias 'Lend α a

Hence, if you see Borrow bk α a in a function, it can be either Mut or Share. If you see Alias ak α a, it may also be a Lend.

Control.Monad.Borrow.Pure.Experimental.Borrows provides an experimental API for treating a bundle of multiple borrows in the same lifetime at once.

Which combinator should I use?

Central Borrow types

type Mut = Borrow 'Mut Source #

Mutable borrower, which is affine and can update the data.

type Share = Borrow 'Share Source #

Shared borrower, which is unrestricted but usually can only read from the data.

type Lend = Alias 'Lend Source #

Lender, which can retrieve the lifetime at the lifetime α.

type Borrow (bk :: BorrowKind) = Alias ('Borrow bk) Source #

Borrower of kind bk that is active during the lifetime α.

data Alias (ak :: AliasKind) (α :: Lifetime) a Source #

Alias of kind ak to a resource of type a.

Instances

Instances details
Reborrowable Mut Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Experimental.Reborrowable

Methods

locally' :: forall (α :: Lifetime) a (α' :: Lifetime) r. Mut α a %1 -> (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') (After β r)) %1 -> BO α' (r, Mut α a) Source #

Reborrowable Share Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Experimental.Reborrowable

Methods

locally' :: forall (α :: Lifetime) a (α' :: Lifetime) r. Share α a %1 -> (forall (β :: Lifetime). Share/\ α) a %1 -> BO/\ α') (After β r)) %1 -> BO α' (r, Share α a) Source #

(α <= β, a <: b) => (Lend α a :: Type) <: (Lend β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Lend α a) (Lend β b) Source #

(α >= β, a <: b, b <: a) => (Mut α a :: Type) <: (Mut β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Mut α a) (Mut β b) Source #

(α >= β, a <: b) => (Share α a :: Type) <: (Share β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

subtype :: SubtypeWitness (Share α a) (Share β b) Source #

bk ~ 'Mut => LinearOnly (Borrow bk α a :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Consumable (Borrow bk α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

consume :: Borrow bk α a %1 -> () #

k ~ 'Borrow 'Share => Dupable (Alias k α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

dupR :: Alias k α a %1 -> Replicator (Alias k α a) #

dup2 :: Alias k α a %1 -> (Alias k α a, Alias k α a) #

k ~ 'Borrow 'Share => Movable (Alias k α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

move :: Alias k α a %1 -> Ur (Alias k α a) #

Affine (Borrow bk α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

aff :: Borrow bk α a %1 -> Aff (Borrow bk α a) Source #

Introduction form

borrowM :: forall a (α :: Lifetime). a %1 -> BO α (Mut α a, Lend α a) Source #

Borrow a resource linearly for the same lifetime as the ambient BO computation. Returns the pair of the mutable borrow to the resource, and Lender to be invoked later to reclaim the resource at the End of the lifetime.

See also borrowLinearlyM.

If you want to borrow a resource indepdendent of the ambient lifetime, you can use borrow instead.

borrowLinearlyM :: forall a (α :: Lifetime). (Linearly %1 -> a) %1 -> BO α (Mut α a, Lend α a) Source #

A variant of borrowM that does linear allocation first.

share :: forall (k :: BorrowKind) (α :: Lifetime) a. Borrow k α a %1 -> Ur (Share α a) Source #

Shares a mutable borrow, invalidating the original one.

Reborrowing and computation in sublifetime

reborrowing' :: forall (α :: Lifetime) a (α' :: Lifetime) r. Mut α a %1 -> (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') (After β r)) %1 -> BO α' (r, Mut α a) Source #

Executes an operation on Mutable borrow in sub lifetime. You may need -XImpredicativeTypes extension to use this function.

See also: reborrowing, and reborrowing_. For Shared borrows, see sharing, sharing', and sharing_.

reborrowing :: forall (α :: Lifetime) a (α' :: Lifetime) r. Mut α a %1 -> (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') r) %1 -> BO α' (r, Mut α a) Source #

A variant of reborrowing' that returns the direct value of the operation on the reborrowed mutable borrow. There is also a flipped infix version (<%~).

See also: reborrowing_ and sharing.

(<%~) :: forall (α :: Lifetime) a (α' :: Lifetime) r. (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') r) %1 -> Mut α a %1 -> BO α' (r, Mut α a) infix 4 Source #

Flipped infix version of reborrowing, smoewhat analgous to (<$>) and (<%~) in lens package.

reborrowing_ :: forall r (α :: Lifetime) a (α' :: Lifetime). Consumable r => Mut α a %1 -> (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') r) %1 -> BO α' (Mut α a) Source #

A variant of reborrowing' that discards the final result of the computation. There is also a flipped infix version (<%=).

See also: reborrowing and sharing_.

(<%=) :: forall (α :: Lifetime) a (α' :: Lifetime). (forall (β :: Lifetime). Mut/\ α) a %1 -> BO/\ α') ()) %1 -> Mut α a %1 -> BO α' (Mut α a) infix 4 Source #

Flipped infix version of reborrowing_, smoewhat analgous to (<$>) and (<%=) in lens package.

sharing' :: forall (α :: Lifetime) a (α' :: Lifetime) r. Mut α a %1 -> (forall (β :: Lifetime). Share/\ α) a -> BO/\ α') (After β r)) %1 -> BO α' (r, Mut α a) Source #

Executes an operation on Shared borrow in sub lifetime. You may need -XImpredicativeTypes extension to use this function.

See also: sharing and sharing_. For Mutable borrows, see reborrowing'.

sharing :: forall (α :: Lifetime) (α' :: Lifetime) a r. Mut α a %1 -> (forall (β :: Lifetime). Share/\ α) a -> BO/\ α') r) %1 -> BO α' (r, Mut α a) Source #

A variant of sharing' that returns the direct value of the computation on the shared borrow. There is also a flipped infix version (<$~).

See also: sharing_. For Mutable borrows, see reborrowing.

(<$~) :: forall (α :: Lifetime) a (α' :: Lifetime) r. (forall (β :: Lifetime). Share/\ α) a -> BO/\ α') r) %1 -> Mut α a %1 -> BO α' (r, Mut α a) infix 4 Source #

Flipped infix version of sharing, smoewhat analgous to (<$>) and (<%~) in lens package.

sharing_ :: forall (α :: Lifetime) (α' :: Lifetime) a r. Consumable r => Mut α a %1 -> (forall (β :: Lifetime). Share/\ α) a -> BO/\ α') r) %1 -> BO α' (Mut α a) Source #

A variant of sharing' that discards the final result of the computation. There is also a flipped infix version (<$=).

See also: sharing. For Mutable borrows, see reborrowing_.

(<$=) :: forall (α :: Lifetime) a (α' :: Lifetime). (forall (β :: Lifetime). Share/\ α) a -> BO/\ α') ()) %1 -> Mut α a %1 -> BO α' (Mut α a) Source #

Flipped infix version of sharing_, smoewhat analgous to (<$>) and (<%=) in lens package.

Finalization and reclamation

newtype After (α :: Lifetime) a Source #

Utility type to represent an object available after the lifetime α.

You can use Applicative and Monad instances to write After conveniently.

Constructors

After (End α => a) 

Instances

Instances details
(α <= β, a <: b) => (After α a :: Type) <: (After β b :: Type) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

subtype :: SubtypeWitness (After α a) (After β b) Source #

Applicative (After α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

pure :: a %1 -> After α a #

(<*>) :: After α (a %1 -> b) %1 -> After α a %1 -> After α b #

liftA2 :: (a %1 -> b %1 -> c) %1 -> After α a %1 -> After α b %1 -> After α c #

Functor (After α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

fmap :: (a %1 -> b) %1 -> After α a %1 -> After α b #

Monad (After α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

(>>=) :: After α a %1 -> (a %1 -> After α b) %1 -> After α b #

(>>) :: After α () %1 -> After α a %1 -> After α a #

Applicative (After α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

pure :: a -> After α a #

(<*>) :: After α (a %1 -> b) %1 -> After α a %1 -> After α b #

liftA2 :: (a %1 -> b %1 -> c) -> After α a %1 -> After α b %1 -> After α c #

Functor (After α) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

fmap :: (a %1 -> b) -> After α a %1 -> After α b #

reclaim' :: forall (α :: Lifetime) a. Lend α a %1 -> After α a Source #

Reclaims a borrowed resource at the End of lifetime @α'.

reclaim :: forall (α :: Lifetime) a. End α => Lend α a %1 -> a Source #

Reclaims a borrowed resource at the End of lifetime @α'.

pureAfter :: forall (α :: Lifetime) a. (End α => a) %1 -> BO α (After α a) Source #

class End (α :: Lifetime) Source #

Witness that the lifetime α has ended.

Minimal complete definition

endToken

In-place modification with mutable borrows

modifyBO :: a %1 -> Linearly %1 -> (forall (α :: Lifetime). Mut α a %1 -> BO α r) %1 -> (r, a) Source #

Modifies linear resources in-place, together with results.

modifyBO_ :: a %1 -> Linearly %1 -> (forall (α :: Lifetime). Mut α a %1 -> BO α ()) %1 -> a Source #

Modifies linear resources in-place, without results.

modifyLinearOnlyBO :: LinearOnly a => a %1 -> (forall (α :: Lifetime). Mut α a %1 -> BO α r) %1 -> (r, a) Source #

Modifies linear resources in-place, together with results.

modifyLinearOnlyBO_ :: LinearOnly a => a %1 -> (forall (α :: Lifetime). Mut α a %1 -> BO α ()) %1 -> a Source #

Modifies linear resources in-place, together with results.

Utility function to manipulate borrows

joinMut :: forall (bk :: BorrowKind) (α :: Lifetime) (β :: Lifetime) a. Borrow bk α (Mut β a) %1 -> Borrow bk (α /\ β) a Source #

Collapse a borrower to a mutable borrower.

joinLend :: forall (α :: Lifetime) a. Lend α (Lend α a) %1 -> Lend α a Source #

coerceShare :: forall b (α :: Lifetime) a. Coercible a b => Share α a %1 -> Share α b Source #

Copying and Cloning

For some types, you can copy them as the direct value out of a borrow:

copy :: Borrow bk α a %1 -> a

Note that copy consumes a borrow linearly. For Shared borrows it doesn't matter because they are always introduced nonlinearly. But for Mutable borrows, we cannot use a copyed value multiple times as Muts are always bound linearly. To alleviate this problem, we also provide copyMut that wraps copied value inside Ur:

copyMut :: Mut α a %1 -> Ur a

Precisely, if the type a does not contain any mutable or foreign resources, it can be safely Copyable out of borrows. Some examples are (but not limited to):

  • Primitive types, such as Int, Bool, etc.
  • Immutable data structures, such as lists, tuples of them, etc. (but not mutable vectors, arrays, etc.)

For possibly mutable types, you can still clone them out of borrows linearly inside BO-monad:

clone :: Clone a => Share α a %1 -> BO α a

This includes, for example, Ref or Vector. The fact that the cloned value is only accessible inside BO ensures that we cannot leak mutable states inside a into unrestricted contexts -- otherwise, we can introduce mutable values into unrestricted context via move :: Share α a -> Ur (Share α a).

class Copyable a where Source #

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α a %1 -> a Source #

Instances

Instances details
Copyable Int16 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Int16 %1 -> Int16 Source #

Copyable Int32 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Int32 %1 -> Int32 Source #

Copyable Int64 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Int64 %1 -> Int64 Source #

Copyable Int8 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Int8 %1 -> Int8 Source #

Copyable Word16 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Word16 %1 -> Word16 Source #

Copyable Word32 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Word32 %1 -> Word32 Source #

Copyable Word64 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Word64 %1 -> Word64 Source #

Copyable Word8 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Word8 %1 -> Word8 Source #

Copyable Integer Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Integer %1 -> Integer Source #

Copyable Natural Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Natural %1 -> Natural Source #

Copyable () Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α () %1 -> () Source #

Copyable Bool Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Bool %1 -> Bool Source #

Copyable Char Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Char %1 -> Char Source #

Copyable Double Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Double %1 -> Double Source #

Copyable Float Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Float %1 -> Float Source #

Copyable Int Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Int %1 -> Int Source #

Copyable Word Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α Word %1 -> Word Source #

Copyable a => Copyable (Max a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Max a) %1 -> Max a Source #

Copyable a => Copyable (Min a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Min a) %1 -> Min a Source #

Copyable a => Copyable (Product a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Product a) %1 -> Product a Source #

Copyable a => Copyable (Sum a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Sum a) %1 -> Sum a Source #

GenericCopyable a => Copyable (Generically a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Generically a) %1 -> Generically a Source #

Unsatisfiable ('ShowType (Array a) ':<>: 'Text " cannot be copied!") => Copyable (Array a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Array a) %1 -> Array a Source #

Copyable (Ur a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Ur a) %1 -> Ur a Source #

Unsatisfiable ('ShowType (Vector a) ':<>: 'Text " cannot be copied!") => Copyable (Vector a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Vector a) %1 -> Vector a Source #

Copyable a => Copyable (AsCopyable a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (AsCopyable a) %1 -> AsCopyable a Source #

Unsatisfiable ('ShowType (Ref a) ':<>: 'Text " cannot be copied!") => Copyable (Ref a) Source # 
Instance details

Defined in Data.Ref.Linear

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Ref a) %1 -> Ref a Source #

Unsatisfiable ('ShowType (Vector a) ':<>: 'Text " cannot be copied!") => Copyable (Vector a) Source # 
Instance details

Defined in Data.Vector.Mutable.Linear.Borrow

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Vector a) %1 -> Vector a Source #

Copyable a => Copyable (Maybe a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Maybe a) %1 -> Maybe a Source #

Copyable a => Copyable [a] Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α [a] %1 -> [a] Source #

(Copyable a, Copyable b) => Copyable (Arg a b) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Arg a b) %1 -> Arg a b Source #

(Copyable a, Copyable b) => Copyable (Either a b) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Either a b) %1 -> Either a b Source #

(Copyable a, Copyable b) => Copyable (a, b) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (a, b) %1 -> (a, b) Source #

(Copyable1 f, Copyable a) => Copyable (AsCopyable1 f a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (AsCopyable1 f a) %1 -> AsCopyable1 f a Source #

(Copyable a, Copyable b, Copyable c) => Copyable (a, b, c) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (a, b, c) %1 -> (a, b, c) Source #

(Copyable a, Copyable b, Copyable c, Copyable d) => Copyable (a, b, c, d) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (a, b, c, d) %1 -> (a, b, c, d) Source #

copyMut :: forall a (α :: Lifetime). Copyable a => Mut α a %1 -> Ur a Source #

A variant of copy that returns Ur wrapped copy of the value. Ur wrapper was not necessary because Share is always introduced unrestricted, whereas Mut is introduced linearly, so it is convenient to have Ur wrapped version.

class Clone a where Source #

Clone a is analogous o Copyable a, but requires cloned values to be accessible only inside the BO α monad.

The difference between Clone and Copyable is that the former allows for cloning a shared borrow of a mutable or linear value, while the latter requires cloning a shared borrow of an immutable value. This is because we can leak Share α a via Movable instance, and hence it can outlive the original BO α lifetime, which allows leaking mutable states inside a into unrestricted contexts, which destroys the soundness severly.

Minimal complete definition

Nothing

Methods

clone :: forall (α :: Lifetime). Share α a %1 -> BO α a Source #

default clone :: forall (α :: Lifetime). GenericClone a => Share α a %1 -> BO α a Source #

Instances

Instances details
Clone Int16 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Int16 %1 -> BO α Int16 Source #

Clone Int32 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Int32 %1 -> BO α Int32 Source #

Clone Int64 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Int64 %1 -> BO α Int64 Source #

Clone Int8 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Int8 %1 -> BO α Int8 Source #

Clone Word16 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Word16 %1 -> BO α Word16 Source #

Clone Word32 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Word32 %1 -> BO α Word32 Source #

Clone Word64 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Word64 %1 -> BO α Word64 Source #

Clone Word8 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Word8 %1 -> BO α Word8 Source #

Clone Integer Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Integer %1 -> BO α Integer Source #

Clone Natural Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Natural %1 -> BO α Natural Source #

Clone () Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α () %1 -> BO α () Source #

Clone Bool Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Bool %1 -> BO α Bool Source #

Clone Char Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Char %1 -> BO α Char Source #

Clone Double Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Double %1 -> BO α Double Source #

Clone Float Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Float %1 -> BO α Float Source #

Clone Int Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Int %1 -> BO α Int Source #

Clone Word Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α Word %1 -> BO α Word Source #

Clone a => Clone (NonEmpty a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (NonEmpty a) %1 -> BO α (NonEmpty a) Source #

GenericClone a => Clone (Generically a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (Generically a) %1 -> BO α (Generically a) Source #

Copyable a => Clone (AsCopyable a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (AsCopyable a) %1 -> BO α (AsCopyable a) Source #

Dupable a => Clone (Ref a) Source # 
Instance details

Defined in Data.Ref.Linear

Methods

clone :: forall (α :: Lifetime). Share α (Ref a) %1 -> BO α (Ref a) Source #

Dupable a => Clone (Vector a) Source # 
Instance details

Defined in Data.Vector.Mutable.Linear.Borrow

Methods

clone :: forall (α :: Lifetime). Share α (Vector a) %1 -> BO α (Vector a) Source #

Clone a => Clone (Maybe a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (Maybe a) %1 -> BO α (Maybe a) Source #

Clone a => Clone [a] Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α [a] %1 -> BO α [a] Source #

(Clone a, Clone b) => Clone (Either a b) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (Either a b) %1 -> BO α (Either a b) Source #

(Clone a, Clone b) => Clone (a, b) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (a, b) %1 -> BO α (a, b) Source #

(Clone a, Clone b, Clone c) => Clone (a, b, c) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (a, b, c) %1 -> BO α (a, b, c) Source #

(Clone a, Clone b, Clone c, Clone d) => Clone (a, b, c, d) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (a, b, c, d) %1 -> BO α (a, b, c, d) Source #

(Clone a, Clone b, Clone c, Clone d, Clone e) => Clone (a, b, c, d, e) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Clone

Methods

clone :: forall (α :: Lifetime). Share α (a, b, c, d, e) %1 -> BO α (a, b, c, d, e) Source #

Splitting aliases

You can do case-splitting on Borrows - for example:

splitPair :: Alias ak α (a, b) %1 -> (Alias ak α a, Alias ak α b)
splitEither :: Alias ak α (Either a b) %1 -> Either (Alias ak α a) (Alias ak α b)

For other datatypes, you can use split to split general parametric types into borrows. It is morally an instance method of the DistributesAlias class, and you can derive it using anyclass derivation together with the deriveGenericAnd1 macro.

We also provide experimental splitting on record types in Data.Record.Linear.Borrow.Experimental.PatternMatch and Data.Record.Linear.Borrow.Experimental.Split.

splitPair :: forall (ak :: AliasKind) (α :: Lifetime) a b. Alias ak α (a, b) %1 -> (Alias ak α a, Alias ak α b) Source #

splitEither :: forall (ak :: AliasKind) (α :: Lifetime) a b. Alias ak α (Either a b) %1 -> Either (Alias ak α a) (Alias ak α b) Source #

split :: forall f x (ak :: AliasKind) (α :: Lifetime). DistributesAlias f => Alias ak α (f x) %1 -> f (Alias ak α x) Source #

class DistributesAlias (f :: Type -> Type) Source #

Distribute an alias over a functor.

Instances

Instances details
DistributesAlias First Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (First x) %1 -> First (Alias ak α x)

DistributesAlias Last Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Last x) %1 -> Last (Alias ak α x)

DistributesAlias Max Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Max x) %1 -> Max (Alias ak α x)

DistributesAlias Min Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Min x) %1 -> Min (Alias ak α x)

DistributesAlias Identity Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Identity x) %1 -> Identity (Alias ak α x)

DistributesAlias First Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (First x) %1 -> First (Alias ak α x)

DistributesAlias Last Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Last x) %1 -> Last (Alias ak α x)

DistributesAlias Down Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Down x) %1 -> Down (Alias ak α x)

DistributesAlias Dual Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Dual x) %1 -> Dual (Alias ak α x)

DistributesAlias Par1 Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Par1 x) %1 -> Par1 (Alias ak α x)

DistributesAlias Maybe Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Maybe x) %1 -> Maybe (Alias ak α x)

DistributesAlias Solo Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Solo x) %1 -> Solo (Alias ak α x)

DistributesAlias [] Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α [x] %1 -> [Alias ak α x]

Unsatisfiable ('Text "Use splitEither directly!") => DistributesAlias (Either e) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Either e x) %1 -> Either e (Alias ak α x)

Unsatisfiable ('Text "Use splitPair instead!") => DistributesAlias ((,) a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (a, x) %1 -> (a, Alias ak α x)

GenericDistributesAlias f => DistributesAlias (Generically1 f) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

split_ :: forall (ak :: AliasKind) (α :: Lifetime) x. Alias ak α (Generically1 f x) %1 -> Generically1 f (Alias ak α x)

type GenericDistributesAlias (f :: Type -> Type) = (Generic1 f, GDistributeAlias (Rep1 f)) Source #

genericSplit :: forall f x (ak :: AliasKind) (α :: Lifetime). GenericDistributesAlias f => Alias ak α (f x) %1 -> f (Alias ak α x) Source #

Re-exporting Prelude.Linear classes

class Consumable a where #

Methods

consume :: a %1 -> () #

Instances

Instances details
Consumable ByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: ByteString %1 -> () #

Consumable ShortByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: ShortByteString %1 -> () #

Consumable Void # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Void %1 -> () #

Consumable All # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: All %1 -> () #

Consumable Any # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Any %1 -> () #

Consumable Int16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Int16 %1 -> () #

Consumable Int32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Int32 %1 -> () #

Consumable Int64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Int64 %1 -> () #

Consumable Int8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Int8 %1 -> () #

Consumable Word16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Word16 %1 -> () #

Consumable Word32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Word32 %1 -> () #

Consumable Word64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Word64 %1 -> () #

Consumable Word8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Word8 %1 -> () #

Consumable Ordering # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Ordering %1 -> () #

Consumable Pool # 
Instance details

Defined in Foreign.Marshal.Pure.Internal

Methods

consume :: Pool %1 -> () #

Consumable Linearly Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Methods

consume :: Linearly %1 -> () #

Consumable UniqueSource Source # 
Instance details

Defined in Data.Unique.Linear

Methods

consume :: UniqueSource %1 -> () #

Consumable Text # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Text %1 -> () #

Consumable Integer # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Integer %1 -> () #

Consumable Natural # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: Natural %1 -> () #

Consumable () # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: () %1 -> () #

Consumable Bool # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Bool %1 -> () #

Consumable Char # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Char %1 -> () #

Consumable Double # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Double %1 -> () #

Consumable Float # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Float %1 -> () #

Consumable Int # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Int %1 -> () #

Consumable Word # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Word %1 -> () #

Consumable a => Consumable (First a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: First a %1 -> () #

Consumable a => Consumable (Last a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Last a %1 -> () #

Consumable a => Consumable (Max a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Max a %1 -> () #

Consumable a => Consumable (Min a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Min a %1 -> () #

Consumable a => Consumable (WrappedMonoid a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: WrappedMonoid a %1 -> () #

Consumable a => Consumable (NonEmpty a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: NonEmpty a %1 -> () #

Consumable a => Consumable (First a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: First a %1 -> () #

Consumable a => Consumable (Last a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Last a %1 -> () #

Consumable a => Consumable (Dual a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Dual a %1 -> () #

Consumable a => Consumable (Product a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Product a %1 -> () #

Consumable a => Consumable (Sum a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Sum a %1 -> () #

(Generic a, GConsumable (Rep a)) => Consumable (Generically a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Generically a %1 -> () #

Consumable (Array a) # 
Instance details

Defined in Data.Array.Mutable.Linear.Internal

Methods

consume :: Array a %1 -> () #

Consumable a => Consumable (MovableNum a) # 
Instance details

Defined in Data.Num.Linear

Methods

consume :: MovableNum a %1 -> () #

Consumable (Replicator a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Replicator a %1 -> () #

Consumable (ReplicationStream a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: ReplicationStream a %1 -> () #

Consumable (Set a) # 
Instance details

Defined in Data.Set.Mutable.Linear.Internal

Methods

consume :: Set a %1 -> () #

Movable a => Consumable (AsMovable a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: AsMovable a %1 -> () #

Consumable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Ur a %1 -> () #

Consumable (Vector a) # 
Instance details

Defined in Data.Vector.Mutable.Linear.Internal

Methods

consume :: Vector a %1 -> () #

Consumable (Aff a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Affine.Internal

Methods

consume :: Aff a %1 -> () #

Affine a => Consumable (AsAffine a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Affine.Internal

Methods

consume :: AsAffine a %1 -> () #

GenericAffine a => Consumable (GenericallyAffine a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Affine.Internal

Methods

consume :: GenericallyAffine a %1 -> () #

Consumable a => Consumable (Ref a) Source # 
Instance details

Defined in Data.Ref.Linear

Methods

consume :: Ref a %1 -> () #

Consumable a => Consumable (Vector a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Vector a %1 -> () #

Consumable a => Consumable (Maybe a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Maybe a %1 -> () #

Consumable a => Consumable (Solo a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Solo a %1 -> () #

Consumable a => Consumable [a] # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: [a] %1 -> () #

(Consumable a, Consumable b) => Consumable (Arg a b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Arg a b %1 -> () #

(Consumable e, Consumable a) => Consumable (Either e a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Either e a %1 -> () #

Consumable (HashMap k v) # 
Instance details

Defined in Data.HashMap.Mutable.Linear.Internal

Methods

consume :: HashMap k v %1 -> () #

(KnownNat n, Consumable a) => Consumable (V n a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: V n a %1 -> () #

Consumable (V 0 a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

consume :: V 0 a %1 -> () #

Consumable (LabelsOrBorrows h xs) Source # 
Instance details

Defined in Data.Record.Linear.Borrow.Experimental.PatternMatch

Methods

consume :: LabelsOrBorrows h xs %1 -> () #

(Consumable a, Consumable b) => Consumable (a, b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: (a, b) %1 -> () #

Consumable (f a) => Consumable (Ap f a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Ap f a %1 -> () #

Consumable (f a) => Consumable (Alt f a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Alt f a %1 -> () #

Consumable (Borrow bk α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

consume :: Borrow bk α a %1 -> () #

Consumable (Borrows bk α xs) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Experimental.Borrows

Methods

consume :: Borrows bk α xs %1 -> () #

(Consumable a, Consumable b, Consumable c) => Consumable (a, b, c) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: (a, b, c) %1 -> () #

Consumable (SplitRecord a bk α fs) Source # 
Instance details

Defined in Data.Record.Linear.Borrow.Experimental.Split

Methods

consume :: SplitRecord a bk α fs %1 -> () #

(Consumable a, Consumable b, Consumable c, Consumable d) => Consumable (a, b, c, d) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: (a, b, c, d) %1 -> () #

(Consumable a, Consumable b, Consumable c, Consumable d, Consumable e) => Consumable (a, b, c, d, e) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: (a, b, c, d, e) %1 -> () #

class Consumable a => Dupable a where #

The laws of Dupable are dual to those of Monoid:

  • 1. first consume (dup2 a) ≃ a ≃ second consume (dup2 a) (dup2 neutrality)
  • 2. first dup2 (dup2 a) ≃ (second dup2 (dup2 a)) (dup2 associativity)

where the (≃) sign represents equality up to type isomorphism.

  • 3. dup2 = Replicator.elim (,) . dupR (coherence between dup2 and dupR)
  • 4. consume = Replicator.elim () . dupR (coherence between consume and dupR)
  • 5. Replicator.extract . dupR = id (dupR identity)
  • 6. dupR . dupR = (Replicator.map dupR) . dupR (dupR interchange)

(Laws 1-2 and 5-6 are equivalent)

Implementation of Dupable for Movable types should be done with deriving via AsMovable.

Implementation of Dupable for other types can be done with deriving via Generically. Note that at present this mechanism can have performance problems for recursive parameterized types. Specifically, the methods will not specialize to underlying Dupable instances. See this GHC issue.

Minimal complete definition

dupR | dup2

Methods

dupR :: a %1 -> Replicator a #

Creates a Replicator for the given a.

You usually want to define this method using Replicator's Applicative instance. For instance, here is an implementation of Dupable [a]:

instance Dupable a => Dupable [a] where
  dupR [] = pure []
  dupR (a : as) = (:) <$> dupR a <*> dupR as

dup2 :: a %1 -> (a, a) #

Creates two as from a Dupable a, in a linear fashion.

Instances

Instances details
Dupable ByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Dupable ShortByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Dupable All # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: All %1 -> Replicator All #

dup2 :: All %1 -> (All, All) #

Dupable Any # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Any %1 -> Replicator Any #

dup2 :: Any %1 -> (Any, Any) #

Dupable Int16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Int16 %1 -> Replicator Int16 #

dup2 :: Int16 %1 -> (Int16, Int16) #

Dupable Int32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Int32 %1 -> Replicator Int32 #

dup2 :: Int32 %1 -> (Int32, Int32) #

Dupable Int64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Int64 %1 -> Replicator Int64 #

dup2 :: Int64 %1 -> (Int64, Int64) #

Dupable Int8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Int8 %1 -> Replicator Int8 #

dup2 :: Int8 %1 -> (Int8, Int8) #

Dupable Word16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Word16 %1 -> Replicator Word16 #

dup2 :: Word16 %1 -> (Word16, Word16) #

Dupable Word32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Word32 %1 -> Replicator Word32 #

dup2 :: Word32 %1 -> (Word32, Word32) #

Dupable Word64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Word64 %1 -> Replicator Word64 #

dup2 :: Word64 %1 -> (Word64, Word64) #

Dupable Word8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Word8 %1 -> Replicator Word8 #

dup2 :: Word8 %1 -> (Word8, Word8) #

Dupable Ordering # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Dupable Pool # 
Instance details

Defined in Foreign.Marshal.Pure.Internal

Methods

dupR :: Pool %1 -> Replicator Pool #

dup2 :: Pool %1 -> (Pool, Pool) #

Dupable Linearly Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Lifetime.Token.Internal

Dupable Text # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: Text %1 -> Replicator Text #

dup2 :: Text %1 -> (Text, Text) #

Dupable Integer # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Dupable Natural # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Dupable () # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: () %1 -> Replicator () #

dup2 :: () %1 -> ((), ()) #

Dupable Bool # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Bool %1 -> Replicator Bool #

dup2 :: Bool %1 -> (Bool, Bool) #

Dupable Char # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Char %1 -> Replicator Char #

dup2 :: Char %1 -> (Char, Char) #

Dupable Double # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Double %1 -> Replicator Double #

dup2 :: Double %1 -> (Double, Double) #

Dupable Float # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Float %1 -> Replicator Float #

dup2 :: Float %1 -> (Float, Float) #

Dupable Int # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Int %1 -> Replicator Int #

dup2 :: Int %1 -> (Int, Int) #

Dupable Word # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Word %1 -> Replicator Word #

dup2 :: Word %1 -> (Word, Word) #

Dupable a => Dupable (NonEmpty a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: NonEmpty a %1 -> Replicator (NonEmpty a) #

dup2 :: NonEmpty a %1 -> (NonEmpty a, NonEmpty a) #

Dupable a => Dupable (Product a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Product a %1 -> Replicator (Product a) #

dup2 :: Product a %1 -> (Product a, Product a) #

Dupable a => Dupable (Sum a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Sum a %1 -> Replicator (Sum a) #

dup2 :: Sum a %1 -> (Sum a, Sum a) #

(Generic a, GDupable (Rep a)) => Dupable (Generically a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Dupable (Array a) # 
Instance details

Defined in Data.Array.Mutable.Linear.Internal

Methods

dupR :: Array a %1 -> Replicator (Array a) #

dup2 :: Array a %1 -> (Array a, Array a) #

Dupable a => Dupable (MovableNum a) # 
Instance details

Defined in Data.Num.Linear

Methods

dupR :: MovableNum a %1 -> Replicator (MovableNum a) #

dup2 :: MovableNum a %1 -> (MovableNum a, MovableNum a) #

Dupable (Replicator a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Replicator a %1 -> Replicator (Replicator a) #

dup2 :: Replicator a %1 -> (Replicator a, Replicator a) #

Dupable (ReplicationStream a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: ReplicationStream a %1 -> Replicator (ReplicationStream a) #

dup2 :: ReplicationStream a %1 -> (ReplicationStream a, ReplicationStream a) #

Dupable (Set a) # 
Instance details

Defined in Data.Set.Mutable.Linear.Internal

Methods

dupR :: Set a %1 -> Replicator (Set a) #

dup2 :: Set a %1 -> (Set a, Set a) #

Movable a => Dupable (AsMovable a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: AsMovable a %1 -> Replicator (AsMovable a) #

dup2 :: AsMovable a %1 -> (AsMovable a, AsMovable a) #

Dupable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Ur a %1 -> Replicator (Ur a) #

dup2 :: Ur a %1 -> (Ur a, Ur a) #

Dupable (Vector a) # 
Instance details

Defined in Data.Vector.Mutable.Linear.Internal

Methods

dupR :: Vector a %1 -> Replicator (Vector a) #

dup2 :: Vector a %1 -> (Vector a, Vector a) #

Dupable a => Dupable (Ref a) Source # 
Instance details

Defined in Data.Ref.Linear

Methods

dupR :: Ref a %1 -> Replicator (Ref a) #

dup2 :: Ref a %1 -> (Ref a, Ref a) #

Dupable a => Dupable (Maybe a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Maybe a %1 -> Replicator (Maybe a) #

dup2 :: Maybe a %1 -> (Maybe a, Maybe a) #

Dupable a => Dupable (Solo a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Solo a %1 -> Replicator (Solo a) #

dup2 :: Solo a %1 -> (Solo a, Solo a) #

Dupable a => Dupable [a] # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: [a] %1 -> Replicator [a] #

dup2 :: [a] %1 -> ([a], [a]) #

(Dupable a, Dupable b) => Dupable (Either a b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Either a b %1 -> Replicator (Either a b) #

dup2 :: Either a b %1 -> (Either a b, Either a b) #

Dupable (HashMap k v) # 
Instance details

Defined in Data.HashMap.Mutable.Linear.Internal

Methods

dupR :: HashMap k v %1 -> Replicator (HashMap k v) #

dup2 :: HashMap k v %1 -> (HashMap k v, HashMap k v) #

(KnownNat n, Dupable a) => Dupable (V n a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

dupR :: V n a %1 -> Replicator (V n a) #

dup2 :: V n a %1 -> (V n a, V n a) #

(Dupable a, Dupable b) => Dupable (a, b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: (a, b) %1 -> Replicator (a, b) #

dup2 :: (a, b) %1 -> ((a, b), (a, b)) #

k ~ 'Borrow 'Share => Dupable (Alias k α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

dupR :: Alias k α a %1 -> Replicator (Alias k α a) #

dup2 :: Alias k α a %1 -> (Alias k α a, Alias k α a) #

(Dupable a, Dupable b, Dupable c) => Dupable (a, b, c) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: (a, b, c) %1 -> Replicator (a, b, c) #

dup2 :: (a, b, c) %1 -> ((a, b, c), (a, b, c)) #

(Dupable a, Dupable b, Dupable c, Dupable d) => Dupable (a, b, c, d) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: (a, b, c, d) %1 -> Replicator (a, b, c, d) #

dup2 :: (a, b, c, d) %1 -> ((a, b, c, d), (a, b, c, d)) #

(Dupable a, Dupable b, Dupable c, Dupable d, Dupable e) => Dupable (a, b, c, d, e) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: (a, b, c, d, e) %1 -> Replicator (a, b, c, d, e) #

dup2 :: (a, b, c, d, e) %1 -> ((a, b, c, d, e), (a, b, c, d, e)) #

dup :: Dupable a => a %1 -> (a, a) #

Creates two as from a Dupable a. Same function as dup2.

dup3 :: Dupable a => a %1 -> (a, a, a) #

Creates 3 as from a Dupable a, in a linear fashion.

class Dupable a => Movable a where #

Use Movable a to represent a type which can be used many times even when given linearly. Simple data types such as Bool or [] are Movable. Though, bear in mind that this typically induces a deep copy of the value.

Formally, Movable a is the class of coalgebras of the Ur comonad. That is

  • unur (move x) = x
  • move @(Ur a) (move @a x) = fmap (move @a) $ move @a x

Additionally, a Movable instance must be compatible with its Dupable parent instance. That is:

  • case move x of {Ur _ -> ()} = consume x
  • case move x of {Ur x -> (x, x)} = dup2 x

Methods

move :: a %1 -> Ur a #

Instances

Instances details
Movable ByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: ByteString %1 -> Ur ByteString #

Movable ShortByteString # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Movable All # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: All %1 -> Ur All #

Movable Any # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Any %1 -> Ur Any #

Movable Int16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Int16 %1 -> Ur Int16 #

Movable Int32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Int32 %1 -> Ur Int32 #

Movable Int64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Int64 %1 -> Ur Int64 #

Movable Int8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Int8 %1 -> Ur Int8 #

Movable Word16 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Word16 %1 -> Ur Word16 #

Movable Word32 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Word32 %1 -> Ur Word32 #

Movable Word64 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Word64 %1 -> Ur Word64 #

Movable Word8 # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Word8 %1 -> Ur Word8 #

Movable Ordering # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Ordering %1 -> Ur Ordering #

Movable Text # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Text %1 -> Ur Text #

Movable Integer # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Integer %1 -> Ur Integer #

Movable Natural # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: Natural %1 -> Ur Natural #

Movable () # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: () %1 -> Ur () #

Movable Bool # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Bool %1 -> Ur Bool #

Movable Char # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Char %1 -> Ur Char #

Movable Double # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Double %1 -> Ur Double #

Movable Float # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Float %1 -> Ur Float #

Movable Int # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Int %1 -> Ur Int #

Movable Word # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Word %1 -> Ur Word #

Movable a => Movable (NonEmpty a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: NonEmpty a %1 -> Ur (NonEmpty a) #

Movable a => Movable (Product a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Product a %1 -> Ur (Product a) #

Movable a => Movable (Sum a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Sum a %1 -> Ur (Sum a) #

(Generic a, GMovable (Rep a)) => Movable (Generically a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Generically a %1 -> Ur (Generically a) #

Movable a => Movable (MovableNum a) # 
Instance details

Defined in Data.Num.Linear

Methods

move :: MovableNum a %1 -> Ur (MovableNum a) #

Movable a => Movable (AsMovable a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Instances

Methods

move :: AsMovable a %1 -> Ur (AsMovable a) #

Movable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Ur a %1 -> Ur (Ur a) #

Movable a => Movable (Maybe a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Maybe a %1 -> Ur (Maybe a) #

Movable a => Movable (Solo a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Solo a %1 -> Ur (Solo a) #

Movable a => Movable [a] # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: [a] %1 -> Ur [a] #

(Movable a, Movable b) => Movable (Either a b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Either a b %1 -> Ur (Either a b) #

(Movable a, Movable b) => Movable (a, b) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: (a, b) %1 -> Ur (a, b) #

k ~ 'Borrow 'Share => Movable (Alias k α a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.BO.Internal

Methods

move :: Alias k α a %1 -> Ur (Alias k α a) #

(Movable a, Movable b, Movable c) => Movable (a, b, c) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: (a, b, c) %1 -> Ur (a, b, c) #

(Movable a, Movable b, Movable c, Movable d) => Movable (a, b, c, d) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: (a, b, c, d) %1 -> Ur (a, b, c, d) #

(Movable a, Movable b, Movable c, Movable d, Movable e) => Movable (a, b, c, d, e) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: (a, b, c, d, e) %1 -> Ur (a, b, c, d, e) #

data Ur a where #

Ur a represents unrestricted values of type a in a linear context. The key idea is that because the contructor holds a with a regular arrow, a function that uses Ur a linearly can use a however it likes.

someLinear :: Ur a %1-> (a,a)
someLinear (Ur a) = (a,a)

Constructors

Ur :: forall a. a -> Ur a 

Instances

Instances details
Applicative Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Methods

pure :: a -> Ur a #

(<*>) :: Ur (a -> b) -> Ur a -> Ur b #

liftA2 :: (a -> b -> c) -> Ur a -> Ur b -> Ur c #

(*>) :: Ur a -> Ur b -> Ur b #

(<*) :: Ur a -> Ur b -> Ur a #

Functor Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Methods

fmap :: (a -> b) -> Ur a -> Ur b #

(<$) :: a -> Ur b -> Ur a #

Monad Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Methods

(>>=) :: Ur a -> (a -> Ur b) -> Ur b #

(>>) :: Ur a -> Ur b -> Ur b #

return :: a -> Ur a #

Foldable Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Methods

fold :: Monoid m => Ur m -> m #

foldMap :: Monoid m => (a -> m) -> Ur a -> m #

foldMap' :: Monoid m => (a -> m) -> Ur a -> m #

foldr :: (a -> b -> b) -> b -> Ur a -> b #

foldr' :: (a -> b -> b) -> b -> Ur a -> b #

foldl :: (b -> a -> b) -> b -> Ur a -> b #

foldl' :: (b -> a -> b) -> b -> Ur a -> b #

foldr1 :: (a -> a -> a) -> Ur a -> a #

foldl1 :: (a -> a -> a) -> Ur a -> a #

toList :: Ur a -> [a] #

null :: Ur a -> Bool #

length :: Ur a -> Int #

elem :: Eq a => a -> Ur a -> Bool #

maximum :: Ord a => Ur a -> a #

minimum :: Ord a => Ur a -> a #

sum :: Num a => Ur a -> a #

product :: Num a => Ur a -> a #

Traversable Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Methods

traverse :: Applicative f => (a -> f b) -> Ur a -> f (Ur b) #

sequenceA :: Applicative f => Ur (f a) -> f (Ur a) #

mapM :: Monad m => (a -> m b) -> Ur a -> m (Ur b) #

sequence :: Monad m => Ur (m a) -> m (Ur a) #

Applicative Ur # 
Instance details

Defined in Data.Functor.Linear.Internal.Applicative

Methods

pure :: a -> Ur a #

(<*>) :: Ur (a %1 -> b) %1 -> Ur a %1 -> Ur b #

liftA2 :: (a %1 -> b %1 -> c) -> Ur a %1 -> Ur b %1 -> Ur c #

Functor Ur # 
Instance details

Defined in Data.Functor.Linear.Internal.Functor

Methods

fmap :: (a %1 -> b) -> Ur a %1 -> Ur b #

Comonad Ur Source # 
Instance details

Defined in Data.Comonad.Linear

Methods

extract :: Ur a %1 -> a Source #

duplicate :: Ur a %1 -> Ur (Ur a) Source #

ComonadApply Ur Source # 
Instance details

Defined in Data.Comonad.Linear

Methods

(<@>) :: Ur (a %1 -> b) %1 -> Ur a %1 -> Ur b Source #

Generic1 Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Associated Types

type Rep1 Ur 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep1 Ur = D1 ('MetaData "Ur" "Data.Unrestricted.Linear.Internal.Ur" "lnr-bs-0.7.0-928fde49" 'False) (C1 ('MetaCons "Ur" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))

Methods

from1 :: Ur a -> Rep1 Ur a #

to1 :: Rep1 Ur a -> Ur a #

Generic1 Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Associated Types

type Rep1 Ur 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep1 Ur = FixupMetaData1 Ur (D1 Any (C1 Any (S1 Any (MP1 'Many Par1))))

Methods

to1 :: forall p (m :: Multiplicity). Rep1 Ur p %m -> Ur p #

from1 :: forall p (m :: Multiplicity). Ur p %m -> Rep1 Ur p #

Generic (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Associated Types

type Rep (Ur a) 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep (Ur a) = D1 ('MetaData "Ur" "Data.Unrestricted.Linear.Internal.Ur" "lnr-bs-0.7.0-928fde49" 'False) (C1 ('MetaCons "Ur" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

Methods

from :: Ur a -> Rep (Ur a) x #

to :: Rep (Ur a) x -> Ur a #

Monoid a => Monoid (Ur a) #

Useful to treat unrestricted monoids as linear ones.

Instance details

Defined in Data.Monoid.Linear.Internal.Monoid

Methods

mempty :: Ur a #

Semigroup a => Semigroup (Ur a) #

Useful to treat unrestricted semigroups as linear ones.

Instance details

Defined in Data.Monoid.Linear.Internal.Semigroup

Methods

(<>) :: Ur a %1 -> Ur a %1 -> Ur a #

Eq a => Eq (Ur a) # 
Instance details

Defined in Data.Ord.Linear.Internal.Eq

Methods

(==) :: Ur a %1 -> Ur a %1 -> Bool #

(/=) :: Ur a %1 -> Ur a %1 -> Bool #

Ord a => Ord (Ur a) # 
Instance details

Defined in Data.Ord.Linear.Internal.Ord

Methods

compare :: Ur a %1 -> Ur a %1 -> Ordering #

(<=) :: Ur a %1 -> Ur a %1 -> Bool #

(<) :: Ur a %1 -> Ur a %1 -> Bool #

(>) :: Ur a %1 -> Ur a %1 -> Bool #

(>=) :: Ur a %1 -> Ur a %1 -> Bool #

Consumable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Consumable

Methods

consume :: Ur a %1 -> () #

Dupable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Dupable

Methods

dupR :: Ur a %1 -> Replicator (Ur a) #

dup2 :: Ur a %1 -> (Ur a, Ur a) #

Movable (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Movable

Methods

move :: Ur a %1 -> Ur (Ur a) #

KnownRepresentable a => KnownRepresentable (Ur a) # 
Instance details

Defined in Foreign.Marshal.Pure.Internal

Methods

storable :: Dict (Storable (Ur a))

Generic (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

Associated Types

type Rep (Ur a) 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep (Ur a) = FixupMetaData (Ur a) (D1 Any (C1 Any (S1 Any (MP1 'Many (Rec0 a)))))

Methods

to :: forall p (m :: Multiplicity). Rep (Ur a) p %m -> Ur a #

from :: forall p (m :: Multiplicity). Ur a %m -> Rep (Ur a) p #

Affine (Ur a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Affine.Internal

Methods

aff :: Ur a %1 -> Aff (Ur a) Source #

Copyable (Ur a) Source # 
Instance details

Defined in Control.Monad.Borrow.Pure.Copyable

Methods

copy :: forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α (Ur a) %1 -> Ur a Source #

type Rep1 Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep1 Ur = D1 ('MetaData "Ur" "Data.Unrestricted.Linear.Internal.Ur" "lnr-bs-0.7.0-928fde49" 'False) (C1 ('MetaCons "Ur" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))
type Rep1 Ur # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep1 Ur = FixupMetaData1 Ur (D1 Any (C1 Any (S1 Any (MP1 'Many Par1))))
type Rep (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep (Ur a) = D1 ('MetaData "Ur" "Data.Unrestricted.Linear.Internal.Ur" "lnr-bs-0.7.0-928fde49" 'False) (C1 ('MetaCons "Ur" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))
type Rep (Ur a) # 
Instance details

Defined in Data.Unrestricted.Linear.Internal.Ur

type Rep (Ur a) = FixupMetaData (Ur a) (D1 Any (C1 Any (S1 Any (MP1 'Many (Rec0 a)))))