我是一名机械工程研究生,我的顾问刚刚让我为我们的一个传感器项目编写数据可视化实用程序。因为这是夏天,他希望我对它有一些乐趣,我认为这是学习一门擅长科学计算的语言的好时机,所以我继续前进,直接进入F#。
由于我是功能编程范例的新手,我在构建程序时遇到了一些困难,特别是考虑到在F#中轻松组合OO / FP的可能性。我的任务如下:
我应该如何设计我的应用程序?我想过这样的事情: 1.我打算连接到每个传感器以开始接收数据,然后将这些数据转储到消息队列中。 我有一个事件驱动的处理函数接收队列上的数据。当接收到数据时,确定数据来自哪个传感器,然后将数据放入相应传感器的时间序列对象中。 3.每次添加传感器数据时间序列对象时,我都可以触发一个事件并让我的统计函数处理传感器的新数据。
显然我需要在这个应用程序中保持某种状态。所以我添加了以下可变数据结构。我将使用通用.NET可调整大小的List来存储我的时间序列数据,并实现一个新的派生来触发数据添加事件。我可以在一个字典中存储sensorid和实际时间序列容器之间的映射(当数据从队列中弹出时,我可以读取sensorid字段,获取该sensorid的时间序列容器,然后轻松添加新数据)。我还可以使用第二个字典来存储sensorid和包含该传感器时间序列统计信息的各种时间序列之间的映射。当添加主传感器时间序列时,它会触发一个事件来调用所有统计函数以在新数据上运行它们,并将它们的信息存储在该传感器的相应字典中。
我还没有想过如何保存数据,但我想我可以用数据写出二进制文件。
赞赏任何建议,想法或参考。
谢谢:)
答案 0 :(得分:5)
我建议不要在F#中实现新项目,直到你更好地处理语言,否则你最终会用F#语法编写C#代码。至少对于工作中的项目来说,使用你所知道的工具比使用公司资金试验新技术更好。
但是,既然你问过,我会使用mailbox processor作为所有传感器输入的线程安全消息处理队列。消息队列可以重新计算每个接收消息的统计信息。在我的头脑中,我正在考虑这样的设置:
type SensorMsg<'a, 'b> =
| Fetch of 'a AsyncReplyChannel
| Post of 'b
| Die
type SensorMessageQueue<'a, 'b>(emptyStats : 'a, compute : 'a -> 'b -> 'a) =
let queue = MailboxProcessor.Start(fun inbox ->
let rec loop stats =
async {
let! msg = inbox.Receive()
match msg with
| Die -> return ()
| Post(x) -> return! loop (compute stats x)
| Fetch(x) -> x.Reply(stats); return! loop stats
}
loop emptyStats
)
member this.Post(x) = queue.Post(Post(x))
member this.Fetch() = queue.PostAndReply(fun replyChannel -> Fetch(replyChannel))
member this.Die() = queue.Post(Die)
这样的事情可以保存传感器的实时运行统计数据。例如,假设我想发布一些可以保持平均运行的东西:
let averager =
SensorMessageQueue(
(0, 0), (* initial state of sum, total *)
(fun (sum, total) input -> sum + input, total + 1)
)
averager.Post(75)
averager.Post(90)
averager.Post(80)
let x = averager.Fetch() (* returns (245, 3) *)
averager.Post(100)
let y = averager.Fetch() (* returns (345, 4) *)
这样的设置相对容易使用,线程安全,并且不使用可变状态(闭包的参数中存在所有“状态”)。如果你考虑一下,这基本上是一个美化的seq.unfold,只能使用邮箱处理器实现。它可能过度,可能恰到好处,或者可能正是您的项目所需要的,这取决于您的要求。
答案 1 :(得分:2)
我可能完全错了,这不是你问题的答案,所以请随意投票给我,但我对F#一年多的兴趣的“感觉”是没有那么多那些人(或“在这里”)在科学/技术环境中使用F#的经验很丰富(我知道one exception)。
微软可能会把他们的努力集中在F#对金融界的推广上 - 相当不幸的回顾时机!
这并不意味着你不会得到你的具体问题的好答案,你只是不太可能得到“哦是的,我上周做了类似的事,注意这个问题”等。 ..
顺便说一句,你知道units of measure in F#吗?与技术相关的任何内容都非常有趣。