Hi there. I know I am doing something wrong, but instead of giving me a helpful suggestion, the compiler crashes. Is this a known error or should I file it as a bug?
foo = \x ->
when x is
Bool.false -> Ok Bool.false
NotImplemented op -> Ok Bool.true
Gives:
❯ roc check
An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: https://github.com/roc-lang/roc/issues/new/choose
thread '<unnamed>' panicked at 'After type checking, a constructor can never align with a literal: that should be a type error!', crates/compiler/exhaustive/src/lib.rs:637:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
There was an unrecoverable error in the Roc compiler. The `roc check` command can sometimes give a more helpful error report than other commands.
Hello :wave:
A fellow beginner Rocketeer here! It's probably best to wait for the more experienced members to join the discussion but, in the meantime, I'll try to help. My understanding is that pattern matching on booleans is currently not supported.
References:
In your case, some if
-then
-else
might be more applicable, given this current limitation.
General related question: what is the type of x
supposed to be in your code sample? It looks like it is trying to be two different types at once. Both Bool and a tag that contains a NotImplemented variant.
I was in the process of trying to recreate a pattern from other ML languages like Haskell with a sum type e.g. Either
. To represent if the operation is implemented or not, but I got stuck along the way and then I just made the reproducible example as small as possible. What I actually want to achieve is something of the sort Left a | Right b
. Imagine getting passed a data structure like this to a hypothetical testEquality
function:
testEquality [
{ op: "Equals", a: 1, b: 1 },
{ op: "NotEquals", a: 1, b: 2 },
{ op: "UnknownOperand", a: 1, b: 2 },
]
I then want to report back the equality test doesn't work on that last op
I was meaning to inquire about the type of x
as well actually, but I dismissed this question in my head because my assumption has been that the current standard-library booleans couldn't be made to work in that context, regardless of the type of x
.
If the solution doesn't have to depend on the standard library, I wonder if it would be possible with a custom type, which would implement the Eq
ability. Without having experimented with it, I couldn't confidently convince myself that it wouldn't be possible.
Update: Based on Richard's comment below, it seems that implementing custom equality behaviour wouldn't be necessary at all.
I don't totally understand the example, but you can implement Either
in Roc like this if you want:
Either a b : [Left a, Right b]
and then use Left
and Right
the same way as you would in Haskell
is that helpful?
Thanks Richard. Though it is not quite what I was aiming for. I guess I need to post the full example.
I am playing around and found that I want to make a program that can take in data like the above example
[
{ operand: "Equals", a: 1, b: 1 },
{ operand: "NotEquals", a: 1, b: 2 },
{ operand: "ThisOperandDoesNotExist", a: 1, b: 2 },
]
I want to go from here to testing equality for each record in the array.
I have then implemented the equality operators like this:
(I am missing a step where I convert from String "Equals"
to tag Equals
)
compare = \op, a, b ->
when op is
Equals -> Ok (a == b)
NotEquals -> Ok (a != b)
GreaterThan -> Ok (a > b)
LessThan -> Ok (a < b)
GreaterThanOrEquals -> Ok (a >= b)
LessThanOrEquals -> Ok (a <= b)
_ -> NotImplemented op
Then I want to execute all these comparisons, e.g.
executeRulesFold = \rules ->
List.walk rules (Ok Bool.true) \state, rule ->
result <- compare rule.condition rule.a rule.b
when result is
Ok Bool.true -> state
Ok Bool.false -> Ok Bool.false
NotImplemented op -> NotImplemented op
Mind you, I am not that proficient in functional programming and I am just exploring and want to learn Roc and how to solve problems with this language :).
So what I hope for with this is being told that there is an unknown operand in the data passed in "ThisOperandDoesNotExist"
by way of the tag NotImplemented
I hope it makes sense.
that looks mostly like it should work (except for the compiler bug), although it should be result =
and not result <-
with result <-
, that function will be equivalent to this:
executeRulesFold = \rules ->
List.walk rules (Ok Bool.true) \state, rule ->
compare rule.condition rule.a rule.b \result ->
when result is
Ok Bool.true -> state
Ok Bool.false -> Ok Bool.false
NotImplemented op -> NotImplemented op
but that's not going to work, because compare
doesn't take a function as its last argument :big_smile:
(because result <-
is syntax sugar for a "backwards lambda" essentially)
assuming the compiler bug is happening on this part of it:
Ok Bool.true -> state
Ok Bool.false -> Ok Bool.false
...you can try writing it like this instead as a workaround:
Ok bool if bool -> state
Ok _ -> Ok Bool.false
that should sidestep the compiler bug, assuming that's what the problem is!
Richard Feldman said:
that looks mostly like it should work (except for the compiler bug), although it should be
result =
and notresult <-
this syntax made me a little bit confused at a first.
There was this thread here to help beginners with Task understanding or something like this and I think this was the only thing that made me scratch my head for a few minutes, until I read the actual Roc docs on it.
Not directly related to Task use, but it is usually something that we do with Tasks
yeah, we're working on a different syntax for chaining tasks that will hopefully be easier to pick up! :big_smile:
Last updated: Jul 05 2025 at 12:14 UTC