Skip to content

Instantly share code, notes, and snippets.

@ianfun
Created August 1, 2022 13:43
Show Gist options
  • Save ianfun/9e6a6ede9c7a020976c8b627a36b3028 to your computer and use it in GitHub Desktop.
Save ianfun/9e6a6ede9c7a020976c8b627a36b3028 to your computer and use it in GitHub Desktop.
IO Monad for Nim
# IO Monad for Nim!
type IO*[T] = proc (): T
type EmptyTuple* = tuple[]
proc callIO*[T](f: IO[T]): auto {.inline.} = f()
proc `>>`*[A, B](a: IO[A], b: IO[B]): IO[B] =
discard callIO(a)
b
proc `>>=`*[A, B](a: IO[A], f: proc (x: A): IO[B]): IO[B] =
f(callIO(a))
# hFlush :: Handle -> IO ()
let hFlush*: proc (a: File): IO[EmptyTuple] = proc (a: File): IO[EmptyTuple] =
return proc (): EmptyTuple =
a.flushFile()
return ()
# hPutChar :: Handle -> Char -> IO ()
let hPutChar*: (proc (a: File): proc (c: char): IO[EmptyTuple]) = proc (a: File): (proc (c: char): IO[EmptyTuple]) =
return proc (c: char): IO[EmptyTuple] =
return proc (): EmptyTuple =
a.write(c)
return ()
# getChar :: IO Char
let getChar*: IO[char] = proc (): char = stdin.readChar()
# getLine :: IO String
let getLine*: IO[string] = proc (): string = stdin.readLine()
# putStrLn :: String -> IO ()
let putStrLn*: proc (a: string): IO[EmptyTuple] = proc (a: string): IO[EmptyTuple] =
return proc (): EmptyTuple =
stdout.writeLine(a)
return ()
# readFile :: FilePath -> IO String (FilePath=String)
let readFile*: proc (a: string): IO[string] = proc (a: string): IO[string] =
return proc (): string =
return system.readFile(a) # readFile is defined at system.io, not our function
let putC: IO[EmptyTuple] = (hPutChar stdout)('C')
# main :: IO ()
let main: IO[EmptyTuple] =
(getLine >>= readFile >>= putStrLn) >>
putC >>
(hFlush stdout)
discard callIO(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment