{-# 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)
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 = ()
inferT :: forall cls t m a. KnownTypeT cls t m a -> m a
inferT = runIdentityT . view _Wrapped'
instance PrimMonad m => PrimMonad (KnownTypeT cls t m) where
type PrimState (KnownTypeT cls t m) = PrimState m
primitive = lift . primitive