1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE MagicHash #-}
6{-# LANGUAGE RecordWildCards #-}
7{-# LANGUAGE UnboxedTuples #-}
8{-# LANGUAGE ScopedTypeVariables #-}
13-- Module : Streamly.Internal.Mutable.Prim.Var
14-- Copyright : (c) 2019 Composewell Technologies
17-- Maintainer : streamly@composewell.com
18-- Stability : experimental
21-- A mutable variable in a mutation capable monad (IO/ST) holding a 'Prim'
22-- value. This allows fast modification because of unboxed storage.
24module Streamly.Internal.Mutable.Prim.Var
42import Control.Monad.Primitive (PrimMonad(..), primitive_)
43import Data.Primitive.Types (Prim, sizeOf#, readByteArray#, writeByteArray#)
44import GHC.Exts (MutableByteArray#, newByteArray#)
46-- | A 'Var' holds a single 'Prim' value.
47data Var m a = Var (MutableByteArray# (PrimState m))
49-- The name PrimMonad does not give a clue what it means, an explicit "Mut"
50-- suffix provides a better hint. MonadMut is just a generalization of MonadIO.
52-- | A monad that allows mutable operations using a state token.
53type MonadMut = PrimMonad
55-- | Create a new mutable variable.
57newVar :: forall m a. (MonadMut m, Prim a) => a -> m (Var m a)
58newVar x = primitive (\s# ->
59 case newByteArray# (sizeOf# (undefined :: a)) s# of
61 case writeByteArray# arr# 0# x s1# of
62 s2# -> (# s2#, Var arr# #)
65-- | Write a value to a mutable variable.
66{-# INLINE writeVar #-}
67writeVar :: (MonadMut m, Prim a) => Var m a -> a -> m ()
68writeVar (Var arr#) x = primitive_ (writeByteArray# arr# 0# x)
70-- | Read a value from a variable.
72readVar :: (MonadMut m, Prim a) => Var m a -> m a
73readVar (Var arr#) = primitive (readByteArray# arr# 0#)
75-- | Modify the value of a mutable variable using a function with strict
77{-# INLINE modifyVar' #-}
78modifyVar' :: (MonadMut m, Prim a) => Var m a -> (a -> a) -> m ()
79modifyVar' (Var arr#) g = primitive_ $ \s# ->
80 case readByteArray# arr# 0# s# of
81 (# s'#, a #) -> let a' = g a in a' `seq` writeByteArray# arr# 0# a' s'#
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list