I think you want Ok is_file if is_file ->
as the first when branch and _ ->
as the second when branch
Sorry - never used Zulip before...I deleted my original message by mistake.
So - trying to determine if a entry is a File or a Directory using "if" rather than "when"
Code: https://github.com/bartonhammond/pullNightly/blob/main/list-walk.roc
Here's the code snipped:
foo = List.walk dir_list { file: [], dir: [] } \state, elem ->
if File.is_file! elem then
{ state & file: List.append state.file elem }
else
{ state & dir: List.append state.dir elem }
And the error is
This if condition needs to be a Bool:
15│ if File.is_file! elem then
^^^^^^^^^^^^^^^^^^
This File.is_file! call produces:
Result Bool [PathErr InternalIOErr.IOErr]
But I need every if condition to evaluate to a Bool—either Bool.true
or Bool.false.
so File.is_file!
returns a Result Bool [PathErr InternalIOErr.IOErr]
. Essentially, if the path is bad or if something else goes wrong, it will return a PathErr
.
Otherwise, it returns a boolean indicating if something is a file or not
In the example, you have to decide what to do with the error.
Probably the easiest is just propagating the error with ?
Something like:
foo = List.walk? dir_list { file: [], dir: [] } \state, elem ->
if File.is_file!? elem then
{ state & file: List.append state.file elem }
else
{ state & dir: List.append state.dir elem }
I think should work an propagate the error up the stack
I think that is the right syntax...
Otherwise, you can handle the error locally:
foo = List.walk? dir_list { file: [], dir: [] } \state, elem ->
when File.is_file! elem is
Ok is_file if is_file ->
{ state & file: List.append state.file elem }
Ok _ ->
{ state & dir: List.append state.dir elem }
_ ->
# Just ignore failures
state
Sorry - this is very confusing...
With this:
foo = List.walk dir_list { file: [], dir: [] } \state, elem ->
when File.is_file! elem is
Ok is_file if is_file ->
{ state & file: List.append state.file elem }
Ok _ ->
{ state & dir: List.append state.dir elem }
_ ->
# Just ignore failures
state
I get this:
I was partway through parsing a function, but I got stuck here:
14│ foo = List.walk dir_list { file: [], dir: [] } \state, elem ->
^
I just saw a pattern, so I was expecting to see a -> next.%
Try putting some more newlines and indents in there
Seems like it doesn't know where the block starts?
sorry, I may have mixed up some tabbing. Didn't actually run the example, just typed it out
Oh, we don't have List.walk!
so this function can't work.
wrt to formatting, my VSCode is not formatting the file on save. I have the Roc Extension installed and have the settings.json updated.
The roc_nightly
directory has the roc
and roc_language_server
.
When I am in any roc
file, I do not have a menu option to "format" so I don't know if there is problem with file formatting.
settings.json
{
"roc-lang.language-server.exe": "/Users/bartonhammond/projects/roc/roc_nightly",
"editor.formatOnSave": true
}
So to give a concrete solution here. Due to File.is_file!
being effectful (e.g. having a !
in the name), it can't be used with non-effectful functions like List.walk
. Currently, roc does not have List.walk!
, so this code must be done manually through a recursive functions (growing pains of having just switched to purity inference).
So the solution right now is likely this:
dirs_and_files! = \list, state ->
when list is
[elem, .. as rest] ->
next_state =
when File.is_file! elem is
Ok is_file if is_file ->
{ state & file: List.append state.file elem }
Ok _ ->
{ state & dir: List.append state.dir elem }
_ ->
# Just ignore failures
state
dirs_and_files! rest next_state
_ ->
state
I'll have to learn more to understand what you're talking about.
Barton Hammond has marked this topic as resolved.
Yeah, roc is currently in flux with a lot of changes that greatly affect syntax and direct code.
Purity inference is one of them. Original design doc at the top of this thread: #ideas > Purity inference proposal v3
Last updated: Jul 06 2025 at 12:14 UTC