Skip to content

Add List.Extra.insertAt#99

Merged
gampleman merged 3 commits intoelmcraft:masterfrom
Janiczek:master
Mar 25, 2026
Merged

Add List.Extra.insertAt#99
gampleman merged 3 commits intoelmcraft:masterfrom
Janiczek:master

Conversation

@Janiczek
Copy link
Copy Markdown
Contributor

insertAt 3 "X" ["a","b","c","d","e"]
---------------0---1---2---^3
-->            ["a","b","c","X","d","e"]

The behaviour with out-of-bounds indexes mirrors Array.Extra.insertAt.

Benchmarks:

Screenshot 2026-03-21 at 20 03 31

I chose the splitAt approach.

  • intended "happy" case: the splitAt approach is 2x faster
  • edge cases:
    • negative index: All approaches do the same thing - any differences are basically a measurement error
    • large positive index: the takeDrop approach is faster, but this is still an edge case so I wouldn't give this too much weight

@lue-bird
Copy link
Copy Markdown
Collaborator

lue-bird commented Mar 21, 2026

Cool!
When I change the recursive definition to use List.foldl (::) instead of List.reverse ++ I get these results:
image
with similar results in firefox.
(I also increased the benchmarked list to 100 elements and moved the let helper to the top level but the foldl is the biggest influence)

@lue-bird
Copy link
Copy Markdown
Collaborator

lue-bird commented Mar 21, 2026

Also, here's a nice test to add to verify the final order is correct:

fuzz2
    (Fuzz.intRange 0 4)
    (Fuzz.listOfLengthBetween 4 10 (Fuzz.intRange 0 10))
    "index in bounds (0 <= index <= length) inserts in the right place in the list keeping the elements in the right order"
  <|
    \goodIndex list ->
        List.Extra.insertAt goodIndex -1 list
            |> List.Extra.removeAt goodIndex
            |> Expect.equal list

@Janiczek
Copy link
Copy Markdown
Contributor Author

Also, here's a nice test

ah yes, that one's much better than mine, thanks!

I've incorporated your notes in 587293c. Here's the benchmark on a second machine:

Screenshot 2026-03-22 at 11 47 13


insertAtRecursion2Help : Int -> a -> List a -> Int -> List a -> List a -> List a
insertAtRecursion2Help index value list i rest acc =
if i == index then
Copy link
Copy Markdown
Collaborator

@lue-bird lue-bird Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I forgot to mention that in my benchmarks this instead counts down from index and checks when it goes to 0. This avoids the extra i argument but should not be that much faster (not sure if comparisons with a literal are only optimized in eol2 or elm make)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Janiczek
Copy link
Copy Markdown
Contributor Author

@lue-bird 2x speedup for such a small change, that's awesome!

Screenshot 2026-03-23 at 9 05 13

@gampleman gampleman merged commit d8486ad into elmcraft:master Mar 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants