Let’s take this code:
open System
open System.IO
let lines = seq {
use sr = new StreamReader(@"d:\a.h")
while not sr.EndOfStream do yield sr.ReadLine()
}
lines |> Seq.iter Console.WriteLine
Console.ReadLine()
Here I am reading all the lines in a seq, and to go over it, I am using Seq.iter. If I have a list I would be using List.iter, and if I have an array I would be using Array.iter. Isn’t there a more generic traversal function I could use, instead of having to keep track of what kind of collection I have? For example, in Scala, I would just call a foreach and it would work regardless of the fact that I am using a List, an Array, or a Seq.
Am I doing it wrong?
You may or may not need to keep track of what type of collection you deal with, depending on your situation.
In case of simple iterating over items nothing may prevent you from using
Seq.iteron lists or arrays in F#: it will work over arrays as well as over lists as both are also sequences, orIEnumerables from .NET standpoint. UsingArray.iterover an array, orList.iterover a list would simply offer more effective implementations of traversal based on specific properties of each type of collection. As the signature of Seq.iterSeq.iter : ('T -> unit) -> seq<'T> -> unitshows you do not care about your type'Tafter the traversal.In other situations you may want to consider types of input and output arguments and use specialized functions, if you care about further composition. For example, if you need to filter a list and continue using result, then
List.filter : ('T -> bool) -> 'T list -> 'T listwill preserve you the type of underlying collection intact, butSeq.filter : ('T -> bool) -> seq<'T> -> seq<'T>being applied to a list will return you a sequence, not a list anymore: