簡體   English   中英

帶參數的f#函數調用並轉換為度量單位

[英]f# function call with parameters and cast to units of measure

我喜歡用F#編寫一些數學函數並從C#中使用它們。 由於F#使用度量單位,因此進行編譯時間檢查確實很棒。 在C#中,我已經有了一個Length(可將其轉換為m,mm,km等的索引器)類,因此我想使用F#函數將其用作C#中的參數並將其轉換為float或更特定的float。

因為我有兩個參數,所以我很難調用這些函數。 我想這與欺騙有關。

module Static
open Xunit
open Units.Contract // here is my Length class defined in C#

[<Measure>] type m
[<Measure>] type slabThickness = m
[<Measure>] type kN
[<Measure>] type freshConcreteDensity = kN/m^3
[<Measure>] type freshConcreteLoad = kN/m^2


let FreshConcreteLoad(slabThickness:float<m>, freshConcreteDensity:float<kN/m^3>) = slabThickness * freshConcreteDensity // 1. works

let FreshConcreteLoadL(slabThickness:Length, freshConcreteDensity:Length) = slabThickness.[Length.Units.m] *  freshConcreteDensity.[Length.Units.m] //2. works

let FreshConcreteLoadLUseMeasure(slabThickness:Length, freshConcreteDensity:Length) =  FreshConcreteLoad (slabThickness.[Length.Units.m]:float<m> freshConcreteDensity.[Length.Units.m]:float<kN/m^3>)  //3. here I struggel

// Related to 1. and works
[<Fact>]
let FreshConcreteLoad_Test() = 
    let thickness =  0.2<slabThickness>
    let density =  25.0<freshConcreteDensity> 
    let load:float<freshConcreteLoad> = FreshConcreteLoad(thickness,density)  
    Assert.Equal(load, 5.0<kN/m^2>) 

// Related to 2. and works
[<Fact>]
let FreshConcreteLoadL_Test() = 
    let thickness = new Length(0.2)
    let density = new Length(25.0) // dont care that this is now also a length, just for testing. in real live here would be a class for kN
    let load:float = FreshConcreteLoadL(thickness,density)  
    Assert.Equal(load, 5.0)

// Related to 3. and I struggle with the function call
[<Fact>]
let FreshConcreteLoadLUseMeasure_Test() = 
    let thickness = new Length(0.2)
    let density = new Length(25.0) // dont care that this is now also a length, just for testing. in real live here would be a class for kN
    let load:float = FreshConcreteLoadLUseMeasure(thickness,density)  
    Assert.Equal(load, 5.0)

您的3.函數定義不是有效的F#函數定義。 如果需要調用另一個函數“ FreshConcreteLoad()”,則不能在函數調用中使用類型注釋。 也許您想將函數參數轉換為度量單位,但由於C#中不存在F#度量單位,因此無法執行此轉換,因此無法將C#值直接轉換為它。

您可以做的是創建幾個幫助程序來轉換F#函數,例如:

let convToLength (inp: float) = inp * 1.0<m>
let convToDensity (inp: float) = inp * 1.0<kN/m^3>

並將第三個函數定義為:

let FreshConcreteLoadLUseMeasure(slabThickness:Length, freshConcreteDensity:Length) =  FreshConcreteLoad (convToLength slabThickness.[Length.Units.m], convToDensity freshConcreteDensity.[Length.Units.m]) 

或直接在通話中執行轉換:

let FreshConcreteLoadLUseMeasure(slabThickness:Length, freshConcreteDensity:Length) =  FreshConcreteLoad (1.0<m> * slabThickness.[Length.Units.m], 1.0<kN/m^3> * freshConcreteDensity.[Length.Units.m])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM