File: IOExts.hs

package info (click to toggle)
hugs98 98.200109-5
  • links: PTS
  • area: main
  • in suites: woody
  • size: 3,344 kB
  • ctags: 5,368
  • sloc: ansic: 42,923; haskell: 6,574; xml: 1,143; yacc: 1,119; makefile: 332; sh: 260
file content (141 lines) | stat: -rw-r--r-- 4,342 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
-----------------------------------------------------------------------------
-- IO monad extensions:
--
-- Suitable for use with Hugs 98.
-----------------------------------------------------------------------------

module IOExts
	( fixIO
	, unsafePerformIO
	, unsafeInterleaveIO

	, IORef
	  -- instance Eq (IORef a)
	, newIORef
	, readIORef
	, writeIORef

        , IOArray
          -- instance Eq (IOArray ix elt)
        , newIOArray
        , boundsIOArray
        , readIOArray
        , writeIOArray
        , thawIOArray
        , freezeIOArray
        , unsafeFreezeIOArray

	, performGC
	, trace
	, unsafePtrEq
	, unsafePtrToInt
	) where

import Trace( trace )
import IO( ioeGetErrorString )
import Array

-----------------------------------------------------------------------------

primitive performGC "primGC" :: IO ()

unsafePerformIO :: IO a -> a
unsafePerformIO m = performIO (runAndShowError m)

unsafeInterleaveIO :: IO a -> IO a
unsafeInterleaveIO m = interleaveIO (runAndShowError m)

primitive unsafePtrEq    :: a -> a -> Bool
primitive unsafePtrToInt :: a -> Int

fixIO :: (a -> IO a) -> IO a
fixIO m = IO fixIO'
 where
  fixIO' fail succ =
    case r of
    Finished_Return a   -> succ a
    Finished_Error err  -> fail err
    other               -> error "IOExts:fixIO: failed"
   where
    r = basicIORun (m a)
    a = case r   of 
        Finished_Return a  -> a
        _                  -> error "IOExts:fixIO: thread exited with error"

primitive unsafeCoerce "primUnsafeCoerce" :: a -> b

performIO :: IO a -> a
performIO m = 
  case basicIORun m of
    Finished_Return a  -> a
    _                  -> error "IOExts.performIO: thread exited with error"

interleaveIO :: IO a -> IO a
interleaveIO m = IO (\ f s -> 
  s (case basicIORun m of
       Finished_Return a  -> a
       _                  -> error "IOExts.interleaveIO: thread exited with error"
     ))

runAndShowError :: IO a -> IO a
runAndShowError m =
  m `catch` \err -> do 
      putChar '\n'
      putStr (ioeGetErrorString err)
      return undefined

-----------------------------------------------------------------------------

data IORef a        -- mutable variables containing values of type a

primitive newIORef   "newRef" :: a -> IO (IORef a)
primitive readIORef  "getRef" :: IORef a -> IO a
primitive writeIORef "setRef" :: IORef a -> a -> IO ()
primitive eqIORef    "eqRef"  :: IORef a -> IORef a -> Bool

instance Eq (IORef a) where
    (==) = eqIORef

-----------------------------------------------------------------------------

data IOArray ix elt -- implemented as an internal primitive

newIOArray          :: Ix ix => (ix,ix) -> elt -> IO (IOArray ix elt)
boundsIOArray       :: Ix ix => IOArray ix elt -> (ix, ix)
readIOArray         :: Ix ix => IOArray ix elt -> ix -> IO elt
writeIOArray        :: Ix ix => IOArray ix elt -> ix -> elt -> IO ()
thawIOArray         :: Ix ix => Array ix elt -> IO (IOArray ix elt)
freezeIOArray       :: Ix ix => IOArray ix elt -> IO (Array ix elt)
unsafeFreezeIOArray :: Ix ix => IOArray ix elt -> IO (Array ix elt)

newIOArray bs e      = primNewArr bs (rangeSize bs) e
boundsIOArray a      = primBounds a
readIOArray a i      = primReadArr index a i
writeIOArray a i e   = primWriteArr index a i e
thawIOArray arr      = do a <- newIOArray (bounds arr) err
			  let fillin []          = return a
			      fillin((ix,v):ixs) = do writeIOArray a ix v
                                                      fillin ixs
                          fillin (assocs arr)
                       where err =  error "thawArray: element not overwritten"

freezeIOArray a      = primFreeze a
unsafeFreezeIOArray  = freezeIOArray  -- not as fast as GHC

instance Eq (IOArray ix elt) where
  (==) = eqIOArray

primitive primNewArr   "IONewArr"
          :: (a,a) -> Int -> b -> IO (IOArray a b)
primitive primReadArr  "IOReadArr"
          :: ((a,a) -> a -> Int) -> IOArray a b -> a -> IO b
primitive primWriteArr "IOWriteArr"
          :: ((a,a) -> a -> Int) -> IOArray a b -> a -> b -> IO ()
primitive primFreeze   "IOFreeze"
          :: IOArray a b -> IO (Array a b)
primitive primBounds   "IOBounds"
          :: IOArray a b -> (a,a)
primitive eqIOArray    "IOArrEq"
          :: IOArray a b -> IOArray a b -> Bool

-----------------------------------------------------------------------------