content: {-# LANGUAGE BangPatterns #-}
  {-# LANGUAGE LambdaCase #-}
  {-# LANGUAGE LinearTypes #-}
  {-# LANGUAGE PolyKinds #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE TypeOperators #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  -- TODO: Disabled while we still support GHC 9.2 to enable
  -- the import of the empty TypeEq module there.
  {-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
  {-# OPTIONS_HADDOCK hide #-}
  
  -- | This is a very very simple prelude, which doesn't depend on anything else
  -- in the linear-base library.
  module Prelude.Linear.Internal
    ( module Prelude.Linear.Internal,
      module Prelude.Linear.Internal.TypeEq,
    )
  where
  
  import Data.Coerce
  import Data.Functor.Identity
  import GHC.Exts (TYPE)
  import Prelude.Linear.Internal.TypeEq
  
  -- A note on implementation: to avoid silly mistakes, very easy functions are
  -- simply reimplemented here. For harder function, we reuse the Prelude
  -- definition and make an unsafe cast.
  
  ($) :: forall {rep} a (b :: TYPE rep) p q. (a %p -> b) %q -> a %p -> b
  ($) f x = f x
  
  infixr 0 $ -- same fixity as base.$
  
  (&) :: forall {rep} a (b :: TYPE rep) p q. a %p -> (a %p -> b) %q -> b
  x & f = f x
  
  infixl 1 & -- same fixity as base.&
  
  id :: a %q -> a
  id x = x
  
  const :: a %q -> b -> a
  const x _ = x
  
  -- | @seq x y@ only forces @x@ to head normal form, therefore is not guaranteed
  -- to consume @x@ when the resulting computation is consumed. Therefore, @seq@
  -- cannot be linear in it's first argument.
  seq :: a -> b %q -> b
  seq !_ y = y
  
  infixr 0 `seq` -- same fixity as base.seq
  
  ($!) :: forall {rep} a (b :: TYPE rep) p q. (a %p -> b) %q -> a %p -> b
  ($!) f !a = f a
  
  infixr 0 $! -- same fixity as base.$!
  
  curry :: ((a, b) %p -> c) %q -> a %p -> b %p -> c
  curry f x y = f (x, y)
  
  uncurry :: (a %p -> b %p -> c) %q -> (a, b) %p -> c
  uncurry f (x, y) = f x y
  
  -- | Beware: @(.)@ is not compatible with the standard one because it is
  -- higher-order and we don't have sufficient multiplicity polymorphism yet.
  (.) :: forall {rep} b (c :: TYPE rep) a q m n. (b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
  f . g = \x -> f (g x)
  
  infixr 9 . -- same fixity as base..
  
  -- | Convenience operator when a higher-order function expects a non-linear
  -- arrow but we have a linear arrow.
  forget :: forall {rep} a (b :: TYPE rep). (a %1 -> b) %1 -> a -> b
  forget f a = f a
  
  -- XXX: Temporary, until newtype record projections are linear.
  runIdentity' :: Identity a %p -> a
  runIdentity' (Identity x) = x
  
  -- | A linear version of 'Data.Coerce.coerce' for types of kind 'Data.Kind.Type'.
  lcoerce :: forall a b. (Coercible a b) => a %1 -> b
  lcoerce = coerce ((\x -> x) :: a %1 -> a)
  {-# INLINE CONLIKE lcoerce #-}
  