content: {-# OPTIONS_GHC -Wunused-imports #-}
  
  ------------------------------------------------------------------------
  -- | Strictification of Haskell code
  ------------------------------------------------------------------------
  
  module Agda.Compiler.MAlonzo.Strict where
  
  import Agda.Utils.Haskell.Syntax
  
  -- | The function 'makeStrict' makes every function argument, case and
  -- generator pattern, and 'LocalBind' binding strict (except for those
  -- patterns that are marked as irrefutable, and anything in a
  -- 'FakeDecl' or 'FakeExp'). Note that only the outermost patterns are
  -- made strict.
  
  class MakeStrict a where
    makeStrict :: a -> a
  
  instance MakeStrict a => MakeStrict [a] where
    makeStrict = map makeStrict
  
  instance MakeStrict a => MakeStrict (Maybe a) where
    makeStrict = fmap makeStrict
  
  instance MakeStrict Module where
    makeStrict (Module m pragmas imps decls) =
      Module m pragmas imps (makeStrict decls)
  
  instance MakeStrict Decl where
    makeStrict = \case
      d@TypeDecl{}      -> d
      d@DataDecl{}      -> d
      d@TypeSig{}       -> d
      FunBind ms        -> FunBind (makeStrict ms)
      LocalBind s f rhs -> LocalBind Strict f (makeStrict rhs)
      d@PatSyn{}        -> d
      d@FakeDecl{}      -> d
      d@Comment{}       -> d
  
  instance MakeStrict Match where
    makeStrict (Match f ps rhs wh) =
      Match f (makeStrict ps) (makeStrict rhs) (makeStrict wh)
  
  instance MakeStrict Pat where
    makeStrict = \case
      p@PVar{}       -> PBangPat p
      p@PLit{}       -> PBangPat p
      PAsPat x p     -> PAsPat x (makeStrict p)
      p@PWildCard{}  -> PBangPat p
      p@PBangPat{}   -> p
      p@PApp{}       -> PBangPat p
      PatTypeSig p t -> PatTypeSig (makeStrict p) t
      p@PIrrPat{}    -> p
  
  instance MakeStrict Binds where
    makeStrict (BDecls ds) = BDecls (makeStrict ds)
  
  instance MakeStrict Rhs where
    makeStrict (UnGuardedRhs e) = UnGuardedRhs (makeStrict e)
    makeStrict (GuardedRhss rs) = GuardedRhss (makeStrict rs)
  
  instance MakeStrict GuardedRhs where
    makeStrict (GuardedRhs ss e) =
      GuardedRhs (makeStrict ss) (makeStrict e)
  
  instance MakeStrict Stmt where
    makeStrict = \case
      Qualifier e   -> Qualifier (makeStrict e)
      Generator p e -> Generator (makeStrict p) (makeStrict e)
  
  instance MakeStrict Exp where
    makeStrict e =
      case e of
        Var{}           -> e
        Con{}           -> e
        Lit{}           -> e
        InfixApp a op b -> InfixApp (makeStrict a) op (makeStrict b)
        Ann e ty        -> Ann (makeStrict e) ty
        App a b         -> App (makeStrict a) (makeStrict b)
        Lambda ps e     -> Lambda (makeStrict ps) (makeStrict e)
        Let bs e        -> Let (makeStrict bs) (makeStrict e)
        If a b c        -> If (makeStrict a) (makeStrict b) (makeStrict c)
        Case e bs       -> Case (makeStrict e) (makeStrict bs)
        ExpTypeSig e t  -> ExpTypeSig (makeStrict e) t
        NegApp e        -> NegApp (makeStrict e)
        FakeExp s       -> FakeExp s
  
  instance MakeStrict Alt where
    makeStrict (Alt pat rhs wh) =
      Alt (makeStrict pat) (makeStrict rhs) (makeStrict wh)
  