Guest User

Untitled

a guest
May 20th, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.52 KB | None | 0 0
  1. {-# LANGUAGE MagicHash, UnboxedTuples, Rank2Types, FlexibleInstances,
  2. MultiParamTypeClasses, UndecidableInstances #-}
  3. {- |
  4. Module : Control.Monad.ST.Trans
  5. Copyright : Josef Svenningsson 2008
  6. (c) The University of Glasgow, 1994-2000
  7. License : BSD
  8.  
  9. Maintainer : josef.svenningsson@gmail.com
  10. Stability : experimental
  11. Portability : non-portable (GHC Extensions)
  12.  
  13. This library provides a monad transformer version of the ST monad.
  14.  
  15. Warning! This monad transformer should not be used with monads that
  16. can contain multiple answers, like the list monad. The reason is that
  17. the will be duplicated across the different answers and this cause
  18. Bad Things to happen (such as loss of referential transparency). Safe
  19. monads include the monads State, Reader, Writer, Maybe and
  20. combinations of their corresponding monad transformers.
  21.  
  22. -}
  23. module Control.Monad.ST.Trans(
  24. -- * The ST Monad Transformer
  25. STT,
  26. runST,
  27. -- * Mutable references
  28. STRef,
  29. newSTRef,
  30. readSTRef,
  31. writeSTRef,
  32. -- * Mutable arrays
  33. {-
  34. STArray,
  35. newSTArray,
  36. readSTArray,
  37. writeSTArray,
  38. boundsSTArray,
  39. numElementsSTArray,
  40. freezeSTArray,
  41. thawSTArray,
  42. runSTArray,
  43. -}
  44. -- * Unsafe Operations
  45. unsafeIOToST,
  46. unsafeSTToIO,
  47. unsafeSTRefToIORef,
  48. unsafeIORefToSTRef
  49. )where
  50.  
  51. import GHC.Base
  52. import GHC.Arr (Ix(..), safeRangeSize, safeIndex,
  53. Array(..), arrEleBottom)
  54.  
  55. import Control.Monad.Fix
  56. import Control.Monad.Trans
  57. import Control.Monad.Error.Class
  58. import Control.Monad.Reader.Class
  59. import Control.Monad.State.Class
  60. import Control.Monad.Writer.Class
  61.  
  62. import Control.Applicative
  63.  
  64. import Data.IORef
  65.  
  66. import Unsafe.Coerce
  67. import System.IO.Unsafe
  68.  
  69.  
  70. -- | 'STT' is the monad transformer providing polymorphic updateable references
  71. newtype STT s m a = STT { unSTT :: forall r . State# s -> (a -> State# s -> m r) -> m r }
  72.  
  73. instance Monad (STT s m) where
  74. return a = STT $ \st next -> next a st
  75. m >>= f = STT $ \st next ->
  76. unSTT m st $ \x st' ->
  77. unSTT (f x) st' next
  78.  
  79. instance MonadTrans (STT s) where
  80. lift m = STT $ \st next -> do
  81. a <- m
  82. next a st
  83.  
  84.  
  85. instance Functor (STT s m) where
  86. fmap f p = STT $ \s# next -> unSTT p s# (next . f)
  87.  
  88. -- | Mutable references
  89. data STRef s a = STRef (MutVar# s a)
  90.  
  91. -- | Create a new reference
  92.  
  93. newSTRef :: a -> STT s m (STRef s a)
  94. newSTRef init = STT $ \st1 f -> case newMutVar# init st1 of
  95. (# st2, var #) -> f (STRef var) st2
  96.  
  97. -- | Reads the value of a reference
  98. readSTRef :: STRef s a -> STT s m a
  99. readSTRef (STRef var) = STT $ \st1 f -> case readMutVar# var st1 of
  100. (# st2, a #) -> f a st2
  101.  
  102. -- | Modifies the value of a reference
  103. writeSTRef :: STRef s a -> a -> STT s m ()
  104. writeSTRef (STRef var) a = STT $ \st1 f -> case writeMutVar# var a st1 of
  105. st2 -> f () st2
  106.  
  107. instance Eq (STRef s a) where
  108. STRef v1 == STRef v2 = sameMutVar# v1 v2
  109.  
  110. -- | Executes a computation in the 'STT' monad transformer
  111. runST :: Monad m => (forall s. STT s m a) -> m a
  112. runST m = unSTT m realWorld# (\a _ -> return a)
  113.  
  114. {-# NOINLINE unsafeIOToST #-}
  115. unsafeIOToST :: IO a -> STT s m a
  116. unsafeIOToST m = return $! unsafePerformIO m
  117.  
  118. unsafeSTToIO :: STT s IO a -> IO a
  119. unsafeSTToIO m = runST $ unsafeCoerce m
  120.  
  121. -- This should work, as STRef and IORef should have identical internal representation
  122. unsafeSTRefToIORef :: STRef s a -> IORef a
  123. unsafeSTRefToIORef ref = unsafeCoerce ref
  124.  
  125. unsafeIORefToSTRef :: IORef a -> STRef s a
  126. unsafeIORefToSTRef ref = unsafeCoerce ref
Add Comment
Please, Sign In to add comment