typelevel-1.2.2: src/Type/Inference.hs
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Type.Inference where
import Prelude
import Data.Typeable
import Control.Applicative
import Control.Lens
import Control.Monad.Catch
import Control.Monad.Fix
import Control.Monad.Identity
import Control.Monad.Trans
import Control.Monad.Trans.Identity
import Control.Monad.Primitive
import GHC.Exts (Constraint)
-- === Definitions ===
-- | The Inferable type class describes a monad with a functional dependency on the given type.
-- It allows for writing polymorphic code and ensuring Haskell that the type will be resolved while
-- evaluating the monadic stack.
type KnownType cls t = KnownTypeT cls t Identity
newtype KnownTypeT (cls :: ck) (t :: tk) (m :: * -> *) (a :: *) = KnownTypeT (IdentityT m a) deriving (Show, Functor, Monad, MonadIO, MonadFix, MonadTrans, Applicative, MonadThrow, MonadCatch, MonadMask, MonadPlus, Alternative)
makeWrapped ''KnownTypeT
type family Infer (p :: k) m where
Infer p (KnownTypeT p t m) = t
Infer p (t m) = Infer p m
type family TryInfer (p :: k) m a :: Constraint where
TryInfer p (KnownTypeT p t m) a = (a ~ t)
TryInfer p (t m) a = TryInfer p m a
TryInfer p m a = ()
-- === Utils === --
inferT :: forall cls t m a. KnownTypeT cls t m a -> m a
inferT = runIdentityT . view _Wrapped'
-- === Instances ===
-- Primitive
instance PrimMonad m => PrimMonad (KnownTypeT cls t m) where
type PrimState (KnownTypeT cls t m) = PrimState m
primitive = lift . primitive