module Haskell.Extra.Dec where

open import Haskell.Prelude
open import Haskell.Extra.Refinement
open import Agda.Primitive

private variable
   : Level
  P : Set

@0 Reflects : Set   Bool  Set 
Reflects P True  = P
Reflects P False = P  

of : {b : Bool}  if b then P else (P  )  Reflects P b
of {b = False} np = np
of {b = True}  p  = p

invert :  {b}  Reflects P b  if b then P else (P  )
invert {b = False} np = np
invert {b = True}  p  = p

extractTrue :  { b }   true : b  True   Reflects P b  P
extractTrue {b = True} p = p

extractFalse :  { b }   true : b  False   Reflects P b  (P  )
extractFalse {b = False} np = np

mapReflects :  {cond}  (a  b)  (b  a)
             Reflects a cond  Reflects b cond
mapReflects {cond = False} f g x = x  g
mapReflects {cond = True}  f g x = f x

Dec :  {}  @0 Set   Set 
Dec P =  Bool (Reflects P)
{-# COMPILE AGDA2HS Dec inline #-}

mapDec : @0 (a  b)
        @0 (b  a)
        Dec a  Dec b
mapDec f g (True   x ) = True   f x   
mapDec f g (False  h ) = False  h  g 
{-# COMPILE AGDA2HS mapDec transparent #-}

ifDec : Dec a  (@0 {{a}}  b)  (@0 {{a  }}  b)  b
ifDec (b  p ) x y = if b then  where {{refl}}  x {{p}}) else  where {{refl}}  y {{p}})
{-# COMPILE AGDA2HS ifDec inline #-}