@@ -8,8 +8,8 @@ import Control.IOExcept
8||| A Dependent type to describe File Handles. File handles are
8||| A Dependent type to describe File Handles. File handles are
9||| parameterised with the current state of the file: Closed; Open for
9||| parameterised with the current state of the file: Closed; Open for
10||| reading; and Open for writing.
10||| reading; and Open for writing.
12−||| @ m The file mode.
12+||| @ m The file mode.
13data OpenFile : (m : Mode) -> Type where
13data OpenFile : (m : Mode) -> Type where
14 FH : File -> OpenFile m
14 FH : File -> OpenFile m
@@ -21,27 +21,27 @@ openOK m False = ()
22||| Here the protocol for resource access is defined as an effect.
22||| Here the protocol for resource access is defined as an effect.
23||| The state transitions diagram for the protocol is as follows:
23||| The state transitions diagram for the protocol is as follows:
25||| digraph G {
25||| digraph G {
27||| empty; read; write; // States
27||| empty; read; write; // States
29||| empty -> read [label="Open R"];
29||| empty -> read [label="Open R"];
30||| read -> empty [label="Close"];
30||| read -> empty [label="Close"];
31||| read -> read [label="ReadLine"];
31||| read -> read [label="ReadLine"];
32||| read -> read [label="EOF"];
32||| read -> read [label="EOF"];
34||| empty -> write [label="Open W"];
34||| empty -> write [label="Open W"];
35||| write -> empty [label="Close"];
35||| write -> empty [label="Close"];
36||| write -> write [label="WriteLine"];
36||| write -> write [label="WriteLine"];
39data FileIO : Effect where
39data FileIO : Effect where
40 ||| Open a file with the specified mode.
40 ||| Open a file with the specified mode.
42 ||| Opening a file successful moves the state from 'empty' to the
42 ||| Opening a file successful moves the state from 'empty' to the
43 ||| specified mode. If not successful the state is still 'empty'.
43 ||| specified mode. If not successful the state is still 'empty'.
45 ||| @ fname The file name to be opened.
45 ||| @ fname The file name to be opened.
46 ||| @ m The file mode.
46 ||| @ m The file mode.
47 Open : (fname: String)
47 Open : (fname: String)
@@ -51,22 +51,22 @@ data FileIO : Effect where
51 False => ())
51 False => ())
53 ||| Close a file.
53 ||| Close a file.
55 ||| Closing a file moves the state from Open to closed.
55 ||| Closing a file moves the state from Open to closed.
56− Close : sig FileIO () (OpenFile m) ()
56+ Close : sig FileIO () (OpenFile m) ()
58 ||| Read a line from the file.
58 ||| Read a line from the file.
60 ||| Only files that are open for reading can be read.
60 ||| Only files that are open for reading can be read.
61 ReadLine : sig FileIO String (OpenFile Read)
61 ReadLine : sig FileIO String (OpenFile Read)
63 ||| Write a string to a file.
63 ||| Write a string to a file.
65 ||| Only file that are open for writing can be written to.
65 ||| Only file that are open for writing can be written to.
66 WriteString : String -> sig FileIO () (OpenFile Write)
66 WriteString : String -> sig FileIO () (OpenFile Write)
68 ||| End of file?
68 ||| End of file?
70 ||| Only files open for reading can be tested for EOF
70 ||| Only files open for reading can be tested for EOF
71 EOF : sig FileIO Bool (OpenFile Read)
71 EOF : sig FileIO Bool (OpenFile Read)
@@ -76,7 +76,7 @@ data FileIO : Effect where
76instance Handler FileIO IO where
76instance Handler FileIO IO where
77 handle () (Open fname m) k = do h <- openFile fname m
77 handle () (Open fname m) k = do h <- openFile fname m
78 valid <- validFile h
78 valid <- validFile h
79− if valid then k True (FH h)
79+ if valid then k True (FH h)
80 else k False ()
80 else k False ()
81 handle (FH h) Close k = do closeFile h
81 handle (FH h) Close k = do closeFile h
@@ -112,12 +112,12 @@ FILE_IO t = MkEff t FileIO
114||| Open a file with the specified mode.
114||| Open a file with the specified mode.
116||| @ fname The file name to be opened.
116||| @ fname The file name to be opened.
117||| @ m The file mode.
117||| @ m The file mode.
118open : (fname : String)
118open : (fname : String)
119 -> (m : Mode)
119 -> (m : Mode)
120− -> Eff Bool [FILE_IO ()]
120+ -> Eff Bool [FILE_IO ()]
121 (\res => [FILE_IO (case res of
121 (\res => [FILE_IO (case res of
122 True => OpenFile m
122 True => OpenFile m
123 False => ())])
123 False => ())])
@@ -144,4 +144,45 @@ writeLine str = call $ WriteString (str ++ "\n")
144eof : Eff Bool [FILE_IO (OpenFile Read)]
144eof : Eff Bool [FILE_IO (OpenFile Read)]
145eof = call $ EOF
145eof = call $ EOF
147+||| Read a complete file, returning a user defined error if
150+readFile : (errFunc : String -> e)
152+ -> Eff (Either e String) [FILE_IO ()]
153+readFile errFunc fname = do
154+ case !(open fname Read) of
155+ False => pure $ Left (errFunc fname)
161+ readAcc : String -> Eff String [FILE_IO (OpenFile Read)]
162+ readAcc acc = if (not !(eof))
163+ then readAcc (acc ++ !(readLine))
166+||| Write a file containing the provided string, returning a user
167+||| defined error if unsuccesful.
169+writeFile : (errFunc : String -> e)
171+ -> (content : String)
172+ -> Eff (Either e ()) [FILE_IO ()]
173+writeFile errFunc fname content = do
174+ case !(open fname Write) of
179+ False => pure $ Left (errFunc fname)
183+ readFile : String -> Eff (Either String String) [FILE_IO ()]
184+ readFile = File.readFile id
186+ writeFile : String -> String -> Eff (Either String ()) [FILE_IO ()]
187+ writeFile = File.writeFile id
147-- --------------------------------------------------------------------- [ EOF ]
188-- --------------------------------------------------------------------- [ EOF ]