101 lines
2.8 KiB
Text
101 lines
2.8 KiB
Text
|
load "misc.quox"
|
|||
|
load "maybe.quox"
|
|||
|
load "list.quox"
|
|||
|
|
|||
|
namespace io {
|
|||
|
|
|||
|
def0 IORes : ★ → ★ = λ A ⇒ A × IOState
|
|||
|
|
|||
|
def0 IO : ★ → ★ = λ A ⇒ IOState → IORes A
|
|||
|
|
|||
|
def pure : 0.(A : ★) → A → IO A = λ A x s ⇒ (x, s)
|
|||
|
|
|||
|
def bind : 0.(A B : ★) → IO A → (A → IO B) → IO B =
|
|||
|
λ A B m k s0 ⇒
|
|||
|
case m s0 return IORes B of { (x, s1) ⇒ k x s1 }
|
|||
|
|
|||
|
def bindω : 0.(A B : ★) → IO [ω.A] → (ω.A → IO B) → IO B =
|
|||
|
λ A B m k s0 ⇒
|
|||
|
case m s0 return IORes B of { (x, s1) ⇒
|
|||
|
case x return IORes B of { [x] ⇒ k x s1 }
|
|||
|
}
|
|||
|
|
|||
|
def map : 0.(A B : ★) → (A → B) → IO A → IO B =
|
|||
|
λ A B f m ⇒ bind A B m (λ x ⇒ pure B (f x))
|
|||
|
|
|||
|
def mapω : 0.(A B : ★) → (ω.A → B) → IO [ω.A] → IO B =
|
|||
|
λ A B f m ⇒ bindω A B m (λ x ⇒ pure B (f x))
|
|||
|
|
|||
|
def seq : 0.(B : ★) → IO True → IO B → IO B =
|
|||
|
λ B x y ⇒ bind True B x (λ u ⇒ case u return IO B of { 'true ⇒ y })
|
|||
|
|
|||
|
def seq' : IO True → IO True → IO True = seq True
|
|||
|
|
|||
|
def pass : IO True = pure True 'true
|
|||
|
|
|||
|
#[compile-scheme "(lambda (str) (builtin-io (display str) 'true))"]
|
|||
|
postulate print : String → IO True
|
|||
|
|
|||
|
#[compile-scheme "(lambda (str) (builtin-io (write str) (newline) 'true))"]
|
|||
|
postulate dump : 0.(A : ★) → A → IO True
|
|||
|
|
|||
|
def newline = print "\n"
|
|||
|
|
|||
|
def println : String → IO True =
|
|||
|
λ str ⇒ seq' (print str) newline
|
|||
|
|
|||
|
#[compile-scheme "(builtin-io (get-line (current-input-port)))"]
|
|||
|
postulate readln : IO String
|
|||
|
|
|||
|
|
|||
|
-- [todo] errors lmao
|
|||
|
|
|||
|
{-
|
|||
|
postulate0 File : ★
|
|||
|
|
|||
|
#[compile-scheme "(lambda (path) (builtin-io (open-input-file path)))"]
|
|||
|
postulate open-read : String → IO File
|
|||
|
|
|||
|
#[compile-scheme "(lambda (file) (builtin-io (close-port file) 'true))"]
|
|||
|
postulate close : File → IO True
|
|||
|
|
|||
|
#[compile-scheme
|
|||
|
"(lambda% (file if-eof if-line)
|
|||
|
(builtin-io
|
|||
|
(let ([result (get-line file)])
|
|||
|
(if (eof-object? result)
|
|||
|
(cons if-eof file)
|
|||
|
(cons (if-line result) file)))))"]
|
|||
|
postulate prim-read-line :
|
|||
|
File →
|
|||
|
ω.(if-eof : Maybe [ω.String]) →
|
|||
|
ω.(if-line : ω.String → Maybe [ω.String]) →
|
|||
|
IO (Maybe [ω.String] × File)
|
|||
|
|
|||
|
def read-line : File → IO (Maybe [ω.String] × File) =
|
|||
|
λ f ⇒ prim-read-line f (Nothing [ω.String]) (λ x ⇒ Just [ω.String] [x])
|
|||
|
-}
|
|||
|
|
|||
|
|
|||
|
#[compile-scheme
|
|||
|
"(lambda (path) (builtin-io (call-with-input-file path get-string-all)))"]
|
|||
|
postulate read-fileω : ω.(path : String) → IO [ω.String]
|
|||
|
|
|||
|
def read-file : ω.(path : String) → IO String =
|
|||
|
λ path ⇒
|
|||
|
map [ω.String] String (getω String) (read-fileω path)
|
|||
|
|
|||
|
|
|||
|
#[compile-scheme
|
|||
|
"(lambda (path) (builtin-io
|
|||
|
(call-with-input-file path
|
|||
|
(lambda (file)
|
|||
|
(do [(line (get-line file) (get-line file))
|
|||
|
(acc '() (cons line acc))]
|
|||
|
[(eof-object? line) (reverse acc)])))))"]
|
|||
|
postulate read-file-lines : ω.(path : String) → IO (List String)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
def0 IO = io.IO
|