reference-counting 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+18/−10 lines, 3 filesdep ~containersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: containers
API changes (from Hackage documentation)
- Data.Linear.Alias: instance (GHC.Generics.Generic a, Data.Linear.Alias.Internal.Fields (GHC.Generics.Rep a)) => Data.Linear.Alias.Shareable m (GHC.Generics.Generically a)
- Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields (GHC.Generics.K1 i (Data.Linear.Alias.Internal.Alias m a))
- Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields GHC.Generics.U1
- Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields GHC.Generics.V1
- Data.Linear.Alias.Internal: instance forall k (a :: k -> *) (b :: k -> *). (Data.Linear.Alias.Internal.Fields a, Data.Linear.Alias.Internal.Fields b) => Data.Linear.Alias.Internal.Fields (a GHC.Generics.:*: b)
- Data.Linear.Alias.Internal: instance forall k (a :: k -> *) (b :: k -> *). (Data.Linear.Alias.Internal.Fields a, Data.Linear.Alias.Internal.Fields b) => Data.Linear.Alias.Internal.Fields (a GHC.Generics.:+: b)
- Data.Linear.Alias.Internal: instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Data.Linear.Alias.Internal.Fields f => Data.Linear.Alias.Internal.Fields (GHC.Generics.M1 i c f)
+ Data.Linear.Alias: ($dmshare) :: (Shareable m a, Generic a, Fields (Rep a), MonadIO m) => a %1 -> m (a, a)
+ Data.Linear.Alias: instance (GHC.Internal.Generics.Generic a, Data.Linear.Alias.Internal.Fields (GHC.Internal.Generics.Rep a)) => Data.Linear.Alias.Shareable m (GHC.Internal.Generics.Generically a)
+ Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields (GHC.Internal.Generics.K1 i (Data.Linear.Alias.Internal.Alias m a))
+ Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields GHC.Internal.Generics.U1
+ Data.Linear.Alias.Internal: instance Data.Linear.Alias.Internal.Fields GHC.Internal.Generics.V1
+ Data.Linear.Alias.Internal: instance forall k (a :: k -> *) (b :: k -> *). (Data.Linear.Alias.Internal.Fields a, Data.Linear.Alias.Internal.Fields b) => Data.Linear.Alias.Internal.Fields (a GHC.Internal.Generics.:*: b)
+ Data.Linear.Alias.Internal: instance forall k (a :: k -> *) (b :: k -> *). (Data.Linear.Alias.Internal.Fields a, Data.Linear.Alias.Internal.Fields b) => Data.Linear.Alias.Internal.Fields (a GHC.Internal.Generics.:+: b)
+ Data.Linear.Alias.Internal: instance forall k (f :: k -> *) i (c :: GHC.Internal.Generics.Meta). Data.Linear.Alias.Internal.Fields f => Data.Linear.Alias.Internal.Fields (GHC.Internal.Generics.M1 i c f)
- Data.Linear.Alias: class Forgettable m a
+ Data.Linear.Alias: class Forgettable (m :: Type -> Type) a
- Data.Linear.Alias: class Shareable m a
+ Data.Linear.Alias: class Shareable (m :: Type -> Type) a
- Data.Linear.Alias: data Alias m a
+ Data.Linear.Alias: data Alias (m :: Type -> Type) a
- Data.Linear.Alias: forget :: (Forgettable m a, MonadIO m) => a %1 -> m ()
+ Data.Linear.Alias: forget :: Forgettable m a => a %1 -> m ()
- Data.Linear.Alias: modify :: (a %1 -> a) %1 -> Alias μ a %1 -> Alias μ a
+ Data.Linear.Alias: modify :: forall a (μ :: Type -> Type). (a %1 -> a) %1 -> Alias μ a %1 -> Alias μ a
- Data.Linear.Alias: modifyM :: MonadIO m => (a %1 -> m a) %1 -> Alias μ a %1 -> m (Alias μ a)
+ Data.Linear.Alias: modifyM :: forall m a (μ :: Type -> Type). MonadIO m => (a %1 -> m a) %1 -> Alias μ a %1 -> m (Alias μ a)
- Data.Linear.Alias: share :: (Shareable m a, Generic a, Fields (Rep a)) => MonadIO m => a %1 -> m (a, a)
+ Data.Linear.Alias: share :: Shareable m a => a %1 -> m (a, a)
- Data.Linear.Alias: use :: Alias μ a %1 -> (a %1 -> (a, b)) %1 -> (Alias μ a, b)
+ Data.Linear.Alias: use :: forall (μ :: Type -> Type) a b. Alias μ a %1 -> (a %1 -> (a, b)) %1 -> (Alias μ a, b)
- Data.Linear.Alias: useM :: MonadIO m => Alias μ a %1 -> (a %1 -> m (a, b)) %1 -> m (Alias μ a, b)
+ Data.Linear.Alias: useM :: forall m (μ :: Type -> Type) a b. MonadIO m => Alias μ a %1 -> (a %1 -> m (a, b)) %1 -> m (Alias μ a, b)
- Data.Linear.Alias.Internal: [Alias] :: (a %1 -> m ()) -> !Counter -> a -> Alias m a
+ Data.Linear.Alias.Internal: [Alias] :: forall a (m :: Type -> Type). (a %1 -> m ()) -> !Counter -> a -> Alias m a
- Data.Linear.Alias.Internal: class Fields rep
+ Data.Linear.Alias.Internal: class Fields (rep :: k -> Type)
- Data.Linear.Alias.Internal: data Alias m a
+ Data.Linear.Alias.Internal: data Alias (m :: Type -> Type) a
- Data.Linear.Alias.Internal: fields :: Fields rep => rep a -> [SomeAlias]
+ Data.Linear.Alias.Internal: fields :: forall (a :: k). Fields rep => rep a -> [SomeAlias]
- Data.Linear.Alias.Unsafe: dec :: MonadIO m => Alias μ a %1 -> m (Ur a)
+ Data.Linear.Alias.Unsafe: dec :: forall m (μ :: Type -> Type) a. MonadIO m => Alias μ a %1 -> m (Ur a)
- Data.Linear.Alias.Unsafe: get :: Alias m' a -> a
+ Data.Linear.Alias.Unsafe: get :: forall (m' :: Type -> Type) a. Alias m' a -> a
- Data.Linear.Alias.Unsafe: inc :: MonadIO m => Alias m' a %1 -> m (Alias m' a)
+ Data.Linear.Alias.Unsafe: inc :: forall m (m' :: Type -> Type) a. MonadIO m => Alias m' a %1 -> m (Alias m' a)
Files
reference-counting.cabal view
@@ -20,7 +20,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.0+version: 0.2.0.0 -- A short (one-line) description of the package. synopsis: A reference counting library to alias linear resources@@ -44,7 +44,7 @@ category: Data build-type: Simple-tested-with: GHC ==9.8.2+tested-with: GHC ==9.12.2 extra-doc-files: CHANGELOG.md README.md@@ -69,7 +69,7 @@ atomic-counter >= 0.1.2 && < 0.2, -- only for instances of Aliasable- containers >= 0.6 && < 0.7,+ containers >= 0.6 && < 0.8, hs-source-dirs: src default-language: GHC2021
src/Data/Linear/Alias.hs view
@@ -43,11 +43,10 @@ => (a ⊸ μ ()) -- ^ Function to free resource when the last alias is released ⊸ a -- ^ The resource to alias ⊸ m (Alias μ a)-newAlias freeC x = Linear.do+newAlias = Unsafe.toLinear \freeC x -> Linear.do Ur c <- liftSystemIOU $ Counter.new 1 pure $ Alias freeC c x - -- | 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@@ -110,8 +109,9 @@ hoist :: MonadIO m => ((a ⊸ m ()) ⊸ b ⊸ μ ()) ⊸ (a ⊸ b) ⊸ Alias m a ⊸ Alias μ b-hoist freeAB f (Alias freeA counter x) = Alias (freeAB freeA) counter (f x)+hoist = Unsafe.toLinear \freeAB f (Alias freeA counter x) -> Alias (freeAB freeA) counter (f x) +{-# INLINABLE get #-} ----- Signature classes ----- @@ -135,6 +135,7 @@ else -- No-op pure (Unsafe.toLinear (\_ -> ()) x)+ {-# INLINE forget #-} -- this was showing up in profiles class Shareable m a where -- | Share a linear resource@@ -155,7 +156,7 @@ consume <$> traverse' (\(SomeAlias alias) -> Linear.do a' <- Unsafe.Alias.inc alias -- increment reference count- Unsafe.toLinear const (pure ()) a') (countedFields x)+ Unsafe.toLinear2 const (pure ()) a') (countedFields x) -- It's safe to return two references to the pointer because we've -- incremented the reference count of all nested aliases. Both references must be used@@ -170,6 +171,7 @@ -- Implement manually since there is no Generic instance for Alias alias' <- Unsafe.Alias.inc alias'' pure $ Unsafe.toLinear (\alias -> (alias, alias)) alias'+ {-# INLINE share #-} -- this was showing up in profiles instance (Generic a, Fields (Rep a)) => Shareable m (Generically a) where share = Unsafe.toLinear $ \(Generically x) -> Linear.do@@ -177,7 +179,7 @@ consume <$> traverse' (\(SomeAlias alias) -> Linear.do a' <- Unsafe.Alias.inc alias -- increment reference count- Unsafe.toLinear const (pure ()) a') (countedFields x)+ Unsafe.toLinear2 const (pure ()) a') (countedFields x) return (Generically x, Generically x) -- Just like 'share', but doesn't require the action to be performed whithin@@ -213,7 +215,7 @@ {-# INLINE forget #-} instance Forgettable m a => Forgettable m (IM.IntMap a) where- forget im = consume <$> traverse' forget (IM.elems im)+ forget im = consume <$> traverse' forget (Unsafe.toLinear IM.elems im) {-# INLINE forget #-} instance Forgettable m a => Forgettable m [a] where@@ -229,7 +231,7 @@ instance Shareable m a => Shareable m (IM.IntMap a) where share im = B.bimap (Unsafe.toLinear IM.fromList) (Unsafe.toLinear IM.fromList) . unzip <$>- traverse' share (IM.toList im)+ traverse' share (Unsafe.toLinear IM.toList im) {-# INLINE share #-} instance Shareable m a => Shareable m [a] where@@ -238,6 +240,8 @@ instance Forgettable m Int where forget = pure . consume+ {-# INLINE forget #-} instance Shareable m Int where share = pure . dup2+ {-# INLINE share #-}
src/Data/Linear/Alias/Unsafe.hs view
@@ -42,3 +42,7 @@ get :: Alias m' a -> a get (Alias _ _ a) = a +-- We always want MonadIO to specialise here, and really it might as well just be inlined.+-- (This showed up in ghengin profiles!)+{-# INLINE inc #-}+{-# INLINE dec #-}