content: {-# LANGUAGE FlexibleInstances       #-}
  {-# LANGUAGE MultiParamTypeClasses   #-}
  {-# LANGUAGE QuantifiedConstraints   #-}
  {-# LANGUAGE TypeFamilies            #-}
  {-# LANGUAGE TypeOperators           #-}
  {-# LANGUAGE UndecidableInstances    #-}
  {-# LANGUAGE UndecidableSuperClasses #-}
  
  -- | A module providing a tool for making sure that each type from a particular universe implements
  -- 'KnownTypeAst', 'ReadKnown' and 'MakeKnown'. Kept separate from the modules defining those
  -- classes in order not to introduce dependencies between them and because this extra safety is
  -- scary looking and it's best to keep it separate from what is necessary.
  module PlutusCore.Builtin.TestKnown
      ( TestTypesFromTheUniverseAreAllKnown
      ) where
  
  import PlutusCore.Builtin.KnownType
  import PlutusCore.Builtin.KnownTypeAst
  
  import Universe
  
  -- | For providing a 'KnownTypeAst' instance for a built-in type it's enough for that type to
  -- satisfy 'KnownBuiltinTypeAst'.
  class    (forall tyname. KnownBuiltinTypeAst tyname uni a => KnownTypeAst tyname uni a) =>
      ImplementedKnownTypeAst uni a
  instance (forall tyname. KnownBuiltinTypeAst tyname uni a => KnownTypeAst tyname uni a) =>
      ImplementedKnownTypeAst uni a
  
  -- | For providing a 'ReadKnownIn' instance for a built-in type it's enough for that type to
  -- satisfy 'KnownBuiltinTypeIn'.
  class    (forall val. KnownBuiltinTypeIn uni val a => ReadKnownIn uni val a) =>
      ImplementedReadKnownIn uni a
  instance (forall val. KnownBuiltinTypeIn uni val a => ReadKnownIn uni val a) =>
      ImplementedReadKnownIn uni a
  
  -- | For providing a 'MakeKnownIn' instance for a built-in type it's enough for that type to
  -- satisfy 'KnownBuiltinTypeIn'.
  class    (forall val. KnownBuiltinTypeIn uni val a => MakeKnownIn uni val a) =>
      ImplementedMakeKnownIn uni a
  instance (forall val. KnownBuiltinTypeIn uni val a => MakeKnownIn uni val a) =>
      ImplementedMakeKnownIn uni a
  
  -- | An instance of this class not having any constraints ensures that every type (according to
  -- 'Everywhere') from the universe has 'KnownTypeAst, 'ReadKnownIn' and 'MakeKnownIn' instances.
  class
      ( uni `Everywhere` ImplementedKnownTypeAst uni
      , uni `Everywhere` ImplementedReadKnownIn uni
      , uni `Everywhere` ImplementedMakeKnownIn uni
      ) => TestTypesFromTheUniverseAreAllKnown uni
  