Stream: beginners

Topic: ✔ latest nightly Eq not implemented for ? (it's a Str)


view this post on Zulip Vladimir Zotov (Jul 23 2024 at 12:42):

I'm trying to compile a code that worked a month ago and getting an error

This expression has a type that does not implement the abilities it's expected to:

105│      parseYarnV1LockFileContent testInputStr

I can't generate an implementation of the Eq ability for

    [
        Err [
            ParsingFailure ?,
            ParsingIncomplete ?,
        ],
        Ok (List [
            Comment ?,
            DependencySection {
                dependencies : List {
                    name : ?,
                    version : ?,
                },
                head : List ?,
                integrity : ?,
                resolved : ?,
                version : ?,
            },
        ]),
    ]

In particular, an implementation for

    ?

cannot be generated.

The ? was supposed to be a Str. Does anyone know if that is something that has changed in the language/platforms?

view this post on Zulip Anton (Jul 23 2024 at 12:44):

Hi @Vladimir Zotov,
Can you share the full code?

view this post on Zulip Vladimir Zotov (Jul 23 2024 at 13:02):

YarnLockV1Parser.roc
main.roc

view this post on Zulip Anton (Jul 23 2024 at 15:05):

I changed c != ":" and c == ":" to c != ':' and c == ':'

view this post on Zulip Anton (Jul 23 2024 at 15:07):

That will bring up a new error, but you should be able to solve it by using sepBy (codeunit ',')in combination with oneOf (to account for one dependency vs multiple) in dependecyHead.

view this post on Zulip Anton (Jul 23 2024 at 15:08):

The old version should not have worked, I suspect this is a bug that was fixed

view this post on Zulip Vladimir Zotov (Jul 23 2024 at 15:48):

It was really not clear what's got broken from just looking at the error. My bad, thank you for spotting, Anton!

view this post on Zulip Brendan Hansknecht (Jul 23 2024 at 16:23):

Really interesting that roc generated ?. I thought type inference was fully decidable, Shouldn't ? be impossible?

view this post on Zulip Anton (Jul 23 2024 at 16:38):

I don't think ? is possible in an error free Roc program, perhaps it's meant to be used to be able to run code with some errors in it, or to be able to diagnose/report other errors in the program instead of stopping at that one.

view this post on Zulip Anton (Jul 23 2024 at 16:40):

The first error was the most helpful one, it highlighted the issue:

── TYPE MISMATCH in /home/username/Downloads/vladimir/YarnLockV1Parser.roc ─────

This 2nd argument to != has an unexpected type:

138│      |> keep (chompWhile (\c -> c != '"' && c != ":") |> map strFromUtf8)
                                                      ^^^

The argument is a string of type:

    Str

But != needs its 2nd argument to be:

    Int *

view this post on Zulip Anton (Jul 23 2024 at 16:42):

The display order of errors is not ideal, because in the terminal you see the last one first, but reversing the order does not seem great either...

view this post on Zulip Anton (Jul 23 2024 at 16:44):

Perhaps we should add a tip after the last error like: "We recommend starting with the first error at the top."?

view this post on Zulip Richard Feldman (Jul 23 2024 at 17:22):

Brendan Hansknecht said:

Really interesting that roc generated ?. I thought type inference was fully decidable, Shouldn't ? be impossible?

this is after type-checking, it's something during ability implementation auto-generation

view this post on Zulip Richard Feldman (Jul 23 2024 at 17:22):

that said, I'm not sure why it would print ? there :big_smile:

view this post on Zulip Vladimir Zotov (Jul 25 2024 at 13:04):

Could anyone help me compile my code re Luke's parser? @Anton || @Luke Boswell :bow:
I don't understand how to turn a parser for a list of possibly quoted strings into a list of definitely unquoted strings. Core.map doesn't do what I think it would, and I can't figure out a pass-through parser (in case the unquoting parser fails)

app [main] {
    cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
    parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.7.1/MvLlME9RxOBjl0QCxyn3LIaoG9pSlaNxCa-t3BfbPNc.tar.br",
}

import cli.Task
import cli.Stdout
import parser.Core exposing [Parser, many, oneOf, oneOrMore, const, skip, between, keep, apply, flatten, chompWhile, chompUntil, map, alt, sepBy]
import parser.String exposing [parseStr, codeunit, strFromUtf8, string, Utf8]

main =
    (parseStr dependencyHead "\"@adobe/css-tools@^4.3.2\":")
        |> \x ->
            when x is
                Ok output -> Str.joinWith output ", "
                Err e ->
                    when e is
                        ParsingFailure msg -> "ParsingFailure: $(msg)"
                        ParsingIncomplete msg -> "ParsingIncomplete: $(msg)"
        |> Stdout.line!

betweenQuotes : Parser Utf8 Str
betweenQuotes =
    const (\value -> value)
        |> skip (codeunit '"')
        |> keep (chompWhile (\c -> c != '"') |> map strFromUtf8)
        |> skip (codeunit '"')

untilColon =
    const (\value -> value)
    |> keep (chompWhile (\c -> c != ':') |> map strFromUtf8)
    |> skip (codeunit ':')

dependencyHead : Parser Utf8 (List Str)
dependencyHead =
    const (\value -> value)
    |> keep (untilColon |> sepBy (codeunit ',') |> map (alt betweenQuotes (const \x -> x)))

expect parseStr dependencyHead "\"@adobe/css-tools@^4.3.2\":" == Ok ["@adobe/css-tools@^4.3.2"]
expect parseStr dependencyHead "mime-db@1.52.0, \"mime-db@>= 1.43.0 < 2\":" == Ok ["mime-db@1.52.0", "mime-db@>= 1.43.0 < 2"]

view this post on Zulip Vladimir Zotov (Jul 25 2024 at 13:07):

That issue is the last step before I get to a compiler bug, that only happens when the rest of my code uses a variant type of two items and compiles if I only have a variant of one XD

view this post on Zulip Luke Boswell (Jul 26 2024 at 01:07):

This works I think. It's probably not 100% what your looking for.

Basically, I'd do that kind of string transformation inside the function we pass to const and just parse both kinds of strings the same.

app [main] {
    cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
    parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.7.1/MvLlME9RxOBjl0QCxyn3LIaoG9pSlaNxCa-t3BfbPNc.tar.br",
}

import cli.Task
import cli.Stdout
import parser.Core exposing [Parser, const, skip, keep, chompWhile, map, sepBy]
import parser.String exposing [parseStr, codeunit, strFromUtf8, Utf8]

main =
    (parseStr dependencyHead "\"@adobe/css-tools@^4.3.2\":")
        |> \x ->
            when x is
                Ok output -> Str.joinWith output ", "
                Err e ->
                    when e is
                        ParsingFailure msg -> "ParsingFailure: $(msg)"
                        ParsingIncomplete msg -> "ParsingIncomplete: $(msg)"
        |> Stdout.line!

untilColon =
    const (\value -> value)
    |> keep (chompWhile (\c -> c != ':') |> map strFromUtf8)
    |> skip (codeunit ':')

dependencyHead : Parser Utf8 (List Str)
dependencyHead =

    splitComma = \str -> Str.split str ","

    const \strings ->
        strings
        |> List.map splitComma # not sure if you wanted this in a parser or here is ok??
        |> List.join
        |> List.map Str.trim
        |> List.map removeQuotes
    |> keep (untilColon |> sepBy (codeunit ','))

expect
    actual = parseStr dependencyHead "\"@adobe/css-tools@^4.3.2\":"
    expected = Ok ["@adobe/css-tools@^4.3.2"]
    actual == expected

expect
    actual = parseStr dependencyHead "mime-db@1.52.0, \"mime-db@>= 1.43.0 < 2\":"
    expected = Ok ["mime-db@1.52.0", "mime-db@>= 1.43.0 < 2"]
    actual == expected

removeQuotes : Str -> Str
removeQuotes = \input ->
    if Str.startsWith input "\"" && Str.endsWith input "\"" then
        input
        |> Str.replaceFirst "\"" ""
        |> Str.replaceLast "\"" ""
    else
        input

expect removeQuotes "@adobe/css-tools@^4.3.2" == "@adobe/css-tools@^4.3.2"
expect removeQuotes "\"@adobe/css-tools@^4.3.2\"" == "@adobe/css-tools@^4.3.2"

view this post on Zulip Luke Boswell (Jul 26 2024 at 01:07):

$ roc test strings.roc
0 failed and 4 passed in 1299 ms.

view this post on Zulip Vladimir Zotov (Jul 26 2024 at 07:50):

Haha, that was also my last idea, but I thought it's cheating to use string replace :-D

view this post on Zulip Notification Bot (Jul 27 2024 at 06:01):

Vladimir Zotov has marked this topic as resolved.


Last updated: Jul 06 2025 at 12:14 UTC