From 88069b679addba9e33bc8e11ac3185ec8ae432bd Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Sat, 2 Oct 2021 10:40:16 -0700 Subject: [PATCH] Fix withOpen --- examples/false-interpreter/Context.roc | 14 +++++++------- examples/false-interpreter/False.roc | 4 +++- examples/false-interpreter/platform/File.roc | 12 +++++++----- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/examples/false-interpreter/Context.roc b/examples/false-interpreter/Context.roc index 2ee7f94da5..8dc92bdf9a 100644 --- a/examples/false-interpreter/Context.roc +++ b/examples/false-interpreter/Context.roc @@ -14,8 +14,10 @@ pushStack: Context, Data -> Context pushStack = \ctx, data -> {ctx & stack: List.append ctx.stack data} -# The compiler fails to type check if I uncomment this. -#popStack: Context -> Result [T Context Data] [EmptyStack]* +# I think an open tag union should just work here. +# Instead at a call sites, I need to match on the error and then return the same error. +# Otherwise it hits unreachable code in ir.rs +popStack: Context -> Result [T Context Data] [ EmptyStack ]* popStack = \ctx -> when List.last ctx.stack is Ok val -> @@ -39,12 +41,10 @@ toStr = \{stack, vars} -> varsStr = Str.joinWith (List.map vars toStrData) " " "\n============\nStack: [\(stackStr)]\nVars: [\(varsStr)]\n============\n" -# The compiler fails to type check if I uncomment this. -# with : Str, (Context -> Task {} *) -> Task {} * +with : Str, (Context -> Task {} a) -> Task {} a with = \path, callback -> - handle <- Task.await (File.open path) - {} <- Task.await (callback { data: Some handle, index: 0, buf: [], stack: [], vars: (List.repeat Variable.totalCount (Number 0)) }) - File.close handle + handle <- File.withOpen path + callback { data: Some handle, index: 0, buf: [], stack: [], vars: (List.repeat Variable.totalCount (Number 0)) } # I am pretty sure there is a syntax to destructure and keep a reference to the whole, but Im not sure what it is. getChar: Context -> Task [T U8 Context] [ EndOfData ]* diff --git a/examples/false-interpreter/False.roc b/examples/false-interpreter/False.roc index b644f4828a..17005e9492 100644 --- a/examples/false-interpreter/False.roc +++ b/examples/false-interpreter/False.roc @@ -286,10 +286,12 @@ interpretContext = \ctx -> 0x3A -> # `:` store to variable result2 = (T popCtx1 var) <- Result.after (popVariable (Context.consumeChar newCtx)) - (T popCtx2 n1) <- Result.after (Context.popStack popCtx1) + # The Result.mapErr on the next line maps from EmptyStack in Context.roc to the full InterpreterErrors union here. + (T popCtx2 n1) <- Result.after (Result.mapErr (Context.popStack popCtx1) (\(EmptyStack) -> EmptyStack)) Ok {popCtx2 & vars: List.set popCtx2.vars (Variable.toIndex var) n1} when result2 is Ok a -> interpretContext a + Err EmptyStack -> Task.fail EmptyStack Err e -> Task.fail e 0x3B -> # `;` load from variable result2 = diff --git a/examples/false-interpreter/platform/File.roc b/examples/false-interpreter/platform/File.roc index 129a4a93df..385ffbe993 100644 --- a/examples/false-interpreter/platform/File.roc +++ b/examples/false-interpreter/platform/File.roc @@ -1,5 +1,5 @@ interface File - exposes [ line, Handle, withOpen, open, close, chunk ] + exposes [ line, Handle, withOpen, chunk ] imports [ fx.Effect, Task.{ Task } ] Handle: [ @Handle U64 ] @@ -19,9 +19,11 @@ open = \path -> close : Handle -> Task.Task {} * close = \@Handle handle -> Effect.after (Effect.closeFile handle) Task.succeed -# The compiler fails to type check if I uncomment this. -# withOpen : Str, (Handle -> Task {} *) -> Task {} * +withOpen : Str, (Handle -> Task {} a) -> Task {} a withOpen = \path, callback -> handle <- Task.await (open path) - {} <- Task.await (callback handle) - close handle \ No newline at end of file + result <- Task.attempt (callback handle) + {} <- Task.await (close handle) + when result is + Ok a -> Task.succeed a + Err e -> Task.fail e \ No newline at end of file