Hi, I am just beginning to experiment with the language, and I have encountered several surprising behaviors. I didn't see these on the issues page, but I might have just missed them.
What I was trying to do was implement a function which takes two lists, and determines if the first is in the second. It's the same as Haskell's isInfixOf
.
This was my first attempt
app "sublist"
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br" }
imports [pf.Stdout]
provides [main] to pf
main = Stdout.line "hi"
contains = \a, b ->
List.len a <= List.len b && (List.startsWith b a || contains a (List.dropFirst b 1))
expect contains [1] [1]
That will stackoverflow, even though List.startsWith [1] [1]
is true, which should short circuit ||
, which I assume is an inclusive or.
Next I tried
contains = \a, b ->
when (a, b) is
([], _) -> Bool.true
(_, []) -> Bool.false
(_, [_, .. as tail]) ->
List.len a <= List.len b && (List.startsWith b a || contains a tail)
For this it complained that my pattern matching isn't exhaustive because "Other possibilities include ( [_, ..], _ )
". I do not understand how that other possibility is not part of my patterns.
The below works, but I am curious to know if I have misunderstandings or if the above are bugs. Thanks!
contains = \a, b ->
when (a, b) is
([], _) -> Bool.true
(_, []) -> Bool.false
(_, _) ->
List.len a <= List.len b && (List.startsWith b a || contains a (List.dropFirst b 1))
||
doesn't currently short-circuit. It's a change we've talked about but haven't implemented yet!
For this it complained that my pattern matching isn't exhaustive because "Other possibilities include ( [_, ..], _ )"
I'll file an issue for that
Richard Feldman said:
||
doesn't currently short-circuit. It's a change we've talked about but haven't implemented yet!
Oh, well that would explain that. Which gives me the idea to do it like this. (I also found the format command)
contains = \a, b ->
List.len a
<= List.len b
&& (
if
List.startsWith b a
then
Bool.true
else
contains a (List.dropFirst a 1))
Thanks for responding. Cool language!
Last updated: Jul 06 2025 at 12:14 UTC