Search code examples
f#doubletype-alias

What is the difference between float32 vs single and float vs double, if any?


I have always considered the types float32 and single to be interchangeable, in that they are type aliases. The same for float and double. However, they appear to be declared in different assemblies Microsoft.FSharp.Core.Operators vs Microsoft.FSharp.Core.ExtraTopLevelOperators.

Also, the popup description is slightly different, where F# says on float32 and float that it can take a string and use Parse() on it.

However, trying that with single and double succeeds just fine too:

let x = single "12.3"
let y = double "13.4"

Is there any difference I should be aware of? I have always used them interchangeably, never really gave it another thought, until I saw the differences in the popups and in signatures:

// on hovering, or in FSI, this will have the slightly confusing signature:
// val x: a: double -> float
let x (a: double) = float a 

Solution

  • All of them are just aliases of the corresponding CLR types as you can see in prim-types-prelude.fs.

        type float32 = System.Single
        type float = System.Double
        type single = System.Single
        type double = System.Double
    

    As for the confusing signature consider this:

    type typA = A;;
    
    type typB = typA;;
    
    let f (x : typA) = (x : typB)
    //val f : x:typA -> typB
    

    Seems like F# prefers to use the aliases at the places you (or some other definition) used them.

    Finally the namespaces you are referring to (FSharp.Core.Operators) are referring not to the float type but the float function (float : 'T -> float). See prim-types.fs.