aoc2023/lib/io.quox

101 lines
2.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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