78 lines
1.8 KiB
Nim
78 lines
1.8 KiB
Nim
import std/[options, os, sugar]
|
|
|
|
# Declarations
|
|
|
|
type
|
|
IO*[T] = proc(): T
|
|
Unit* = object
|
|
|
|
func attempt*[T](uf: IO[T]): Option[T]
|
|
func attempt*(uf: IO[void]): Option[Unit]
|
|
func fileread*(file: string): IO[Option[string]]
|
|
func filewrite*(data: string, file: string): IO[Option[Unit]]
|
|
func flatmap*[T, U](io: IO[T], fn: T -> IO[U]): IO[U]
|
|
func lift*(fn: proc(): void): IO[void]
|
|
func lift*[T](fn: proc(): T): IO[T]
|
|
func join*[T](io: IO[IO[T]]): IO[T]
|
|
func map*[T, U](io: IO[T], fn: T -> U): IO[U]
|
|
func readln*(fd: File): IO[string]
|
|
func run*[T](io: IO[T]): T
|
|
func strput*(str: string): IO[void]
|
|
func to_IO*[T](val: T): IO[T]
|
|
|
|
# Unsafe
|
|
|
|
proc unsafe[T](uf: IO[T]): Option[T] =
|
|
try:
|
|
let sf: T = uf()
|
|
some(sf)
|
|
except:
|
|
none(T)
|
|
|
|
proc unsafe(uf: IO[void]): Option[Unit] =
|
|
try:
|
|
run uf
|
|
some(Unit())
|
|
except:
|
|
none(Unit)
|
|
|
|
# Definitions
|
|
|
|
func attempt*[T](uf: IO[T]): Option[T] = unsafe(uf)
|
|
|
|
func attempt*(uf: IO[void]): Option[Unit] = unsafe(uf)
|
|
|
|
func fileread*(file: string): IO[Option[string]] =
|
|
proc(): Option[string] =
|
|
if fileExists(file):
|
|
attempt(lift () => readFile(file))
|
|
else:
|
|
none(string)
|
|
|
|
func filewrite*(data: string, file: string): IO[Option[Unit]] =
|
|
proc(): Option[Unit] = attempt(lift () => writeFile(file, data))
|
|
|
|
func flatmap*[T, U](io: IO[T], fn: T -> IO[U]): IO[U] = join(map(io, fn))
|
|
|
|
func lift*(fn: proc(): void): IO[void] =
|
|
proc(): void = fn()
|
|
|
|
func lift*[T](fn: proc(): T): IO[T] =
|
|
proc(): T = fn()
|
|
|
|
func join*[T](io: IO[IO[T]]): IO[T] = map(io, run)
|
|
|
|
func map*[T, U](io: IO[T], fn: T -> U): IO[U] =
|
|
proc(): U = fn(run(io))
|
|
|
|
func readln*(fd: File): IO[string] =
|
|
proc(): string = readLine(fd)
|
|
|
|
func run*[T](io: IO[T]): T = io()
|
|
|
|
func strput*(str: string): IO[void] =
|
|
proc(): void = echo str
|
|
|
|
func to_IO*[T](val: T): IO[T] =
|
|
proc(): T = val
|