{-# LANGUAGE MagicHash #-}

module Control.Monad.Borrow.Pure.Utils (
  module Control.Monad.Borrow.Pure.Utils,
) where

import Data.Coerce (Coercible)
import Data.Coerce qualified
import Data.Type.Coercion (Coercion, coerceWith)
import Data.Unrestricted.Linear
import GHC.Base (UnliftedType)
import Unsafe.Linear qualified as Unsafe

coerceLin :: (Coercible a b) => a %1 -> b
{-# INLINE coerceLin #-}
coerceLin :: forall a b. Coercible a b => a %1 -> b
coerceLin = (a -> b) %1 -> a %1 -> b
forall a b (p :: Multiplicity) (x :: Multiplicity).
(a %p -> b) %1 -> a %x -> b
Unsafe.toLinear a -> b
forall a b. Coercible a b => a -> b
Data.Coerce.coerce

lseq# :: forall a (s :: UnliftedType). (Consumable a) => a %1 -> s %1 -> s
{-# INLINE lseq# #-}
lseq# :: forall a (s :: UnliftedType). Consumable a => a %1 -> s %1 -> s
lseq# a
a = case a %1 -> ()
forall a. Consumable a => a %1 -> ()
consume a
a of
  () -> \s
b -> s
b

coerceWithLin :: Coercion a b %1 -> a %1 -> b
{-# INLINE coerceWithLin #-}
coerceWithLin :: forall a b. Coercion a b %1 -> a %1 -> b
coerceWithLin = (Coercion a b -> a -> b) %1 -> Coercion a b %1 -> a %1 -> b
forall a b c (p :: Multiplicity) (q :: Multiplicity)
       (x :: Multiplicity) (y :: Multiplicity).
(a %p -> b %q -> c) %1 -> a %x -> b %y -> c
Unsafe.toLinear2 Coercion a b -> a -> b
forall a b. Coercion a b -> a -> b
coerceWith

infixr 1 >>>

(>>>) :: (a %1 -> b) -> (b %1 -> c) -> a %1 -> c
{-# INLINE (>>>) #-}
>>> :: forall a b c. (a %1 -> b) -> (b %1 -> c) -> a %1 -> c
(>>>) a %1 -> b
f b %1 -> c
g = \a
x -> b %1 -> c
g (a %1 -> b
f a
x)