question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

List traverse runs from right to left

See original GitHub issue

Description

It looks like List.traverse runs from right to left, it should be from left to right according to the document.

Repro steps

Below code could reproduce this problem

let mapper (v: int) =
    Console.WriteLine(sprintf "mapping: %d" v)
    Result.Ok v

let test v =
     List.traverse mapper v |> Result.map List.last
   
 test [1; 2; 3]

Expected behavior

It should prints

mapping: 1 mapping: 2 mapping: 3

Actual behavior

It prints in the reverse order

mapping: 3 mapping: 2 mapping: 1

Related information

The code runs with FSharpPlus 1.1.6

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
3Rafalcommented, Jan 5, 2021

I guess we can even do it in 2 passes with this version:

let traverseList' f lst =
    let rec loop acc = function
        | [] -> acc
        | x::xs -> let v = f x
                   let consed = List.cons <!> v <*> acc
                   if v |> IsLeftZero.Invoke |> not 
                   then loop consed xs 
                   else consed 
    loop (result []) lst 
    |> Map.Invoke List.rev

What do you think @gusty ?

EDIT: I’ve ran simple performance tests:

#time

let ok_f v = Ok v : Result<int,string>
let oldOne = List.traverse ok_f [1..5000000];; 
let newOne = traverseList' ok_f [1..5000000];;

and the results show that this implementation seems to have similar performance

> let newOne = traverseList' ok_f [1..5000000];;;;
Real: 00:00:03.790, CPU: 00:00:03.765, GC gen0: 180, gen1: 53, gen2: 2
> let oldOne = List.traverse ok_f [1..5000000];; ;;
Real: 00:00:05.454, CPU: 00:00:05.875, GC gen0: 220, gen1: 63, gen2: 3
1reaction
gustycommented, Dec 31, 2020

Sure, but note that it’s not a good practice, even in F#, to include sideeffects in let’s say a map function call, it’s always better and more readable (and less surprising) to use a dedicated iter to perform side-effects. The same applies for traverse.

Anyway, let’s try to come up with a solution that fixes the order without compromising performance too much.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Traverse a list in reverse order in Python [duplicate]
Use list. reverse() and then iterate as you normally would. for what ever it's worth you can do it like this too. very...
Read more >
Traverse a list in reverse order in Python
This post will discuss how to traverse a list in reverse order in Python without modifying the original list. 1. Using built-in reversed()...
Read more >
Iterating Backward Through a List
In this quick tutorial, we'll learn about various ways in which we can iterate backward through a list in Java.
Read more >
Java Program to Traverse Through ArrayList in Reverse ...
There are several methods by which we can Iterate and print List in reverse direction listed below. Method 1: (Using ListIterator). 1. Declare ......
Read more >
ZigZag Tree Traversal
Whenever the current level order is from left to right, push the nodes left child, then its right child to the stack nextlevel....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found