What is the optimal way of representing a floating point number in a range from 0 to 1?

floating-point, haskell, numbers, types

Solution

A Serious Suggestions

You could use a newtype wrapper (and smart constructor) around a word of the proper bit size:

newtype SmallFrac = SF Word64

-- Example conversion (You'd actually want to make
-- instances of common classes, I assume)
sfToDouble :: SmallFrac -> Double
sfToDouble (SF x) = fromIntegral x / fromIntegral (maxBound `asTypeOf` x)

instance Show SmallFrac where
    show = show . sfToDouble

Implementing multiplication and division might be more costly than you would like, but at least addition is easy (modulo protecting against over/underflow) and you claim to not need any operations so even better.

A Less Useful Suggestion

If all you need is a symbol representing a value exists between one and zero then take dave4420's suggestion and just have a unit type:

newtype SmallFrac = SF ()

There are no operations for this type, not even conversion to/from other types of interest such as `Double`, but this meets the request as stated.

Problem

I'm looking for a numeric type able to represent, say, a value `0.213123` or `0.0`, or `1.0`, but refusing the out of range values, such as `-0.2123` and `1.2312`. Does there exist a specific type fitting that purpose, and what is the optimal general approach to restricting numbers to a specific range? Of course, the first answer coming to mind is: just use `Double`, but getting spoiled by Haskell's type system I've gotten used to maximally securing the program on a type level.

Original source

Related problems