Frage

I am learning F# and I am trying to use for the first time the concept of Unit of Measure. I have the following questions:

  • The last let (variable y in the getPosition function gives me the following error: "The unit of measure ''u ^ 2 m/second' does not match the unit of measure 'm'". Is there something wrong in the formula or it is my usage os unit of measure?

  • I am using the Unit of Measures defined in Microsoft.FSharp.Data.UnitSystems.SI. Is there a way to not specify the use a shorter version of the name? (e.g. UnitNames.second vs second).

  • I have to use the function cos and sin. These two functions expect a float, not a float. I use LanguagePrimitives.FloatWithMeasure to convert the float into a unit of measure. Is this the only way to do that? It makes the code very verbose.

Thanks!

open System
open Microsoft.FSharp.Data.UnitSystems.SI

module GeneralBallisticTrajectory = 
    [<Measure>] type radian

    let gravitationalAcceleration : float<UnitNames.metre/UnitNames.second^2> = 9.80665<UnitNames.metre/UnitNames.second^2>

    let getPosition (angle: float<radian>) (velocity: float<UnitNames.metre/UnitNames.second>)  (t: float<UnitNames.second>) =
        let x = velocity * t * (cos (float angle) |> LanguagePrimitives.FloatWithMeasure<UnitNames.metre/UnitNames.second>)
        let abc = (0.5 * gravitationalAcceleration) * t * t // returns float<UnitNames.metre>

        // The unit of measure 'UnitNames.metre' does not match the unit of measure 'UnitNames.metre ^ 2/UnitNames.second'
        let y = (velocity * t * (sin (float angle) |> LanguagePrimitives.FloatWithMeasure<UnitNames.metre/UnitNames.second>)) - abc

        (x, y)
War es hilfreich?

Lösung

You can use the shorter names by adding an

open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames

to your file.

As for the error, it's not clear why you are converting the result of the sin call to a measure type, since velocity * t has the same measure type (meter) as abc. The following appears to be what you want:

open System
open Microsoft.FSharp.Data.UnitSystems.SI
open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames

module GeneralBallisticTrajectory = 
    [<Measure>] type radian

    let gravitationalAcceleration : float<metre/second^2> = 9.80665<metre/second^2>

    let getPosition (angle: float<radian>) (velocity: float<metre/second>)  (t: float<second>) =
        let x = velocity * t * (cos (float angle) |> LanguagePrimitives.FloatWithMeasure<metre/second>)
        let abc = (0.5 * gravitationalAcceleration) * t * t // returns float<UnitNames.metre>

        let y = (velocity * t * (sin (float angle))) - abc
        (x, y)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top