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?
Hi @Vladimir Zotov,
Can you share the full code?
I changed c != ":"
and c == ":"
to c != ':'
and c == ':'
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
.
The old version should not have worked, I suspect this is a bug that was fixed
It was really not clear what's got broken from just looking at the error. My bad, thank you for spotting, Anton!
Really interesting that roc generated ?
. I thought type inference was fully decidable, Shouldn't ?
be impossible?
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.
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 *
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...
Perhaps we should add a tip after the last error like: "We recommend starting with the first error at the top."?
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
that said, I'm not sure why it would print ?
there :big_smile:
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"]
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
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"
$ roc test strings.roc
0 failed and 4 passed in 1299 ms.
Haha, that was also my last idea, but I thought it's cheating to use string replace :-D
Vladimir Zotov has marked this topic as resolved.
Last updated: Jul 06 2025 at 12:14 UTC