content: {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE DeriveAnyClass #-}
  module Data.Abstract.There where
  
  import Data.Order
  import Data.Hashable
  import Prettyprinter
  import Data.Abstract.Widening
  import Data.Abstract.Stable
  
  import Control.DeepSeq
  import GHC.Generics (Generic)
  
  -- | Datatype that indicates if a value in the map must be there or may not be there.
  data There = Must | May deriving (Eq, Generic, NFData)
  
  instance Show There where
    show Must = ""
    show May = "?"
  
  instance Pretty There where
    pretty = viaShow
  
  instance PreOrd There where
    Must ⊑ May = True
    Must ⊑ Must = True
    May ⊑ May = True
    _ ⊑ _ = False
  
  instance Complete There where
    Must ⊔ Must = Must
    _ ⊔ _ = May
  
  widening :: Widening There
  widening Must Must = (Stable,Must)
  widening May May   = (Stable,May)
  widening Must May  = (Unstable,May)
  widening May Must  = (Unstable,May)
  
  instance Hashable There where
    hashWithSalt s Must = s `hashWithSalt` (1::Int)
    hashWithSalt s May = s `hashWithSalt` (2::Int)
  
  may :: a -> (There,a)
  may a = (May,a)
  
  must :: a -> (There,a)
  must a = (Must,a)
  