13

我一直在尝试使用Deedle F# Library编写 F# 批处理程序。它工作得很好。但是,我不确定以下 2 项任务的最佳设计:

  1. 将 F# 模块组合到现有的 ASP.net MVC/Web Api 系统中

  2. 创建 WPF 界面以用作各种 F# 模块的控制面板和可视依赖项控制器。

F# 模块正在执行的任务类型是处理时间序列并应用统计过程来导出新的时间序列。

我一直在尝试为现有模块创建一个类包装器,以便可以从 C# 代码中调用它。我从C# Deep Dive中读到,这是将 F# 模块公开给 C# 调用者的更好方法。

以下是一个示例包装器:

type TimeSeriesDataProcessor(fileName:string) = 
        let mutable _fileName = fileName
        let _rawInputData = loadCsvFile _fileName
        let _pivotedData = _rawInputData 
                       |> pivotRawData 
                       |> fillPivotedRawData
                       |> calculateExpandingZscore

    //read and write 
    member this.FileName
        with get () = _fileName
        and set (value) = _fileName <- value
    member this.RawInputData
        with get () = _rawInputData
    member this.PivotedData
        with get () = _pivotedData
    member this.rawInputDataCount
        with get () = _rawInputData.RowCount
    member this.pivotedDataCount
        with get () = _pivotedData.RowCount

以下是一个示例模块,大部分逻辑都应驻留在其中:

 module Common = 

    let loadCsvFile (fileName:string ) : Frame<int,string> =
        let inputData = Frame.ReadCsv(fileName)
        inputData


    let pivotRawData inputData:Frame<DateTime,string> = 
        let pivotedData = inputData |> Frame.pivotTable (fun k r -> r.GetAs<DateTime>("Date"))  
                              (fun k r -> r.GetAs<string>("Indicator")) 
                              (fun f -> let maxVal = f?Value |> Stats.max 
                                        match maxVal with
                                        | Some mv -> mv
                                        | _ -> Double.NaN
                              )
        pivotedData

    let fillPivotedRawData inputData:Frame<DateTime,string> = 
        let filledA = inputData?A |> Series.fillMissing Direction.Forward
        inputData?A<-filledA
        let filledB = inputData?B |> Series.fillMissing Direction.Forward
        inputData?B<-filledB

        inputData

    let calculateExpandingZscore inputData:Frame<DateTime,string> = 
        let expandingMeanColA = inputData?A |> Stats.expandingMean
        let expandingMeanColB = inputData?B |> Stats.expandingMean
        let expandingStdevColA = inputData?A |> Stats.expandingStdDev
        let expandingStdevColB = inputData?B |> Stats.expandingStdDev
        let expandingZscoreColA = (inputData?A - expandingMeanColA)/expandingStdevColA
        let expandingZscoreColB = (inputData?B - expandingMeanColB)/expandingStdevColB
        inputData?ExpdingMeanA <- expandingMeanColA
        inputData?ExpdingMeanB <- expandingMeanColB
        inputData?ExpdingStdevA <- expandingStdevColA
        inputData?ExpdingStdevB <- expandingStdevColB
        inputData?ExpdingZscoreA <- expandingZscoreColA
        inputData?ExpdingZscoreB <- expandingZscoreColB
        inputData

我一直在尝试使用 NUnit 作为 C# 调用者。我发现自己把大部分逻辑都放在了课堂do/let binding上。成员方法用作将结果传递给调用者。我不认为我的方法是正确的。

有人可以指出我正确的方向吗?(我尝试在 GitHub 上学习F# WPF 框架,但我还没有完成任务)

我知道 Deedle 也适用于 C#。但是,我真的很想使用 F#。示例代码实际上有太多副作用。

4

1 回答 1

4

坦率地说,您希望在 F# 中构建尽可能少的UI框架。正如您所指出的,当 F# 很棒时,它是一种很棒的语言。否则,不建议将它用于应用程序构建(一些铁杆功能语言爱好者可能会在这方面与我抗争,但我支持它,哈哈)。

我建议将所有工作单元F# 代码放入便携式 F# 库 ( https://msdn.microsoft.com/en-us/library/hh913781.aspx )。然后,引用该库并从中调用方法就像从 C# 或 VB 类和方法中调用类和方法一样简单。

您还可以使用一些模板(http://blogs.msdn.com/b/mcsuksoldev/archive/2011/06/05/f-class-library-template.aspx)。

于 2015-05-19T00:54:22.970 回答