{-# OPTIONS_HADDOCK not-home #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {- | This modules contains the newtype definitions backing * "Data.Recursive.Bool" * "Data.Recursive.DualBool" * "Data.Recursive.Set" Access to the newtype contructor can break the guarantees of these modules. Only import this if you want to extend the APIs for these types. -} module Data.Recursive.Internal where import qualified Data.Set as S import qualified Data.Map as M import qualified Data.Propagator.Purify as Purify import Data.Propagator.P2 import Data.Propagator.Naive import Data.Coerce -- Not yet -- import GHC.TypeError -- | Like 'Bool', but admits recursive definitions, preferring the least solution. newtype RBool = RBool (Purify.Purify P2) -- | Like 'Bool', but admits recursive definitions, preferring the greatest solution. newtype RDualBool = RDualBool (Purify.Purify P2) -- | Like 'S.Set', but admits recursive definitions. newtype RSet a = RSet (Purify.Purify (Prop (S.Set a))) -- | Like 'M.Map', but admits recursive definitions. data RMap a b = RMap (RSet a) (M.Map a b) -- | See 'openR'. Can be extended as needed type family OpenR a where -- newtypes OpenR RBool = Purify.Purify P2 OpenR RDualBool = Purify.Purify P2 OpenR (RSet a) = Purify.Purify (Prop (S.Set a)) -- other type constructors (extended as needed) OpenR (a -> b) = OpenR a -> OpenR b OpenR [a] = [OpenR a] -- base type OpenR other = other -- | A constrainted form of 'coerce' that only resolves the newtypes from this -- module, in a directed way. -- -- This improves type inference (e.g. if 'Data.Recursive.Set.id' was using -- 'coerce' instead, it would need a type signature). -- -- The idiom is [due to Daniel Díaz Carrete](https://discourse.haskell.org/t/haskell-mini-idiom-constraining-coerce/3814?u=nomeata). openR :: Coercible a (OpenR a) => OpenR a -> a openR :: forall a. Coercible a (OpenR a) => OpenR a -> a openR = OpenR a -> a coerce