I'd like to run (1..=10).sum() but Iter.sum does not exist. I can work around this by writing (1..=10)->List.from_iter().sum() and this works fine, but it's a pity we have to materialize a List for this. So I wrote the following function:
sum = |iter| {
var $s = 0
for value in iter {
$s = $s + value
}
$s
}
It works fine, I can now write (1..=10)->sum(). However, I'd like to add the type spec for this function, and I just can't. The inferred type is:
a -> b
where [
a.iter : a -> Iter(item),
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
b.plus : b, item -> b,
]
But when I try to use this type spec, I get an error. Here's a REPL session that shows the error:
» sum : a -> b where [
a.iter : a -> Iter(item),
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
b.plus : b, item -> b,
]
sum = |iter| {
var $s = 0
for value in iter {
$s = $s + value
}
$s
}
assigned `sum`
»
» (1..=10)->sum()
┌───────────────────┐
│ POLYMORPHIC VALUE ├─ This top-level value still has an unresolved polymorphic type. ─────────────────────────────────────────────────────────────────────────┐
└┬──────────────────┘ │
│ │
│ main = (1..=10)->sum() │
│ ‾‾‾‾ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── repl:14:1 ┘
Its type is:
b
where [
b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
b.plus : b, Dec -> b,
]
Add an annotation or use this value in a way that fixes its concrete type.
┌────────────────┐
│ MISSING METHOD ├─ This is trying to dispatch a method named from_numeral on an unresolved type variable, but unresolved type variables have no methods. ─────┐
└┬───────────────┘ │
│ │
│ main = (1..=10)->sum() │
│ ‾‾‾ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── repl:14:18 ┘
Hint: You can replace this static dispatch call with an ordinary function call, or force the type variable to become more concrete—for example, by adding a
type annotation that narrows its type to something that actually has methods.
»
Should I file a bug?
@Jared Ramirez
oh this is a bug, should be a quick fix
separately, Iter.sum seems reasonable to me :thumbs_up:
I had a use case for Iter.sum too in roc-random. I wound up doing it manually with folding but considered going to List so I could use List.sum I figured it would allocate but I was wondering if that’s the kind of thing that would get optimized away, and if so how dependable is that optimization to happen, and lastly is there a way/plan to be able to inspect whether these kind of optimizations are happening? I’m sure it’s a beast of a compilation pipeline, was just curious. @Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function
@Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function
Yes that is a very convenient way to check. You can also look at the llvm IR, instructions from Claude:
Quickest way to inspect IR right now: in src/cli/builder.zig around line 617-631, change
`.llvm_ir_filename = null,`
to point at a path, e.g. .llvm_ir_filename = "/tmp/out.ll".ptr, (temporarily, for debugging) before the emit_options struct
is passed to ZigLLVMTargetMachineEmitToFile at line 633. Rebuild with zig build roc and run your compile — you'll get a
human-readable .ll file alongside the object output.
@Aurélien Geron this now works, and also Iter.sum is a builtin!
Anton said:
@Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function
Yes that is a very convenient way to check. You can also look at the llvm IR, instructions from Claude:
Quickest way to inspect IR right now: in src/cli/builder.zig around line 617-631, change `.llvm_ir_filename = null,` to point at a path, e.g. .llvm_ir_filename = "/tmp/out.ll".ptr, (temporarily, for debugging) before the emit_options struct is passed to ZigLLVMTargetMachineEmitToFile at line 633. Rebuild with zig build roc and run your compile — you'll get a human-readable .ll file alongside the object output.
Nice thanks so much I’m gonna try both approaches
Last updated: Aug 12 2026 at 12:35 UTC