Reputation: 9805
I want to specialise the list type to represent a time serie. This will allow for some additional methods and better readibility.
I would like to reuse all the functions written in the Seq module, while keeping the original underlying type.
module Analytics =
open System
type TimeSerie<'T> () =
inherit ResizeArray<DateTime*'T> ()
module TimeSerie =
open Analytics
let filter f (ts:TimeSerie<'T>) = (Seq.filter f (ts)) |> ResizeArray.ofSeq :?> TimeSerie<'T>
.... same for map, etc..
Is there any alternate way to do this that could cut code ?
Upvotes: 1
Views: 142
Reputation: 41290
In short, no.
There is no easy way to do it. That's one reason why List
, Array
and Seq
modules have their own implementations of those high-order functions.
In your example, I suggest to use ResizeArray module from F# PowerPack, where you have all high-order functions ready to use. Specialization to ResizeArray<DateTime*'T>
could be done by wrapping it in a single-case discriminated unions.
Upvotes: 2
Reputation: 55184
In general, there is no way to do what you want since there is no standard way to build arbitrary subtypes of 't seq
in F# or .NET. The only semi-mainstream programming language that I'm aware of that does something like what you're looking for is Scala, and the Scala collections library is notoriously intricate.
To illustrate one of the problems with defining a more "generic" Seq.filter
function, consider the following type definition:
type Singleton<'t>(t:'t) =
interface seq<'t> with
member __.GetEnumerator() : System.Collections.IEnumerator =
([t] :> System.Collections.IEnumerable).GetEnumerator()
member __.GetEnumerator() : System.Collections.Generic.IEnumerator<'t> =
([t] :> seq<_>).GetEnumerator()
Now all instances of this class have exactly one element, but filtering will either result in a sequence with zero or one elements. Clearly, this means that the static type of
Singleton(1)
|> Seq.filter (fun x -> x > 5)
must be something other than Singleton<int>
.
Upvotes: 1