Categories
askquestion

F# Units of measure, problems with genericity

F# Units of measure, problems with genericity

Ask Question

Asked
11 years ago

Active
11 years ago

Viewed
551 times

.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{
margin-bottom:0;
}

3

(I’m still banging on with units of measure in F#)

I’m having a problem making ‘generic’ functions which take ‘typed’ floats.

The following mockup class is intended to keep tabs on a cumulative error in position, based on a factor ‘c’. The compiler doesn’t like me saying 0.<‘a> in the body of the type (“Unexpected type parameter in unit-of-measure literal”).

///Corrects cumulative error in position based on s and c
type Corrector(s_init:float<‘a>) =
let deltaS ds c = sin (ds / c) //incremental error function

//mutable values
let mutable nominal_s = s_init
let mutable error_s = 0.<‘a> //<– COMPILER NO LIKE

///Set new start pos and reset error to zero
member sc.Reset(s) =
nominal_s <- s
error_s <- 0.<‘a> //<– COMPILER NO LIKE

///Pass in new pos and c to corrector, returns corrected s and current error
member sc.Next(s:float<‘a>, c:float<‘a>) =
let ds = s – nominal_s //distance since last request
nominal_s <- s //update nominal s
error_s <- error_s + (deltaS ds c) //calculate cumulative error
(nominal_s + error_s, error_s) //pass back tuple

Another related question, I believe, still to do with ‘generic’ functions.

In the following code, what I am trying to do is make a function which will take a #seq of any type of floats and apply it to a function which only accepts ‘vanilla’ floats. The third line gives a ‘Value Restriction’ error, and I can’t see any way out. (Removing the # solves the problem, but I’d like to avoid having to write the same thing for lists, seqs, arrays etc.)

[<Measure>] type km //define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes ‘vanilla’ floats
let MapSeqToNonUnitFunction (x:#seq<float<‘a>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
MapSeqToNonUnitFunction testList

f# units-of-measurement

share|improve this question

edited May 23 ’17 at 12:19

Community♦

111 silver badge

asked Jan 20 ’09 at 10:38

BenjolBenjol

52.9k4343 gold badges171171 silver badges240240 bronze badges

add a comment
 | 

2 Answers
2

active

oldest

votes

1

You can change the first ‘compiler no like’ to

let mutable error_s : float<‘a> = 0.0<_>

and the compiler seems to like that.

As for the second question, I am not seeing the same error as you, and this

[<Measure>] type km
//define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes ‘vanilla’ floats
let MapSeqToNonUnitFunction (x:seq<float<_>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
let testList2 = testList :> seq<_>
let result = MapSeqToNonUnitFunction testList2
printfn “%A” result

compiles for me (though the upcast to seq<_> is a little annoying, I am not sure if there is an easy way to get rid of it or not).

Aside, I think convention is to name units parameters ‘u, ‘v, … rather than ‘a, ‘b, …

share|improve this answer

answered Jan 20 ’09 at 20:41

BrianBrian

110k1515 gold badges216216 silver badges285285 bronze badges

I’ll let this stand as the answer, as it answered two thirds of my question. And thanks for the reminder about naming convention. I’d have liked to avoid the upcast too.

– Benjol
Feb 16 ’09 at 21:05

add a comment
 | 

0

Units of measure cannot be used as type parameters. This is because the are erased by the compiler during compilation. This question is quite similar:
F# Units of measure – ‘lifting’ values to float<something>

share|improve this answer

edited May 23 ’17 at 12:19

Community♦

111 silver badge

answered Jan 20 ’09 at 11:33

RobertRobert

5,98622 gold badges2828 silver badges3838 bronze badges

I asked that one too, I must be a bit slow on the uptake! I guess this means I have two options – either I force to a given unit, or I pass in my zero value?

– Benjol
Jan 20 ’09 at 11:54

I’m not sure I understand what you mean by cannot be used as type parameters, ‘cos this works: let fn (a:float<‘a>) (b:float<‘a>) = a * b

– Benjol
Jan 20 ’09 at 12:03

add a comment
 | 

Your Answer

Thanks for contributing an answer to Stack Overflow!Please be sure to answer the question. Provide details and share your research!But avoid …Asking for help, clarification, or responding to other answers.Making statements based on opinion; back them up with references or personal experience.To learn more, see our tips on writing great answers.

Draft saved
Draft discarded

Sign up or log in

Sign up using Google

Sign up using Facebook

Sign up using Email and Password

Submit

Post as a guest

Name

Email
Required, but never shown

Post Your Answer

Discard

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you’re looking for? Browse other questions tagged f# units-of-measurement or ask your own question.

Blog

When laziness is efficient: Make the most of your command line

Ben Popper is the worst coder in the world: Something awry with my array

Featured on Meta

TLS 1.0 and TLS 1.1 removal for Stack Exchange services

Did Stack Exchange cut the number of negative comments nearly in half between…

An account of my meeting with the Stack Overflow management team

Visit chat

Linked

3

How to generically remove F# Units of measure

3

F# Units of measure – ‘lifting’ values to float<something>

3

F# compiler error FS0030, problems with the Value Restriction

2

Reusing units of measure across different types

3

F# Ununit – reunit inside a function

0

F# Units of measure, problems with genericity 2

Related

3How to generically remove F# Units of measure0F# Units of measure, problems with genericity 22Units of Measure – reuse method with different units passed in1F# type extension with units of measure type conversion resulting in strange error109Best approach for designing F# libraries for use from both F# and C#1Units of measures and statistical models with F#9Fractional power of units of measures in F#42Can F# units of measure be implemented in OCaml?2Bit Shifting with units of measure in F#2F# creating generic function with generic units of measure

Hot Network Questions

How to deal with a temporary manager who isn’t competent?

How to convert graphical images to ASCII art?

How can I login as any user without having to grant access?

What are the least powerful airplanes that ever flew?

Why are no recent small aircraft designed to be “characteristically incapable of spinning” as the Ercoupe was?

Why can’t Ditto copy eyes properly?

Is there a hot key that automatically makes a group of vertices into a circle?

Resigning a couple of months before an event : is it abusive resignation?

Find duplicated text for tasks in MS Project

Crooked (Not Parallel with Wall) Electrical Receptacle

Does the Clone Bay regenerate your crew’s health when you “wait” at The Last Stand?

Why are there waves in seas towards shore – even in night?

Would allowing the Rogue sub-class (Assassin) to benefit from Supreme Sneak be unbalanced?

How do helicopters avoid detection from enemies by using IR suppressors?

I like my new job but I’m always late and I skip work often. How to avoid this?

Player has trouble imagining the ingame situation

Busiest domestic-only airport?

Providing the spymaster with cues for clues in Codenames

Why do modern aircraft tend to have angular tails?

Using two tires on one wheel to prevent punctures?

P = NP clarification

How can I generate a sine wave with time varying frequency that is continuous, in C?

What is the Dorfman method in chess?

How do I pick a location to play a tabletop RPG?

more hot questions

Question feed

Subscribe to RSS

Question feed
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

lang-ml

Leave a Reply

Your email address will not be published. Required fields are marked *