Skip to content

Instantly share code, notes, and snippets.

@noughtmare
Created September 12, 2021 10:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noughtmare/3aaef4bce58154f47afe6941ea74ac4f to your computer and use it in GitHub Desktop.
Save noughtmare/3aaef4bce58154f47afe6941ea74ac4f to your computer and use it in GitHub Desktop.
Translation of the PrimMonad class to a Backpack signature with example modules that implement it.
-- vi:syntax=haskell
{-# LANGUAGE UnboxedTuples, MagicHash, TypeFamilies, StandaloneKindSignatures, RankNTypes, AllowAmbiguousTypes, ConstraintKinds, UndecidableInstances #-}
unit primmonad-indef where
signature PrimMonad where
import Data.Kind
import GHC.Prim
type C :: (* -> *) -> * -> Constraint
type family C m s
type PrimMonad m s = (Monad m, C m s)
primitive :: PrimMonad m s => (State# s -> (# State# s, a #)) -> m a
module PrimReaderT where
import Data.Kind
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class
import GHC.Prim
import qualified PrimMonad as Super
type C :: (* -> *) -> * -> Constraint
type family C m s
type instance C (ReaderT _ m) s = (Super.PrimMonad m s)
type PrimMonad m s = (Monad m, C m s)
primitive :: (m ~ ReaderT r n, PrimMonad m s) => (State# s -> (# State# s, a #)) -> m a
primitive = lift . Super.primitive
module Test (primitive) where
-- import PrimMonad
import PrimReaderT
unit primmonad-st where
module PrimST where
import Data.Kind
import GHC.ST
import GHC.Prim
type C :: (* -> *) -> * -> Constraint
type family C m s
type instance C m s = m ~ ST s
type PrimMonad m s = (Monad m, C m s)
primitive :: PrimMonad m s => (State# s -> (# State# s, a #)) -> m a
primitive = ST
unit primmonad-io where
module PrimIO where
import Data.Kind
import GHC.IO
import GHC.Prim
type C :: (* -> *) -> * -> Constraint
type family C m s
type instance C m s = (m ~ IO, s ~ RealWorld)
type PrimMonad m s = (Monad m, C m s)
primitive :: PrimMonad m s => (State# s -> (# State# s, a #)) -> m a
primitive = IO
unit main where
-- dependency primmonad-indef[PrimMonad=primmonad-io:PrimIO]
dependency primmonad-indef[PrimMonad=primmonad-st:PrimST]
module Main where
import Test
test = primitive :: _
main = putStrLn "Hello, World!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment