Stream: beginners

Topic: Compiler is not detecting list piped into walk


view this post on Zulip Tom Hill (May 08 2025 at 22:24):

Sorry, I need some assistance again. The compiler won't recognise the List U8 being piped into List.walk in the below code. I'm sensing it may be an indentation issue, but I've tried different indentation arrangements and still can't make it compile.

module [count_words]

count_words : Str -> Dict Str U64
count_words = |sentence|
    sentence
    |> Str.with_ascii_lowercased
    |> Str.to_utf8
    |> List.append(' ')
    |> List.walk(
        (Dict.empty({}), []),
        |(words, buffer), char|
            if is_separator(char) and to_word_no_quotes(buffer) != "" then
                (Dict.update(words, to_word_no_quotes(buffer), increment), [])
            else if is_separator(char) then
                (words, buffer)
            else
                (words, List.append(buffer, char)),
    ).0

is_separator : U8 -> Bool
is_separator = |char|
    ((char >= 'a' and char <= 'z') or (char >= '0' and char <= '9') or char == '\'')
    |> Bool.not

increment : Result U64 [Missing] -> Result U64 [Missing]
increment = |current_count|
    when current_count is
        Ok count -> Ok (count + 1)
        Err Missing -> Ok 1

to_word_no_quotes : List U8 -> Str
to_word_no_quotes = |chars|
    when chars is
        [first, .. as word, last] if first == '\'' and last == '\'' -> Str.from_utf8_lossy(word)
        [first, .. as word] if first == '\'' -> Str.from_utf8_lossy(word)
        [.. as word, last] if last == '\'' -> Str.from_utf8_lossy(word)
        word -> Str.from_utf8_lossy(word)

If however, I declare the List U8 as a variable and pass it as an argument to List.walk then there is no issue:

all_chars =
        sentence
        |> Str.with_ascii_lowercased
        |> Str.to_utf8
        |> List.append(' ')

    List.walk(
        all_chars,
        (Dict.empty({}), []),
        |(words, buffer), char|
            if is_separator(char) and to_word_no_quotes(buffer) != "" then
                (Dict.update(words, to_word_no_quotes(buffer), increment), [])
            else if is_separator(char) then
                (words, buffer)
            else
                (words, List.append(buffer, char)),
    ).0

view this post on Zulip Hannes (May 09 2025 at 00:35):

I believe the problem is the .0 after the List.walk. Roc expects everything in a pipeline to be either a function or a function call missing its first argument.

... |> List.walk(x, y) is a function call missing its first argument
... |> |x| x + 1 is a function
... |> List.walk(x, y).0 is not (just) a function call, so we need to evaluate it to get the function to pipe into

You can fix it by moving the .0 to another pipe

... |> List.walk(x, y) |> .0

view this post on Zulip Tom Hill (May 09 2025 at 15:26):

thank you


Last updated: Jul 06 2025 at 12:14 UTC