Stream: beginners

Topic: Pattern matching on strings/binaries


view this post on Zulip Hannes Nevalainen (Dec 01 2023 at 17:20):

Im trying to solve this years AdventOfCode with Roc, I already made solution with Elixir that came out quite nice since it has binary pattern matching but Im struggling a bit on how to do something similar with Roc.

Is there a way of pattern match on a string in Roc? Or should I just split by graphemes and pattern match on list instead?

Maybe it is the completely wrong approach fr Roc. Is anyone else doing AdventOfCode in Roc so where I could snek peak on the code?

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 17:21):

I think only list has prefix pattern matching and the like

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 17:22):

So you could turn it into a list and pattern match

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 17:22):

That said, I'm not actually sure what "binary" pattern matching directly refers to.

view this post on Zulip Anton (Dec 01 2023 at 17:32):

@Hannes Nevalainen,
Several day 1 solutions have been posted in this thread.

view this post on Zulip Hannes Nevalainen (Dec 01 2023 at 17:45):

It is a way to match/destructure a binary (string of bytes).

<<a, b, rest::binary>> = "hello"

I would imagine it would look like something like this:

match "hello" is
   "he" <> _  -> 1
  "two" <> _  -> 2

but it might not make sense in the context of Roc, Im still learning :)

In elixir it looks like this.

  def find_digits2(<<>>), do: []

  def find_digits2(<<c, rest::binary>>) when c >= ?0 and c <= ?9,
    do: [c - ?0 | find_digits2(rest)]

  def find_digits2("one" <> rest),     do: [1 | find_digits2(rest)]
  def find_digits2("two" <> rest),     do: [2 | find_digits2(rest)]
  def find_digits2("three" <> rest),  do: [3 | find_digits2(rest)]
  def find_digits2("four" <> rest),    do: [4 | find_digits2(rest)]
  def find_digits2("five" <> rest),     do: [5 | find_digits2(rest)]
  def find_digits2("six" <> rest),       do: [6 | find_digits2(rest)]
  def find_digits2("seven" <> rest), do: [7 | find_digits2(rest)]
  def find_digits2("eight" <> rest),  do: [8 | find_digits2(rest)]
  def find_digits2("nine" <> rest),   do: [9 | find_digits2(rest)]

  def find_digits2(<<_, rest::binary>>), do: find_digits2(rest)

(I know this doesnt account for the catch in todays problem).

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 17:47):

Currently to do something like that, first call Str.toUtf8 the pattern match on the returned list of bytes

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 17:47):

Not as compact, but gets the same thing done

view this post on Zulip Hannes Nevalainen (Dec 01 2023 at 17:49):

Anton said:

Hannes Nevalainen,
Several day 1 solutions have been posted in this thread.

Right, it would be smarter to start searching zulip for "AdventOfCode" instead of "string pattern match" that doesn't exists :sweat_smile:

view this post on Zulip Hannes Nevalainen (Dec 01 2023 at 17:51):

Brendan Hansknecht said:

Currently to do something like that, first call Str.toUtf8 the pattern match on the returned list of bytes

Would that actually convert it to a list of bytes under the hood to?

view this post on Zulip Brendan Hansknecht (Dec 01 2023 at 18:59):

A string is already a list of bytes under the hood. Generally Str.toUtf8 actually does nothing.

view this post on Zulip Hannes Nevalainen (Dec 01 2023 at 20:16):

Thanks for your help :)

view this post on Zulip Sky Rose (Dec 02 2023 at 14:47):

I know I'm late to this, but you could also use Str.startsWith and a bunch of else ifs, instead of doing it in a match.


Last updated: Jul 05 2025 at 12:14 UTC