I don't really get an error like this:
type mismatch
The append method on List has an incompatible type.
result2 = parsed.fold([50], |acc, item| {
The method append has the type:
List(a), a -> List(a)
where [
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
a.plus : a, c -> a,
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
]
But I need it to have the type:
List(a), a -> {}
where [
a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)]),
a.plus : a, c -> a,
c.from_numeral : Numeral -> Try(c, [InvalidNumeral(Str)]),
]
I don't mess with append do I? How can the type of append change?
Code here:
result2 = parsed.fold([50], |acc, item| {
var last = acc.last().ok_or(0)
(d, n) = match item {
Left(i) => (-1, i)
Right(i) => (1, i)
}
for _ in 0..<n {
acc.append(last + d)
last = last + d
}
acc
}).keep_if(|n| n.mod_by(100) == 0).len()
Where does the .plus even come from?
Another one:
add_from : I16, Rotation -> List(I16)
add_from = |start, r| match r {
Left(i) => (-1..<-i).iter().map(|n| start + n)
Right(i) => (1..<i).iter().map(|n| start + n)
}
Results in:
The first branch of this match does not match the previous branch .
Left(i) => (-1..<-i).iter().map(|n| start + n)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first branch is:
Iter(I16)
But the previous branch results in:
List(I16)
Though I don't understand how they could have different types.
(-1..<-i).iter().map(|n| start + n)
Ah I guess descending ranges do not work? That's annoying and unclear how to fix it.
Hi @Alper,
Yeah, the error message isn't clear. There were a few little errors in your code, here's the corrected code:
parsed = [Left(1), Right(2), Left(3)]
main! = |_args| {
result2 = parsed.fold([50], |acc, item| {
var $last = acc.last() ?? 0
(d, n) = match item {
Left(i) => (-1, i)
Right(i) => (1, i)
}
var $next_acc = acc
for _ in 0..<n {
$next_acc = $next_acc.append($last + d)
$last = $last + d
}
$next_acc
})
.keep_if(|n| n.mod_by(100) == 0)
.len()
dbg result2
Ok({})
}
$: $last instead of lastacc is constant, so you can't just append anything to it. One option is to create a variable $next_acc and update that.?? 0 over .ok_or(0), but perhaps it's just a matter of taste.Note: I tried to change your code as little as I could, but I'm pretty sure there's a way to implement this without using variables, with a more functional approach. Perhaps a useful exercise to try?
For your second code example, Iter.map() returns an Iter, not a List, so you have to call List.from_iter:
Rotation : [Left(I16), Right(I16)]
add_from : I16, Rotation -> List(I16)
add_from = |start, r|
match r {
Left(i) => (-1..<-i).iter().map(|n| start + n) |> List.from_iter
Right(i) => (1..<i).iter().map(|n| start + n) |> List.from_iter
}
Alternatively, you can make add_from return Iter(I16).
Where did this "|>" come from?
It's the pipe operator. It's just syntax sugar when chaining multiple functions. The following are equivalent:
result = input |> f(1) |> g(2, 3) |> h
result = h(g(f(input, 1), 2, 3))
I get that but I can't find it either in:
What should be my reference to find stuff?
The all syntax example is nice.
You can also check out the other examples.
But eventually the tutorial and langref should contain everything indeed.
Thank you for sharing your experience, its really helpful to see roc's syntax through fresh eyes :grinning_face_with_smiling_eyes:
Perhaps a useful exercise to try?
Yeah, this is just advent of code day1-2.
add_from : I16, Rotation -> List(I16)
add_from = |start, r| match r {
Left(i) => (-i..<0).iter().map(|n| start + n) |> List.from_iter |> List.rev
Right(i) => (1..=i).iter().map(|n| start + n) |> List.from_iter
}
result2 = parsed.fold([50], |acc, item| {
last = acc.last().ok_or(0)
acc.concat(add_from(last, item))
}).keep_if(|n| n.mod_by(100) == 0).len()
Is it cleaned up. Thanks for the pointers!
Last updated: Sep 03 2026 at 15:16 UTC