Hide this comment

See

[link:stackoverflow.com]

(You need inline to make e.g. '+' work across multiple types, and then can use e.g. GenericZero for generic numeric literals.)

By on 4/4/2010 10:47 AM ()Reply
Hide this comment

Thanks,
That's what I was looking for.
However I don't understand how to use it for values other then 0 or 1.

module NumericLiteralG = begin
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
end

let a:int = 0G
let b:float = 0G
let c:float = 2G

Do you know how to define FromInt32 and the others?

Thanks,
Glen

By on 4/4/2010 8:31 PM ()Reply
Hide this comment

What are you trying to do?

By on 4/4/2010 9:08 PM ()Reply
Hide this comment

I would like to be able to have the following work:

let a:float = 2G
let b:int = 2G
let c:decimal = 2G

a should be 2.0 float = 2.0f
b should be 2 int = 2
c should be 3 decimal = 2M

an application that might use this is
let add2 = (+) 2

add2 2 -> works
add2 2.0 -> fails
add2 2M -> fails

I would like
let a:float = add2 2.0, for example to work

Thanks,
Glen

By on 4/5/2010 7:54 PM ()Reply
Hide this comment

Here's one approach, though it's not particularly efficient:

1
2
3
4
5
6
7
8
9
10
11
12
module NumericLiteralG =
  let inline FromZero() = LanguagePrimitives.GenericZero
  let inline FromOne() = LanguagePrimitives.GenericOne
  let inline FromInt32(n) = 
    let rec loop = function
    | 0 -> FromZero()
    | 1 -> FromOne()
    | k -> 
        let half = loop (k/2)
        let whole = half + half
        if k % 2 = 0 then whole else whole + FromOne()
    loop n

Although this is kind of neat, I would think that instances where generic literals are appropriate are fairly limited in practice, since you would typically want slightly different logic when handling different data types in an algorithm (e.g., you would probably want to use a tolerance when comparing float values for equality, but this is unnecessary for ints, etc.)

By on 4/6/2010 6:49 AM ()Reply
Hide this comment

would <`a>.Parse(2.ToString()) be faster in this case ? That may generate runtime exception though because parse may fail.

This subject has been discussed in another thread.

[link:cs.hubfs.net]

I think fromIntegral should be a part of the numeric types in F#.

By on 4/6/2010 9:23 AM ()Reply
Hide this comment

I think that my approach is likely to be significantly faster than converting an int to a string and then parsing that into the desired type, though you could profile to be sure. Using a static Parse method would also result in code that works on a different set of types (e.g. "5G : System.DateTime" would compile and "5G : complex" wouldn't when relying on a static Parse method; the opposite is true of my code).

I agree in principle that something like "fromIntegral" would be quite nice. However, keep in mind that there's not really a clear definition of "numeric types in F#", particularly given the emphasis on .NET interop. I think that considering static extension methods when performing static member constraint resolution might provide a clean path forward, but I'm sure I haven't considered all of the lurking corner cases. It would be especially great if a technique like that could do away with the need for ad hoc methods with compiler magic (e.g. LanguagePrimitives.DivideByInt).

By on 4/6/2010 10:32 AM ()Reply
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper

Logging in...