module Node

import Prelude

-- Promise has some sequencing issues with IO
ptype Promise : U → U
pfunc promise_bind : ∀ a b. Promise a → (a → Promise b) → Promise b := `(a,b, ma, mab) => ma.then(v => mab(v))`
pfunc promise_pure : ∀ a. a → Promise a := `(_, a) => Promise.resolve(a)`
-- The potential issue here is that fa runs before it is even passed in!
pfunc promise_app : ∀ a b. → Promise (a → b) → Promise a → Promise b := `(a,b,fab,fa) => fab.then(ab => fa.then(a => Promise.resolve(ab(a))))`
-- This runs everything immediately...
pfunc promise_lift : ∀ a. IO a → Promise a := `(a,f) => Promise.resolve(f('WORLD').h1)`

instance Monad Promise where
  bind = promise_bind
  pure = promise_pure

instance Applicative Promise where
  return = pure
  fab <*> fa = promise_app fab fa

instance HasIO Promise where
  liftIO = promise_lift

pfunc fs : JSObject := `require('fs')`
pfunc getArgs : List String := `arrayToList(String, process.argv)`
pfunc readFile uses (MkIORes) : (fn : String) -> IO String := `(fn) => (w) => Prelude_MkIORes(require('fs').readFileSync(fn, 'utf8'), w)`

pfunc runPromise uses (MkIORes MkUnit) : ∀ a. Promise a → IO Unit := `(a,p) => (w) => {
  // p(w)
  return Prelude_MkIORes(Prelude_MkUnit, w)
}`
