Skip to content
Snippets Groups Projects
Commit 6e437a12 authored by Ben Gamari's avatar Ben Gamari Committed by Marge Bot
Browse files

UniqSM: oneShot-ify

Part of #18202

-------------------------
Metric Decrease:
    T12707
    T3294
-------------------------
parent a9129f9f
No related branches found
No related tags found
No related merge requests found
......@@ -42,7 +42,7 @@ import GHC.Utils.Monad
import Control.Monad
import Data.Bits
import Data.Char
import GHC.Exts( Ptr(..), noDuplicate# )
import GHC.Exts( Ptr(..), noDuplicate#, oneShot )
#if MIN_VERSION_GLASGOW_HASKELL(9,1,0,0)
import GHC.Exts( Int(..), word2Int#, fetchAddWordAddr#, plusWord#, readWordOffAddr# )
#if defined(DEBUG)
......@@ -297,7 +297,18 @@ pattern UniqResult x y = (# x, y #)
-- | A monad which just gives the ability to obtain 'Unique's
newtype UniqSM result = USM { unUSM :: UniqSupply -> UniqResult result }
deriving (Functor)
-- See Note [The one-shot state monad trick] for why we don't derive this.
instance Functor UniqSM where
fmap f (USM m) = mkUniqSM $ \us ->
case m us of
(# r, us' #) -> UniqResult (f r) us'
-- | Smart constructor for 'UniqSM', as described in Note [The one-shot state
-- monad trick].
mkUniqSM :: (UniqSupply -> UniqResult a) -> UniqSM a
mkUniqSM f = USM (oneShot f)
{-# INLINE mkUniqSM #-}
instance Monad UniqSM where
(>>=) = thenUs
......@@ -305,7 +316,7 @@ instance Monad UniqSM where
instance Applicative UniqSM where
pure = returnUs
(USM f) <*> (USM x) = USM $ \us0 -> case f us0 of
(USM f) <*> (USM x) = mkUniqSM $ \us0 -> case f us0 of
UniqResult ff us1 -> case x us1 of
UniqResult xx us2 -> UniqResult (ff xx) us2
(*>) = thenUs_
......@@ -332,22 +343,22 @@ liftUSM :: UniqSM a -> UniqSupply -> (a, UniqSupply)
liftUSM (USM m) us0 = case m us0 of UniqResult a us1 -> (a, us1)
instance MonadFix UniqSM where
mfix m = USM (\us0 -> let (r,us1) = liftUSM (m r) us0 in UniqResult r us1)
mfix m = mkUniqSM (\us0 -> let (r,us1) = liftUSM (m r) us0 in UniqResult r us1)
thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b
thenUs (USM expr) cont
= USM (\us0 -> case (expr us0) of
= mkUniqSM (\us0 -> case (expr us0) of
UniqResult result us1 -> unUSM (cont result) us1)
thenUs_ :: UniqSM a -> UniqSM b -> UniqSM b
thenUs_ (USM expr) (USM cont)
= USM (\us0 -> case (expr us0) of { UniqResult _ us1 -> cont us1 })
= mkUniqSM (\us0 -> case (expr us0) of { UniqResult _ us1 -> cont us1 })
returnUs :: a -> UniqSM a
returnUs result = USM (\us -> UniqResult result us)
returnUs result = mkUniqSM (\us -> UniqResult result us)
getUs :: UniqSM UniqSupply
getUs = USM (\us0 -> case splitUniqSupply us0 of (us1,us2) -> UniqResult us1 us2)
getUs = mkUniqSM (\us0 -> case splitUniqSupply us0 of (us1,us2) -> UniqResult us1 us2)
-- | A monad for generating unique identifiers
class Monad m => MonadUnique m where
......@@ -371,9 +382,9 @@ instance MonadUnique UniqSM where
getUniquesM = getUniquesUs
getUniqueUs :: UniqSM Unique
getUniqueUs = USM (\us0 -> case takeUniqFromSupply us0 of
getUniqueUs = mkUniqSM (\us0 -> case takeUniqFromSupply us0 of
(u,us1) -> UniqResult u us1)
getUniquesUs :: UniqSM [Unique]
getUniquesUs = USM (\us0 -> case splitUniqSupply us0 of
getUniquesUs = mkUniqSM (\us0 -> case splitUniqSupply us0 of
(us1,us2) -> UniqResult (uniqsFromSupply us1) us2)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment