Hello,
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:
https://docs.google.com/open?id=0B8oSBVnQGD_wNGEtT1JRSnpPUms.
Please respond with any comments, concerns, or ideas.
Discussion period: 3 weeks.
Thanks,
Jeff