content: {-# language DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
  {-# language GeneralizedNewtypeDeriving #-}
  {-# language ScopedTypeVariables, TypeApplications #-}
  {-# language FlexibleInstances, MultiParamTypeClasses, TemplateHaskell, TypeFamilies #-}
  
  {-|
  Module      : Language.Python.Syntax.Ann
  Copyright   : (C) CSIRO 2017-2019
  License     : BSD3
  Maintainer  : Isaac Elliott <isaace71295@gmail.com>
  Stability   : experimental
  Portability : non-portable
  -}
  
  module Language.Python.Syntax.Ann
    ( Ann(..)
    , annot_
    , HasAnn(..)
    )
  where
  
  import Control.Lens.Lens (Lens')
  import Control.Lens.TH (makeWrapped)
  import Control.Lens.Wrapped (_Wrapped)
  import Data.Deriving (deriveEq1, deriveOrd1, deriveShow1)
  import Data.Semigroup (Semigroup)
  import Data.Monoid (Monoid)
  
  -- | Used to mark annotations in data structures, which helps with generic deriving
  newtype Ann a = Ann { getAnn :: a }
    deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Semigroup, Monoid)
  
  -- | Classy 'Lens'' for things that are annotated
  class HasAnn s where
    annot :: Lens' (s a) (Ann a)
  
  instance HasAnn Ann where
    annot = id
  
  -- | Get an annotation and forget the wrapper
  annot_ :: HasAnn s => Lens' (s a) a
  annot_ = annot._Wrapped
  
  makeWrapped ''Ann
  deriveEq1 ''Ann
  deriveOrd1 ''Ann
  deriveShow1 ''Ann
  