content: {-# LANGUAGE MagicHash #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  
  -- | This module defines a stream-like type named 'Replicator', which is
  -- mainly used in the definition of the 'Data.Unrestricted.Linear.Dupable'
  -- class to provide efficient linear duplication.
  -- The API of 'Replicator' is close to the one of an infinite stream: it
  -- can either produce a new value linearly (with 'next' or 'next#'), or be
  -- linearly discarded (with 'consume' or 'extract').
  --
  -- A crucial aspect, from a performance standpoint, is that the 'pure' function
  -- (which takes an unrestricted argument) is implemented efficiently: the
  -- 'Replicator' returns /the same/ value on each call to 'next'. That is, the
  -- pointer is always shared. This will allow 'Data.Unrestricted.Linear.Movable'
  -- types to be given an efficient instance of 'Data.Unrestricted.Linear.Dupable'.
  -- Instances of both 'Data.Unrestricted.Linear.Movable' and
  -- 'Data.Unrestricted.Linear.Dupable' typically involve deep copies. The
  -- implementation of 'pure' lets us make sure that, for @Movable@ types, only one
  -- deep copy is performed, rather than one per additional replica.
  --
  -- Strictly speaking, the implementation of '(<*>)' plays a role in all this as
  -- well:
  -- For two 'pure' 'Replicators' @fs@ and @as@, @fs \<*\> as@  is a pure
  -- 'Replicator'. Together, 'pure' and '(<*>)' form the
  -- 'Data.Functor.Linear.Applicative' instance of 'Replicator'.
  module Data.Replicator.Linear
    ( Replicator,
      consume,
      duplicate,
      map,
      pure,
      (<*>),
      next,
      next#,
      take,
      extract,
      extend,
      Elim,
      elim,
    )
  where
  
  import Data.Replicator.Linear.Internal
  import Data.Replicator.Linear.Internal.Instances ()
  