我想专门化列表类型来表示时间系列。 这将允许一些额外的方法和更好的可读性。
我想重用Seq模块中编写的所有函数,同时保留原始底层类型。
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..
有没有其他方法可以切断代码?
答案 0 :(得分:2)
简而言之,没有。
没有简单的方法可以做到这一点。这就是为什么List
,Array
和Seq
模块有自己的高阶函数实现的原因之一。
在您的示例中,我建议使用ResizeArray module中的F# PowerPack,您可以在其中使用所有高阶函数。 ResizeArray<DateTime*'T>
的专业化可以通过将其包装在一个单一案例的歧视联盟中来完成。
答案 1 :(得分:1)
通常,没有办法做你想要的,因为没有标准的方法在F#或.NET中构建't seq
的任意子类型。我所知道的唯一的半主流编程语言就像Scala一样,而且Scala集合库非常复杂。
为了说明定义更“通用”Seq.filter
函数的一个问题,请考虑以下类型定义:
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()
现在,此类的所有实例都只有一个元素,但过滤将导致序列中包含零个或一个元素。显然,这意味着静态类型
Singleton(1)
|> Seq.filter (fun x -> x > 5)
必须是Singleton<int>
以外的其他内容。