diff options
-rw-r--r-- | compiler/GHC/Utils/Monad/State.hs | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/compiler/GHC/Utils/Monad/State.hs b/compiler/GHC/Utils/Monad/State.hs index c7b9e3f591..997137525b 100644 --- a/compiler/GHC/Utils/Monad/State.hs +++ b/compiler/GHC/Utils/Monad/State.hs @@ -1,13 +1,27 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE PatternSynonyms #-} module GHC.Utils.Monad.State where import GHC.Prelude -newtype State s a = State { runState' :: s -> (# a, s #) } +import GHC.Exts (oneShot) + +newtype State s a = State' { runState' :: s -> (# a, s #) } deriving (Functor) +pattern State :: (s -> (# a, s #)) + -> State s a + +-- This pattern synonym makes the monad eta-expand, +-- which as a very beneficial effect on compiler performance +-- See #18202. +-- See Note [The one-shot state monad trick] in GHC.Utils.Monad +pattern State m <- State' m + where + State m = State' (oneShot $ \s -> m s) + instance Applicative (State s) where pure x = State $ \s -> (# x, s #) m <*> n = State $ \s -> case runState' m s of |