2014-10-23 1 views
1

F #에서 일부 수학 함수를 작성하고 C#에서 사용하고 싶습니다. F #은 측정 단위를 사용하므로 컴파일 시간을 확인하는 것이 좋습니다. C#에서는 이미 길이 (m, mm, km 등으로 변환되는 인덱서) 클래스가 있으므로 C#에서 매개 변수로 F # 함수를 사용하여 부동 소수점 또는 더 구체적인 float로 변환하려고합니다.매개 변수가있는 f # 함수 호출 및 측정 단위에 캐스트

필자는 두 개의 매개 변수를 사용하여 함수 호출에 어려움을 겪고 있습니다. 나는 그것이 커링과 관련이 있다고 생각합니다.

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) 

답변

1

3. 함수 정의가 유효한 F # 함수 정의가 아닙니다. 'FreshConcreteLoad()'다른 함수를 호출해야한다면 함수 호출에서 타입 주석을 사용할 수 없습니다. 아마도 함수 매개 변수를 측정 단위로 형변환하려고했으나 F # 단위가 C#에 존재하지 않아 C# 값을 직접 형변환 할 수 없기 때문에이 형 변환을 수행 할 수 없습니다.

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

또는 전화로 직접 변환을 수행 : 3 위 기능을

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

및 정의 : 당신이 무엇을 할 수 있는지

처럼 F 번호 기능을 변환 도우미의 몇 가지를 만드는 것입니다

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

감사합니다. 그것이 해결책입니다. 이제는 C#의 Length 개체를 사용하는 것보다 더 빠른 솔루션에 대해 생각해야합니다. double/floats를 사용하는 것이 훨씬 빠르지 만, 단지 float을 사용할 때와 같이 실수로 실수를 할 수 있습니다. 은 C#에서 두 배입니다. 따라서 매개 변수 순서와 측정 단위가 잘못 될 수 있습니다. 다른 질문에 대한 아이디어 나 도움이 필요하십니까? :) – KCT

+0

투표 할 수 없습니다. 그러나 그것은 효과적이다. – KCT

+0

말하기 어렵습니다. 아마도 C# 쪽에서 구조체를 사용하십시오 길이 { public float value; 공공 단위 uom/* 측정 단위 유형으로 enum을 사용 */ } – Petr

관련 문제