Skip to content

Commit 2f0b883

Browse files
committed
Add Chan to IOSim
1 parent 2a6ba17 commit 2f0b883

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

io-classes/io-classes.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ library
6767

6868
-- At this experiment/prototype stage everything is exposed.
6969
-- This has to be tidied up once the design becomes clear.
70-
exposed-modules: Control.Concurrent.Class.MonadMVar
70+
exposed-modules: Control.Concurrent.Class.MonadChan
71+
Control.Concurrent.Class.MonadMVar
7172
Control.Concurrent.Class.MonadSTM
7273
Control.Concurrent.Class.MonadSTM.TArray
7374
Control.Concurrent.Class.MonadSTM.TBQueue
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{-# LANGUAGE DefaultSignatures #-}
2+
{-# LANGUAGE TypeFamilies #-}
3+
4+
module Control.Concurrent.Class.MonadChan
5+
( MonadChan (..)
6+
) where
7+
8+
import Control.Concurrent.Chan qualified as IO
9+
10+
import Data.Kind (Type)
11+
12+
class Monad m => MonadChan m where
13+
{-# MINIMAL newChan,
14+
writeChan, readChan,
15+
dupChan, getChanContents #-}
16+
17+
type Chan m :: Type -> Type
18+
19+
-- | See 'IO.newChan.
20+
newChan :: m (Chan m a)
21+
-- | See 'IO.writeChan'.
22+
writeChan :: Chan m a -> a -> m ()
23+
-- | See 'IO.readChan'.
24+
readChan :: Chan m a -> m a
25+
-- | See 'IO.dupChan'.
26+
dupChan :: Chan m a -> m (Chan m a)
27+
-- | See 'IO.getChanContents'.
28+
getChanContents :: Chan m a -> m [a]
29+
-- | See 'IO.writeList2Chan'
30+
writeList2Chan :: Chan m a -> [a] -> m ()
31+
32+
default writeList2Chan :: Chan m a -> [a] -> m ()
33+
writeList2Chan ch ls = sequence_ (map (writeChan ch) ls)
34+
{-# INLINE writeList2Chan #-}
35+
36+
--
37+
-- IO instance
38+
--
39+
40+
instance MonadChan IO where
41+
type Chan IO = IO.Chan
42+
43+
newChan = IO.newChan
44+
writeChan = IO.writeChan
45+
readChan = IO.readChan
46+
dupChan = IO.dupChan
47+
getChanContents = IO.getChanContents

io-sim/src/Control/Monad/IOSim/Types.hs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ import Control.Exception qualified as IO
8282
import Control.Monad
8383
import Control.Monad.Fix (MonadFix (..))
8484

85+
import Control.Concurrent.Class.MonadChan hiding (Chan)
86+
import Control.Concurrent.Class.MonadChan qualified as MonadAsync
8587
import Control.Concurrent.Class.MonadMVar
8688
import Control.Concurrent.Class.MonadSTM.Strict.TVar (StrictTVar)
8789
import Control.Concurrent.Class.MonadSTM.Strict.TVar qualified as StrictTVar
@@ -776,6 +778,45 @@ instance MonadEventlog (IOSim s) where
776778
traceEventIO = traceM . EventlogEvent
777779
traceMarkerIO = traceM . EventlogMarker
778780

781+
data Chan m a
782+
= Chan (MVar m (Stream m a))
783+
(MVar m (Stream m a))
784+
785+
type Stream m a = MVar m (ChanItem m a)
786+
787+
data ChanItem m a = ChanItem a (Stream m a)
788+
789+
instance MonadChan (IOSim s) where
790+
type Chan (IOSim s) = Chan (IOSim s)
791+
792+
newChan = do
793+
hole <- newEmptyMVar
794+
readVar <- newMVar hole
795+
writeVar <- newMVar hole
796+
return (Chan readVar writeVar)
797+
798+
writeChan (Chan _ writeVar) val = do
799+
new_hole <- newEmptyMVar
800+
mask_ $ do
801+
old_hole <- takeMVar writeVar
802+
putMVar old_hole (ChanItem val new_hole)
803+
putMVar writeVar new_hole
804+
805+
readChan (Chan readVar _) =
806+
modifyMVar readVar $ \read_end -> do
807+
(ChanItem val new_read_end) <- readMVar read_end
808+
return (new_read_end, val)
809+
810+
dupChan (Chan _ writeVar) = do
811+
hole <- readMVar writeVar
812+
newReadVar <- newMVar hole
813+
return (Chan newReadVar writeVar)
814+
815+
getChanContents ch = do
816+
x <- readChan ch
817+
xs <- getChanContents ch
818+
return (x:xs)
819+
779820
-- | 'Trace' is a recursive data type, it is the trace of a 'IOSim'
780821
-- computation. The trace will contain information about thread scheduling,
781822
-- blocking on 'TVar's, and other internal state changes of 'IOSim'. More

0 commit comments

Comments
 (0)