2014-10-23 7 views
1

Мне нравится писать некоторые математические функции в F # и использовать их с C#. Поскольку F # использует единицы измерения, это действительно здорово, чтобы проверить время компиляции. В C# у меня уже есть Length (indexer, который преобразуется в m, mm, km и т. Д.), Поэтому я хочу использовать его как параметр из C# с помощью функции F # и преобразовать его туда в float или более конкретный 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# не может быть напрямую применено к нему.

Что вы могли бы сделать, это создать пару хелперов преобразования F # такие функции, как:

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

и определить 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]) 
+0

Отлично, спасибо. Это решение. Теперь мне просто нужно подумать о решении, которое быстрее, чем использование объекта Length из C#. использование double/floats намного быстрее, но вы легко можете ошибаться, так как при использовании только плавающего в C# он просто двойной. Таким образом, порядок параметров и единица измерения могут быть неправильными. Любая идея или хорошая для другого вопроса? :) – KCT

+0

Не могу проголосовать. Но это работает. – KCT

+0

Трудно сказать. Возможно использование struct на стороне C# Длина { общедоступное значение плавающего; public unit uom/* И использовать перечисление как единицу измерения типа */ } – Petr

 Смежные вопросы

  • Нет связанных вопросов^_^