1||| Effectful file operations.
9-- -------------------------------------------------------------- [ Predicates ]
11||| A record of the file modes that can read from a file.
12data ValidModeRead : Mode -> Type where
13 VMRRead : ValidModeRead Read
14 VMRReadW : ValidModeRead ReadWrite
15 VMRReadWT : ValidModeRead ReadWriteTruncate
16 VMRReadA : ValidModeRead ReadAppend
18||| A record of the file modes that can write from a file.
19data ValidModeWrite : Mode -> Type where
20 VMWWrite : ValidModeWrite WriteTruncate
21 VMWAppend : ValidModeWrite Append
22 VMWReadW : ValidModeWrite ReadWrite
23 VMWReadWT : ValidModeWrite ReadWriteTruncate
25-- -------------------------------------------------- [ Custom Error Reporting ]
29 ||| A type to describe the return type of file operations.
30 data ResultDesc = SUCCESS | RESULT
32 ||| A custom return type for file operations that is dependent on
33 ||| the type of file operation.
35 ||| @desc Parameterises the constructors to describe if the function
36 ||| returns a value or not.
37 ||| @ty The return type for a file operation that returns a value.
39 data FileOpReturnTy : (desc : ResultDesc)
43 ||| The operation completed successfully and doesn't return a
45 Success : FileOpReturnTy SUCCESS ty
47 ||| The operation returns a result of type `ty`.
49 ||| @ty The value returned.
50 Result : ty -> FileOpReturnTy RESULT ty
52 ||| The operation failed and the RTS produced the given error.
54 ||| @err The reported error code.
55 FError : (err : FileError) -> FileOpReturnTy desc ty
57 ||| Type alias to describe a file operatons that returns a result.
58 FileOpResult : Type -> Type
59 FileOpResult ty = FileOpReturnTy RESULT ty
61 ||| Type alias to describe file oeprations that indicate success.
63 FileOpSuccess = FileOpReturnTy SUCCESS ()
65-- ------------------------------------------------------------ [ The Resource ]
67||| The file handle associated with the effect.
69||| @m The `Mode` that the handle was generated under.
70data FileHandle : (m : Mode) -> Type where
71 FH : File -> FileHandle m
73-- ---------------------------------------------- [ Resource Type Construction ]
75||| Calculates the type for the resource being computed over. `Unit`
76||| to describe pre-and-post file handle acquisistion, and `FileHandle
77||| m` when a file handle has been aqcuired.
79||| @m The mode the file handle was generated under.
80||| @ty The functions return type.
81calcResourceTy : (m : Mode)
82 -> (ty : FileOpReturnTy fOpTy retTy)
84calcResourceTy _ (FError e) = ()
85calcResourceTy m _ = FileHandle m
87-- ------------------------------------------------------- [ Effect Definition ]
89||| An effect to describe operations on a file.
90data FileE : Effect where
94 Open : (fname : String)
99 (\res => calcResourceTy m res)
101 OpenX : (fname : String)
106 (\res => calcResourceTy m res)
108 Close : sig FileE () (FileHandle m) ()
112 FGetC : {auto prf : ValidModeRead m}
118 FGetLine : {auto prf : ValidModeRead m}
120 (FileOpResult String)
124 FReadFile : (fname : String)
126 (FileOpResult String)
130 FPutStr : (str : String)
131 -> {auto prf : ValidModeWrite m}
137 FPutStrLn : (str : String)
138 -> {auto prf : ValidModeWrite m}
144 FWriteFile : (fname : String)
145 -> (contents : String)
157 FEOF : {auto prf : ValidModeRead m}
162-- ---------------------------------------------------------------------- [ IO ]
164Handler FileE IO where
167 handle () (Open fname m) k = do
168 res <- openFile fname m
170 Left err => k (FError err) ()
171 Right fh => k Success (FH fh)
173 handle () (OpenX fname m) k = do
174 res <- openFileX fname m
176 Left err => k (FError err) ()
177 Right fh => k Success (FH fh)
179 handle (FH h) Close k = do
184 handle (FH h) FGetC k = do
187 Left err => k (FError err) (FH h)
188 Right c => k (Result c) (FH h)
190 handle (FH h) FGetLine k = do
193 Left err => k (FError err) (FH h)
194 Right ln => k (Result ln) (FH h)
196 handle () (FReadFile fname) k = do
197 res <- readFile fname
199 Left err => k (FError err) ()
200 Right str => k (Result str) ()
203 handle (FH fh) (FPutStr str) k = do
204 res <- fPutStr fh str
206 Left err => k (FError err) (FH fh)
207 Right () => k Success (FH fh)
209 handle (FH fh) (FPutStrLn str) k = do
210 res <- fPutStr fh str
212 Left err => k (FError err) (FH fh)
213 Right () => k Success (FH fh)
215 handle () (FWriteFile fname str) k = do
216 res <- writeFile fname str
218 Left err => k (FError err) ()
219 Right () => k Success ()
222 handle (FH fh) FFlush k = do
227 handle (FH fh) FEOF k = do
231-- ---------------------------------------------------------------- [ IOExcept ]
233Handler FileE (IOExcept a) where
236 handle () (Open fname m) k = do
237 res <- ioe_lift $ openFile fname m
239 Left err => k (FError err) ()
240 Right fh => k Success (FH fh)
242 handle () (OpenX fname m) k = do
243 res <- ioe_lift $ openFileX fname m
245 Left err => k (FError err) ()
246 Right fh => k Success (FH fh)
248 handle (FH h) Close k = do
249 ioe_lift $ closeFile h
253 handle (FH h) FGetC k = do
254 res <- ioe_lift $ fgetc h
256 Left err => k (FError err) (FH h)
257 Right c => k (Result c) (FH h)
259 handle (FH h) FGetLine k = do
260 res <- ioe_lift $ fGetLine h
262 Left err => k (FError err) (FH h)
263 Right ln => k (Result ln) (FH h)
265 handle () (FReadFile fname) k = do
266 res <- ioe_lift $ readFile fname
268 Left err => k (FError err) ()
269 Right str => k (Result str) ()
272 handle (FH fh) (FPutStr str) k = do
273 res <- ioe_lift $ fPutStr fh str
275 Left err => k (FError err) (FH fh)
276 Right () => k Success (FH fh)
278 handle (FH fh) (FPutStrLn str) k = do
279 res <- ioe_lift $ fPutStr fh str
281 Left err => k (FError err) (FH fh)
282 Right () => k Success (FH fh)
284 handle () (FWriteFile fname str) k = do
285 res <- ioe_lift $ writeFile fname str
287 Left err => k (FError err) ()
288 Right () => k Success ()
291 handle (FH fh) FFlush k = do
297 handle (FH fh) FEOF k = do
298 res <- ioe_lift $ fEOF fh
301-- ------------------------------------------------------ [ Effect and Helpers ]
303||| Effectful operations for interacting with files.
305||| The `FILE` effect is parameterised by a file handle once a handle has been acquired, and Unit (`()`) if the file handle is expected to be released once the function has returned.
307FILE : (ty : Type) -> EFFECT
308FILE t = MkEff t FileE
310||| A file has been opened for reading.
314||| A file has been opened for writing.
316W = FileHandle WriteTruncate
318||| A file can only be appeneded to.
322||| A file can be read and written to.
324RW = FileHandle ReadWrite
326||| A file opened for reading and writing and has been truncated to
327||| zero if it previsiouly existed.
329RWPlus = FileHandle ReadWriteTruncate
331||| A file will read from the beginning and write at the end.
333APlus = FileHandle ReadAppend
335-- --------------------------------------------------------------------- [ API ]
337-- -------------------------------------------------------- [ Open/Close/Query ]
341||| @ fname the filename.
342||| @ m the mode; either Read, WriteTruncate, Append, ReadWrite,
343||| ReadWriteTruncate, or ReadAppend
345open : (fname : String)
347 -> Eff (FileOpSuccess)
349 (\res => [FILE (calcResourceTy m res)])
350open f m = call $ Open f m
352||| Open a file using C11 extended modes.
354||| @ fname the filename
355||| @ m the mode; either Read, WriteTruncate, Append, ReadWrite,
356||| ReadWriteTruncate, or ReadAppend
357openX : (fname : String)
359 -> Eff (FileOpSuccess)
361 (\res => [FILE (calcResourceTy m res)])
362openX f m = call $ OpenX f m
365close : Eff () [FILE (FileHandle m)] [FILE ()]
368||| Have we reached the end of the file.
369eof : {auto prf : ValidModeRead m}
370 -> Eff Bool [FILE (FileHandle m)]
373flush : Eff () [FILE (FileHandle m)]
376-- -------------------------------------------------------------------- [ Read ]
379readChar : {auto prf : ValidModeRead m}
380 -> Eff (FileOpResult Char)
381 [FILE (FileHandle m)]
384||| Read a complete line.
385readLine : {auto prf : ValidModeRead m}
386 -> Eff (FileOpResult String)
387 [FILE (FileHandle m)]
388readLine = call FGetLine
390-- ------------------------------------------------------------------- [ Write ]
392||| Write a string to the file.
393writeString : (str : String)
394 -> {auto prf : ValidModeWrite m}
395 -> Eff (FileOpSuccess)
396 [FILE (FileHandle m)]
397writeString str = call $ FPutStr str
399||| Write a complete line to the file.
400writeLine : (str : String)
401 -> {auto prf : ValidModeWrite m}
402 -> Eff (FileOpSuccess)
403 [FILE (FileHandle m)]
404writeLine str = call $ FPutStrLn str
406-- -------------------------------------------------------------- [ Whole File ]
408||| Read the contents of a file into a string.
410||| This checks the size of
411||| the file before beginning to read, and only reads that many bytes,
412||| to ensure that it remains a total function if the file is appended
413||| to while being read.
415||| Returns an error if fname is not a normal file.
416readFile : (fname : String)
417 -> Eff (FileOpResult String)
419readFile fn = call $ FReadFile fn
421||| Create a file and write contents to the file.
422writeFile : (fname : String)
423 -> (contents : String)
424 -> Eff (FileOpSuccess)
426writeFile fn str = call $ FWriteFile fn str
428-- --------------------------------------------------------------------- [ EOF ]
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