reference-counting-0.1.0.0: A reference counting library to alias linear resources
Safe HaskellNone
LanguageGHC2021

Data.Linear.Alias

Description

Simple reference counting with linear types inspired by Advanced Topics in Types and Programming Languages Chapter 1

Synopsis

The heart of aliasing

data Alias (m :: Type -> Type) a Source #

A reference counted alias

Instances

Instances details
Forgettable μ (Alias μ a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: Alias μ a %1 -> μ () Source #

Shareable m (Alias μ a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: Alias μ a %1 -> m (Alias μ a, Alias μ a) Source #

Fields (K1 i (Alias m a) :: k -> Type) Source # 
Instance details

Defined in Data.Linear.Alias.Internal

Methods

fields :: forall (a0 :: k). K1 i (Alias m a) a0 -> [SomeAlias] Source #

class Shareable (m :: Type -> Type) a where Source #

Minimal complete definition

Nothing

Methods

share :: a %1 -> m (a, a) Source #

Share a linear resource

Careful! You must make sure that all aliases recursively nested within this structure a are properly shared/incremented.

If you fail to implement this correctly, reference counting won't be sound. Good thing is we can do this automatically! It's much less bug-prone, especially if you update the definition of a datatype. Your a just needs to instance Generic.

default share :: (Generic a, Fields (Rep a), MonadIO m) => a %1 -> m (a, a) Source #

Instances

Instances details
Shareable m Int Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: Int %1 -> m (Int, Int) Source #

Shareable m a => Shareable m (IntMap a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: IntMap a %1 -> m (IntMap a, IntMap a) Source #

(Generic a, Fields (Rep a)) => Shareable m (Generically a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: Generically a %1 -> m (Generically a, Generically a) Source #

Shareable m a => Shareable m [a] Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: [a] %1 -> m ([a], [a]) Source #

Shareable m (Alias μ a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: Alias μ a %1 -> m (Alias μ a, Alias μ a) Source #

(Shareable m a, Shareable m b) => Shareable m (a, b) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

share :: (a, b) %1 -> m ((a, b), (a, b)) Source #

class Forgettable (m :: Type -> Type) a where Source #

Methods

forget :: a %1 -> m () Source #

Forget the existence of a linear resource

Instances

Instances details
Forgettable m Int Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: Int %1 -> m () Source #

Forgettable m a => Forgettable m (IntMap a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: IntMap a %1 -> m () Source #

Forgettable m a => Forgettable m [a] Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: [a] %1 -> m () Source #

(Forgettable m a, Forgettable m b) => Forgettable m (a, b) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: (a, b) %1 -> m () Source #

Forgettable μ (Alias μ a) Source # 
Instance details

Defined in Data.Linear.Alias

Methods

forget :: Alias μ a %1 -> μ () Source #

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

Defined in Data.Linear.Alias

Methods

forget :: (a, b, c) %1 -> m () Source #

get :: MonadIO μ => Alias μ a %1 -> μ (a, a %1 -> μ ()) Source #

This function returns a value that is aliased in a linear pair with a function to free the linear value. Since both the value and freeing function must be consumed linearly, it is guaranteed that the returned function is the one used to free the resource.

The cleanup function can be one of two things:

  • If the returned value was the last reference, the function is the one passed as an argument to new
  • Otherwise, if this isn't the last reference to the value, the freeing function will be a no-op, but still must be called on the value.

Usage:

(x, cleanup) <- Alias.get ref
x' <- useSomehow x
cleanup x'

Using and modifying aliased resources

use :: forall (μ :: Type -> Type) a b. Alias μ a %1 -> (a %1 -> (a, b)) %1 -> (Alias μ a, b) Source #

Like useM

useM :: forall m (μ :: Type -> Type) a b. MonadIO m => Alias μ a %1 -> (a %1 -> m (a, b)) %1 -> m (Alias μ a, b) Source #

Use a reference value in an action that uses that value linearly without destroying it.

The value with the same reference count will be returned together with a byproduct of the linear computation.

modify :: forall a (μ :: Type -> Type). (a %1 -> a) %1 -> Alias μ a %1 -> Alias μ a Source #

Like modifyM

modifyM :: forall m a (μ :: Type -> Type). MonadIO m => (a %1 -> m a) %1 -> Alias μ a %1 -> m (Alias μ a) Source #

Run a monadic function that modifies a reference counted resource.

hoist :: MonadIO m => ((a %1 -> m ()) %1 -> b %1 -> μ ()) %1 -> (a %1 -> b) %1 -> Alias m a %1 -> Alias μ b Source #

Creating aliases

newAlias Source #

Arguments

:: MonadIO m 
=> (a %1 -> μ ())

Function to free resource when the last alias is released

-> a

The resource to alias

-> m (Alias μ a) 

Create an alias for a resource.