Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a default definition of primitive #228

Open
treeowl opened this issue Feb 6, 2019 · 1 comment
Open

Add a default definition of primitive #228

treeowl opened this issue Feb 6, 2019 · 1 comment

Comments

@treeowl
Copy link
Collaborator

treeowl commented Feb 6, 2019

Almost all PrimMonad instances are monad transformers of other PrimMonad instances. We can give PrimState a default definition and use DefaultSignatures to give primitive one as well. We can use TypeError to produce good error messages when the defaults don't come close to making sense.

class Monad m => PrimMonad m where
  -- | State token type
  type PrimState m
  -- Default for transformed PrimMonad instances
  type PrimState m = PrimState (Arg m)

  -- | Execute a primitive operation
  primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
  default primitive
    :: (IsTransformed m, m ~ t n, PrimMonad n, MonadTrans t, PrimState (t n) ~ PrimState n)
    => (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
  primitive = lift . primitive
  {-# INLINE primitive #-}

type family Arg (m :: * -> *) :: * -> * where
  Arg (_t n) = n

type family IsTransformed (m :: * -> *) :: Constraint where
  IsTransformed (_t (_n :: * -> *)) = ()
  IsTransformed m = TypeError
            ('Text "Cannot use defaults for instance " :$$:
             'Text "    " :<>: 'ShowType (PrimMonad m) :$$:
             'Text "because" :$$:
             'Text "    " :<>: 'ShowType m :$$:
             'Text "is not a transformed monad." )

The only error messages that aren't so great are when users write primitive implementations but forget the PrimState ones. I don't know how to fix that without ending up with a bunch of duplicate errors in some cases (which seems like a GHC issue).

@chessai
Copy link
Member

chessai commented May 1, 2019

I'm +1 on this, though can it instead be a top-level function, like defaultPrimitive/primitiveDefault, or something? Default signatures look so ugly on haddocks. Though a default signature does save users from an extra line of typing. The top-level thing is just something to consider, wondering what others' thoughts are.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants