content: -- | This module provides essential tools for doing non-linear things
  -- in linear code.
  --
  -- = /Critical/ Definition: Restricted
  --
  -- In a linear function @f :: a %1-> b@, the argument @a@ must
  -- be used in a linear way. Its use is __restricted__. By contrast,
  -- an argument in a non-linear function is __unrestricted__.
  --
  -- Hence, a linear function with an argument of @Ur a@ (@Ur@ is short for
  -- /unrestricted/) can use the @a@ in an unrestricted way. That is, we have
  -- the following equivalence:
  --
  -- @
  -- (Ur a %1-> b) ≌ (a -> b)
  -- @
  --
  -- = Consumable, Dupable, Moveable classes
  --
  -- Use these classes to perform some non-linear action on linearly bound values.
  --
  -- If a type is 'Consumable', you can __consume__ it in a linear function that
  -- doesn't need that value to produce it's result:
  --
  -- > fst :: Consumable b => (a,b) %1-> a
  -- > fst (a,b) = withConsume (consume b) a
  -- >   where
  -- >     withConsume :: () %1-> a %1-> a
  -- >     withConsume () x = x
  --
  -- If a type is 'Dupable', you can __duplicate__ it as much as you like.
  --
  -- > -- checkIndex ix size_of_array
  -- > checkIndex :: Int %1-> Int %1-> Bool
  -- > checkIndex ix size = withDuplicate (dup2 ix) size
  -- >   where
  -- >     withDuplicate :: (Int, Int) %1-> Int %1-> Bool
  -- >     withDuplicate (ix,ix') size = (0 <= ix) && (ix < size)
  -- >     (<) :: Int %1-> Int %1-> Bool
  -- >     (<) = ...
  -- >
  -- >     (<=) :: Int %1-> Int %1-> Bool
  -- >     (<=) = ...
  -- >
  -- >     (&&) :: Bool %1-> Bool %1-> Bool
  -- >     (&&) = ...
  --
  -- If a type is 'Moveable', you can __move__ it inside 'Ur'
  -- and use it in any non-linear way you would like.
  --
  -- > diverge :: Int %1-> Bool
  -- > diverge ix = fromMove (move ix)
  -- >   where
  -- >     fromMove :: Ur Int %1-> Bool
  -- >     fromMove (Ur 0) = True
  -- >     fromMove (Ur 1) = True
  -- >     fromMove (Ur x) = False
  module Data.Unrestricted.Linear
    ( -- * Unrestricted
      Ur (..),
      unur,
      lift,
      lift2,
      UrT (..),
      runUrT,
      liftUrT,
      evalUrT,
  
      -- * Performing non-linear actions on linearly bound values
      Consumable (..),
      Dupable (..),
      Movable (..),
      lseq,
      dup,
      dup3,
      dup4,
      dup5,
      dup6,
      dup7,
      module Data.Unrestricted.Linear.Internal.Instances,
    )
  where
  
  import Data.Unrestricted.Linear.Internal.Consumable
  import Data.Unrestricted.Linear.Internal.Dupable
  import Data.Unrestricted.Linear.Internal.Instances
  import Data.Unrestricted.Linear.Internal.Movable
  import Data.Unrestricted.Linear.Internal.Ur
  import Data.Unrestricted.Linear.Internal.UrT
  