content: {-# language DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveGeneric #-}
  {-# language InstanceSigs, ScopedTypeVariables, TypeApplications #-}
  {-# language LambdaCase #-}
  
  {-|
  Module      : Language.Python.Syntax.Operator.Unary
  Copyright   : (C) CSIRO 2017-2019
  License     : BSD3
  Maintainer  : Isaac Elliott <isaace71295@gmail.com>
  Stability   : experimental
  Portability : non-portable
  
  Unary operators
  -}
  
  module Language.Python.Syntax.Operator.Unary where
  
  import Control.Lens.Lens (Lens', lens)
  import Data.Generics.Product.Typed (typed)
  import GHC.Generics (Generic)
  
  import Language.Python.Syntax.Ann
  import Language.Python.Syntax.Whitespace
  
  -- | An 'UnOp' is a unary operator in Python, such as @-@ for negation.
  -- An operator is stored with an annotation and its trailing whitespace.
  data UnOp a
    -- | @-a@
    = Negate (Ann a) [Whitespace]
    -- | @+a@
    | Positive (Ann a) [Whitespace]
    -- | @~a@
    | Complement (Ann a) [Whitespace]
    deriving (Eq, Show, Functor, Foldable, Traversable, Generic)
  
  instance HasAnn UnOp where
    annot :: forall a. Lens' (UnOp a) (Ann a)
    annot = typed @(Ann a)
  
  instance HasTrailingWhitespace (UnOp a) where
    trailingWhitespace =
      lens
        (\case
           Negate _ a -> a
           Positive _ a -> a
           Complement _ a -> a)
        (\op ws ->
           case op of
             Negate a _ -> Negate a ws
             Positive a _ -> Positive a ws
             Complement a _ -> Complement a ws)
  