content: {-# OPTIONS_HADDOCK hide #-}
  
  {- |
     Module      : Data.GraphViz.Attributes.Same
     Description : Consider Attributes equal on constructors.
     Copyright   : (c) Ivan Lazar Miljenovic
     License     : 3-Clause BSD-style
     Maintainer  : Ivan.Miljenovic@gmail.com
  
     This module is used when @a1 == a2@ should return @True@ if they
     are the same Attribute, even if they don't have the same value
     (typically for 'Set's).
  -}
  module Data.GraphViz.Attributes.Same
         ( SameAttr
         , SAttrs
         , toSAttr
         , unSame
         , unSameSet
         ) where
  
  import Data.GraphViz.Attributes.Complete(Attribute, Attributes, sameAttribute)
  
  import Data.Function(on)
  import qualified Data.Set as Set
  import Data.Set(Set)
  
  -- -----------------------------------------------------------------------------
  
  -- | Defined as a wrapper around 'Attribute' where equality is based
  --   solely upon the constructor, not the contents.
  newtype SameAttr = SA { getAttr :: Attribute }
                   deriving (Show, Read)
  
  instance Eq SameAttr where
    (==) = sameAttribute `on` getAttr
  
  instance Ord SameAttr where
    compare sa1 sa2
      | sa1 == sa2 = EQ
      | otherwise  = (compare `on` getAttr) sa1 sa2
  
  
  type SAttrs = Set SameAttr
  
  toSAttr :: Attributes -> SAttrs
  toSAttr = Set.fromList . map SA
  
  unSame :: SAttrs -> Attributes
  unSame = map getAttr . Set.toList
  
  unSameSet :: SAttrs -> Set Attribute
  unSameSet = Set.mapMonotonic getAttr
  