content: -- | This module provides facilities for generating unique names.
  module Futhark.FreshNames
    ( VNameSource (..),
      blankNameSource,
      newNameSource,
      newName,
    )
  where
  
  import Language.Futhark.Core
  import Language.Haskell.TH.Syntax (Lift)
  
  -- | A name source is conceptually an infinite sequence of names with
  -- no repeating entries.  In practice, when asked for a name, the name
  -- source will return the name along with a new name source, which
  -- should then be used in place of the original.
  --
  -- The 'Ord' instance is based on how many names have been extracted
  -- from the name source.
  newtype VNameSource = VNameSource Int
    deriving (Lift, Eq, Ord)
  
  instance Semigroup VNameSource where
    VNameSource x <> VNameSource y = VNameSource (x `max` y)
  
  instance Monoid VNameSource where
    mempty = blankNameSource
  
  -- | Produce a fresh name, using the given name as a template.
  newName :: VNameSource -> VName -> (VName, VNameSource)
  newName (VNameSource i) k = i' `seq` (VName (baseName k) i, VNameSource i')
    where
      i' = i + 1
  
  -- | A blank name source.
  blankNameSource :: VNameSource
  blankNameSource = newNameSource 0
  
  -- | A new name source that starts counting from the given number.
  newNameSource :: Int -> VNameSource
  newNameSource = VNameSource
  