[英]Apply Seq module operations to a subtype while keeping original type in f#
我想专门化列表类型来表示时间系列。 这将允许一些额外的方法和更好的可读性。
我想重用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..
是否有任何替代方法可以削减代码?
简而言之,没有。
没有简单的方法可以做到这一点。 这就是List
, Array
和Seq
模块有自己的高阶函数实现的原因之一。
在您的示例中,我建议使用F#PowerPack中的 ResizeArray模块 ,您可以在其中使用所有高阶函数。 ResizeArray<DateTime*'T>
专业化可以通过将其包装在单个案例区分联合中来完成。
一般来说,没有办法做你想要的,因为没有标准的方法来构建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>
以外的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.