编写函数的最佳方法是什么,以便它们可以无缝地处理:
我特别需要编写函数,例如计算时间序列的平均值/方差/随机变换,我想只编写这些函数的1个版本.
Tom*_*cek 13
正如评论中所述,关键问题是您希望在数据类型上编写什么类型的操作.有可能为基本的数值运算执行此操作,但如果您需要一些更复杂的计算,那么编写两个单独的函数可能会更容易.
无论如何,如果要使用基本的数值运算,则需要为时间戳类型定义标准数字运算符.我描述了在最近的一篇文章这样.以下实现+,除以整数和零:
open System
type TimedFloat =
{ Time : DateTime
Value : float }
static member (+) (tf1, tf2) =
{ Time = DateTime(tf1.Time.Ticks + tf2.Time.Ticks)
Value = tf1.Value + tf2.Value }
static member Zero =
{ Time = DateTime.MinValue
Value = 0.0 }
static member DivideByInt(tf, n) =
{ Time = DateTime(tf.Time.Ticks / int64 n)
Value = tf.Value / float n }
Run Code Online (Sandbox Code Playgroud)
该+运营商有点怀疑,因为你有一些非常大的日子结束了(也许是使用TimeSpan从上会更有意义).但是,一旦定义了运算符,您就可以使用Seq.average:
[ { Time = DateTime.Now
Value = 3.0 }
{ Time = DateTime.Now.AddDays(2.0)
Value = 10.0 } ]
|> Seq.average
Run Code Online (Sandbox Code Playgroud)
该Seq.average函数适用于两种类型,因为它是使用静态成员约束编写的(这意味着它适用于具有必要成员的任何类型).编写这样的函数比编写普通函数更困难,所以默认情况下我可能不会使用这种函数.无论如何,这里有一个介绍更多的例子,这个答案显示更多有用的技巧.
编辑 -正如Jon Harrop指出的那样,这是一种非常复杂的方法,它只给你带来有限的好处.如果您只需要处理这些值,那么转换为一系列值是一种更好的方法.如果您需要更复杂的计算,那么我认为编写泛型函数并不值得.为float和timestamped值编写两个单独的函数可能会更容易.
只需将带时间戳的seq转换为float seq,如下所示:
xs
|> Seq.map (fun x -> x.value)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
308 次 |
| 最近记录: |