Reputation: 2178
Is there a possibility of writing functions which are generic in respect to collection types they support other than using the seq
module?
The goal is, not having to resort to copy and paste when adding new collection functions.
Upvotes: 0
Views: 166
Reputation: 2380
Generic programming with collections can be handled the same way generic programming is done in general: Using generics.
let f (map_fun : ('T1 -> 'T2) -> 'T1s -> 'T2s) (iter_fun : ('T2 -> unit) -> 'T2s -> unit) (ts : 'T1s) (g : 'T1 -> 'T2) (h : 'T2 -> unit)=
ts
|> map_fun g
|> iter_fun h
type A =
static member F(ts, g, h) = f (Array.map) (Array.iter) ts g h
static member F(ts, g, h) = f (List.map) (List.iter) ts g h
A bit ugly and verbose, but it's possible. I'm using a class and static members to take advantage of overloading. In your code, you can just use A.F and the correct specialization will be called.
For a prettier solution, see https://stackoverflow.com/questions/979084/what-features-would-you-add-remove-or-change-in-f/987569#987569 Although this feature is enabled only for the core library, it should not be a problem to modify the compiler to allow it in your code. That's possible because the source code of the compiler is open.
Upvotes: 2
Reputation: 243051
The seq<'T>
type is the primary way of writing computations that work for any collections in F#. There are a few ways you can work with the type:
Seq
module (such as Seq.filter
, Seq.windowed
etc.)seq { for x in col -> x * 2 }
)IEnumerator<'T>
type, which is sometimes needed e.g. if you want to implement your own zipping of collections (this is returned by calling GetEnumerator
)This is relatively simple type and it can be used only for reading data from collections. As the result, you'll always get a value of type seq<'T>
which is essentially a lazy sequence.
F# doesn't have any mechanism for transforming collections (e.g. generic function taking collection C
to collection C
with new values) or any mechanism for creating collections (which is available in Haskell or Scala).
In most of the practical cases, I don't find that a problem - most of the work can be done using seq<'T>
and when you need a specialized collection (e.g. array for performance), you typically need a slightly different implementation anyway.
Upvotes: 1