Proposal: add conversion functions to Data.Fixed.

Jeff Shaw shawjef3 at
Wed Nov 28 18:07:45 CET 2012

In my work I've run into an annoyance: Data.Fixed.Fixed does not have a 
Binary instance in the binary package. This is a result of the 
representation of Fixed being hidden, which is understandable. The 
problem is that when I want to create a Binary instance for Fixed, I 
need to use unsafeCoerce, which is nasty, and there's no built-in way to 
safely deal with problems involving the desired resolution being 
different when deseralizing.

Today I played around with the source to Fixed, and came up with this 
proposed solution:

- | Get a Fixed value's Integer representation and resolution.
fromFixed :: (HasResolution a) => Fixed a -> (Integer,Integer)
fromFixed f@(MkFixed i) = (i, resolution f)

-- | Given an Integer representation and resolution of a Fixed value,
-- create a new Fixed value with an arbitrary resolution.
toFixed :: (HasResolution a) => (Integer,Integer) -> Fixed a
toFixed (i,r0) = withResolution (\r1 -> MkFixed $ (i * r1) `div` r0)

These functions lead to this useful derivation: convertFixed = toFixed . 
fromFixed, which leads to the possibility of having many possibly useful 
utility functions, such as toUni, fromUni, toDeci, fromDeci, etc.

 From fromFixed and toFixed, a safe instance for Binary (Fixed a) can be 
built (I haven't tested this, but it looks right):

instance (HasResolution a) => Binary (Fixed a) where
   put = put . fromFixed
   get = get >>= return . toFixed

Here is my patch:

Please respond with any comments, concerns, or ideas.

Discussion period: 3 weeks.


More information about the Libraries mailing list