Add a default definition of primitive
- Dominant language
- Haskell
- Stars
- 123
- Forks
- 60
- PR merge metrics
- No merged PRs in 30d
Description
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.
```haskell
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).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.