Reputation: 598
I'm sure this problem is trivial, but I can't for the life of me figure it out. Suppose I have a list and I want to get the cumulative product of the list:
> let li = [1; 2; 3; 4;];;
val li : int list = [1; 2; 3; 4]
I can do this with List.scan
:
> li |> List.scan (fun acc value -> acc * value) 1;;
val it : int list = [1; 1; 2; 6; 24]
Notice the result is exactly 1 int
longer. That int
is the 1
in the front. Now, when you go to the microsoft webpage on List.scan, their example seems to return the exact same amount of elements. I don't see any place where they chop the extra element off.
Now, I can simply chop the leading element off:
> li |> List.scan (fun acc value -> acc * value) 1 |> List.tail;;
val it : int list = [1; 2; 6; 24]
and I get my result list. However, I am confused. The function is described as
This function takes the second argument, and applies the function to it and the first element of the list. Then, it passes this result into the function along with the second element, and so on.
To me, this would leave me with a list of the same size as the original, right? How are we getting an extra element?
Upvotes: 1
Views: 129
Reputation: 5004
The description finishes like this:
Finally, it returns the list of intermediate results and the final result.
The "and" suggests that it returns one extra element. Maybe it would be clearer if it mentioned that returns the initial state and the list of results.
Either way it seems to be a feature of the function. If the extra value is not required thenList.tail
chops it off.
Upvotes: 1
Reputation: 947
The webpage on List.scan gives an example where transactions
has 6 elements, and balances = [1122.73 ... 1257.31]
has 7 elements. (For correct accounting the code should be printfn "$%10.2f $%10.2f" transactions.[i] balances.[i]
).
The output of List.scan f s l
satisfies:
o.[0] = s
o.[i] = f(o.[i-1],l.[i-1])
This defines o[i]
for i in 0 .. l.Length
. So o.Length
is naturally l.Length+1
.
Upvotes: 0