{-# LANGUAGE BlockArguments #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE QualifiedDo #-} {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE UnliftedNewtypes #-} {-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} module Control.Concurrent.DivideConquer.Utils.OnceChan.Linear ( Sink, Source, new, put, take, ) where import Control.Concurrent.DivideConquer.Utils.OnceChan.Linear.Unlifted import Control.Monad.Borrow.Pure.Affine import Control.Monad.Borrow.Pure.Affine.Unsafe (unsafeAff) import Control.Monad.Borrow.Pure.BO import Control.Monad.Borrow.Pure.Lifetime.Token.Unsafe ( LinearOnly (..), LinearOnlyWitness (..), ) import Data.Unrestricted.Linear import Prelude.Linear hiding (take) import Unsafe.Linear qualified as Unsafe data Sink a = Sink (Sink# a) data Source a = Source (Source# a) type role Sink nominal type role Source representational new :: Linearly %1 -> (Sink a, Source a) {-# INLINE new #-} new :: forall a. Linearly %1 -> (Sink a, Source a) new Linearly lin = case Linearly %1 -> (# Sink# a, Source# a #) forall a. Linearly %1 -> (# Sink# a, Source# a #) new# Linearly lin of (# Sink# a sink, Source# a source #) -> (Sink# a -> Sink a forall a. Sink# a -> Sink a Sink Sink# a sink, Source# a -> Source a forall a. Source# a -> Source a Source Source# a source) instance LinearOnly (Sink a) where linearOnly :: LinearOnlyWitness (Sink a) linearOnly = LinearOnlyWitness (Sink a) forall {k} (a :: k). LinearOnlyWitness a UnsafeLinearOnly instance LinearOnly (Source a) where linearOnly :: LinearOnlyWitness (Source a) linearOnly = LinearOnlyWitness (Source a) forall {k} (a :: k). LinearOnlyWitness a UnsafeLinearOnly instance Affine (Sink a) where aff :: Sink a %1 -> Aff (Sink a) aff = Sink a %1 -> Aff (Sink a) forall a. a %1 -> Aff a unsafeAff instance Consumable (Sink a) where consume :: Sink a %1 -> () consume = (Sink a -> ()) %1 -> Sink a %1 -> () forall a b (p :: Multiplicity) (x :: Multiplicity). (a %p -> b) %1 -> a %x -> b Unsafe.toLinear \(Sink !Sink# a _) -> () instance Consumable (Source a) where consume :: Source a %1 -> () consume = (Source a -> ()) %1 -> Source a %1 -> () forall a b (p :: Multiplicity) (x :: Multiplicity). (a %p -> b) %1 -> a %x -> b Unsafe.toLinear \(Source !Source# a _) -> () instance Affine (Source a) where aff :: Source a %1 -> Aff (Source a) aff = Source a %1 -> Aff (Source a) forall a. a %1 -> Aff a unsafeAff take :: Source a %1 -> BO α a {-# INLINE take #-} take :: forall a (α :: Lifetime). Source a %1 -> BO α a take (Source Source# a v) = a %1 -> BO α a forall a (α :: Lifetime). a %1 -> BO α a evaluateBO (a %1 -> BO α a) -> a %1 -> BO α a forall a b (p :: Multiplicity) (q :: Multiplicity). (a %p -> b) %q -> a %p -> b $ Source# a %1 -> a forall a. Source# a %1 -> a take# Source# a v put :: Sink a %1 -> a %1 -> BO α () {-# INLINE put #-} put :: forall a (α :: Lifetime). Sink a %1 -> a %1 -> BO α () put (Sink Sink# a v) !a a = () %1 -> BO α () forall a (α :: Lifetime). a %1 -> BO α a evaluateBO (() %1 -> BO α ()) -> () %1 -> BO α () forall a b (p :: Multiplicity) (q :: Multiplicity). (a %p -> b) %q -> a %p -> b $ Sink# a %1 -> a %1 -> () forall a. Sink# a %1 -> a %1 -> () put# Sink# a v a a