module Lang.Hask.SumOfProdVal where

import FP
import Lang.Hask.Semantics
import Literal
import DataCon

newtype SumOfProdVal ν   = SumOfProdVal { unSumOfProdVal :: SumOfProd (ν  ) }
  deriving (Eq, Ord, Buildable (ν  ), Bot, Join, JoinLattice, Meet, Neg, Pretty)

sumOfProdValConcretize :: (Ord b) => (ν   -> ConstructiveClassical b) -> SumOfProdVal ν   -> SetWithTop b
sumOfProdValConcretize f = sumOfProdConcretize f . unSumOfProdVal

instance (Ord , Ord , Ord (ν  ), Val   ConstructiveClassical ν) => Val   SetWithTop (SumOfProdVal ν) where
  botI        :: SumOfProdVal ν                                    ; botI        = single botI
  litI        :: Literal -> SumOfProdVal ν                         ; litI        = single . litI
  litTestE    :: Literal -> SumOfProdVal ν   -> SetWithTop Bool    ; litTestE    = sumOfProdValConcretize . litTestE
  dataI       :: Data   -> SumOfProdVal ν                      ; dataI       = single . dataI
  dataAnyI    :: DataCon -> SumOfProdVal ν                         ; dataAnyI    = single . dataAnyI
  dataE       :: SumOfProdVal ν   -> SetWithTop (Data  )       ; dataE       = sumOfProdValConcretize dataE
  funCloI     :: FunClo   -> SumOfProdVal ν                    ; funCloI     = single . funCloI
  funCloE     :: SumOfProdVal ν   -> SetWithTop (FunClo  )     ; funCloE     = sumOfProdValConcretize funCloE
  thunkCloI   :: ThunkClo   -> SumOfProdVal ν                  ; thunkCloI   = single . thunkCloI
  thunkCloE   :: SumOfProdVal ν   -> SetWithTop (ThunkClo  )   ; thunkCloE   = sumOfProdValConcretize thunkCloE
  forcedI     :: Forced   -> SumOfProdVal ν                    ; forcedI     = single . forcedI
  forcedE     :: SumOfProdVal ν   -> SetWithTop (Forced  )     ; forcedE     = sumOfProdValConcretize forcedE
  refI        :: Ref   -> SumOfProdVal ν                       ; refI        = single . refI
  refAnyI     :: SumOfProdVal ν                                    ; refAnyI     = single refAnyI
  refE        :: SumOfProdVal ν   -> SetWithTop (Ref  )        ; refE        = sumOfProdValConcretize refE
  konCloI     :: KonClo   -> SumOfProdVal ν                    ; konCloI     = single . konCloI
  konCloE     :: SumOfProdVal ν   -> SetWithTop (KonClo  )     ; konCloE     = sumOfProdValConcretize konCloE
  konMemoCloI :: KonMemoClo   -> SumOfProdVal ν                ; konMemoCloI = single . konMemoCloI
  konMemoCloE :: SumOfProdVal ν   -> SetWithTop (KonMemoClo  ) ; konMemoCloE = sumOfProdValConcretize konMemoCloE