summaryrefslogtreecommitdiff
path: root/ghc/docs/libraries/IOExts.sgml
blob: 2af078938f03f936ab3457bb7503e2e1af78c0d8 (plain)
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
<sect> <idx/IOExts/
<label id="sec:IOExts">
<p>

This library provides the following extensions to the IO monad:
<itemize>
<item>
The operations <tt/fixIO/, <tt/unsafePerformIO/ and <tt/unsafeInterleaveIO/
described in <cite id="ImperativeFP">

<item>
References (aka mutable variables) and mutable arrays (but no form of 
mutable byte arrays)

<item>
<tt/openFileEx/ extends the standard <tt/openFile/ action with support
for opening binary files.

<item>
<tt/performGC/ triggers an immediate garbage collection

<item>
When called, <tt/trace/ prints the string in its first argument to
standard error, before returning the second argument as its result.
The <tt/trace/ function is not referentially transparent, and should
only be used for debugging, or for monitoring execution. Some
implementations of <tt/trace/ may decorate the string that's output
to indicate that you're tracing.

<!--
  You should also be warned that, unless you understand some of the
  details about the way that Haskell programs are executed, results
  obtained using <tt/trace/ can be rather confusing.  For example, the
  messages may not appear in the order that you expect.  Even ignoring the
  output that they produce, adding calls to <tt/trace/ can change the
  semantics of your program.  Consider this a warning!
  -->

<item>
<tt/unsafePtrEq/ compares two values for pointer equality without
evaluating them.  The results are not referentially transparent and
may vary significantly from one compiler to another or in the face of
semantics-preserving program changes.  However, pointer equality is useful
in creating a number of referentially transparent constructs such as this
simplified memoisation function:

<tscreen><verb>
> cache :: (a -> b) -> (a -> b)
> cache f = \x -> unsafePerformIO (check x)
>  where
>   ref = unsafePerformIO (newIORef (error "cache", error "cache"))
>   check x = readIORef ref >>= \ (x',a) ->
>	       if x `unsafePtrEq` x' then
>		 return a
>	       else
>		 let a = f x in
>		 writeIORef ref (x, a) >>
>		 return a
</verb></tscreen>

</itemize>

<tscreen><verb>
module IOExts where

fixIO               :: (a -> IO a) -> IO a
unsafePerformIO     :: IO a -> a
unsafeInterleaveIO  :: IO a -> IO a
		    
data IORef a        -- mutable variables containing values of type a
newIORef     	    :: a -> IO (IORef a)
readIORef    	    :: IORef a -> IO a
writeIORef   	    :: IORef a -> a -> IO ()
instance Eq (IORef a)

data IOArray ix elt -- mutable arrays indexed by values of type ix
                    -- containing values of type a.
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 ()
freezeIOArray       :: Ix ix => IOArray ix elt -> IO (Array ix elt)
instance Eq (IOArray ix elt)

openFileEx          :: FilePath -> IOModeEx -> IO Handle
data IOModeEx = BinaryMode IO.IOMode | TextMode IO.IOMode
instance Eq IOModeEx
instance Read IOModeEx
instance Show IOModeEx

performGC           :: IO ()
trace               :: String -> a -> a
unsafePtrEq         :: a -> a -> Bool

</verb></tscreen>