-- | -- Copyright: (c) 2021 Xy Ren -- License: BSD3 -- Maintainer: xy.r@outlook.com -- Stability: unstable -- Portability: non-portable (GHC only) -- -- This module contains common definitions for the @cleff@ internals. -- -- __This is an /internal/ module and its API may change even between minor versions.__ Therefore you should be -- extra careful if you're to depend on this module. module Cleff.Internal ( -- * Basic types Effect , type (~>) , type (++) , HandlerPtr (HandlerPtr, unHandlerPtr) -- * The @Any@ type , Any , pattern Any , fromAny -- * Miscellaneous , noinline ) where import Data.Kind (Type) import GHC.Exts (Any) import Unsafe.Coerce (unsafeCoerce) -- | The type of effects. An effect @e m a@ takes an effect monad type @m :: 'Type' -> 'Type'@ and a result type -- @a :: 'Type'@. type Effect = (Type -> Type) -> Type -> Type -- | A natural transformation from @f@ to @g@. With this, instead of writing -- -- @ -- runSomeEffect :: 'Cleff.Eff' (SomeEffect : es) a -> 'Cleff.Eff' es a -- @ -- -- you can write: -- -- @ -- runSomeEffect :: 'Cleff.Eff' (SomeEffect : es) ~> 'Cleff.Eff' es -- @ type f ~> g = ∀ a. f a -> g a -- | Type level list concatenation. type family xs ++ ys where '[] ++ ys = ys (x : xs) ++ ys = x : (xs ++ ys) infixr 5 ++ -- | A pointer to an effect handler. type role HandlerPtr nominal newtype HandlerPtr (e :: Effect) = HandlerPtr { HandlerPtr e -> Int unHandlerPtr :: Int } -- | A pattern synonym for coercing values to and from 'Any'. This is not any less unsafe but prevents possivle -- misuses. pattern Any :: forall a. a -> Any pattern $bAny :: a -> Any $mAny :: forall r a. Any -> (a -> r) -> (Void# -> r) -> r Any {Any -> a fromAny} <- (unsafeCoerce -> fromAny) where Any = a -> Any forall a b. a -> b unsafeCoerce {-# COMPLETE Any #-} -- | Magic function that tells the compiler /not/ to inline the argument. noinline :: a -> a noinline :: a -> a noinline a x = a x {-# NOINLINE noinline #-}