Probably useful to include a "mkFixed" function example as well, to show how a Fixed can be constructed using the "optimal" data representation:<br><br><span style="font-family:times new roman,serif">-- | Make a fixed field.</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif">--</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif">-- Note that this type constructor function chooses the minimal type</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif">-- representation for the fixed value stored. Unsigned representations</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif">-- are preferred over signed.</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif">mkFixed :: String -> Int -> Integer -> Member</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif">mkFixed name len val</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> | len <= 0 = error $ "mkFixed " ++ name ++ ": length < 0"</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> | len < 8 && validUnsigned len val = Fixed name len False (fromIntegral val :: Word8)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> | len < 8 && validSigned len val = Fixed name len True (fromIntegral val :: Int8)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> | len < 16 && validUnsigned len val = Fixed name len False (fromIntegral val :: Word16)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> | len < 16 && validSigned len val = Fixed name len True (fromIntegral val :: Int16)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> | len < 32 && validUnsigned len val = Fixed name len False (fromIntegral val :: Word32)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> | len < 32 && validSigned len val = Fixed name len True (fromIntegral val :: Int32)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> | len < 64 && validUnsigned len val = Fixed name len False (fromIntegral val :: Word64)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> | len < 64 && validSigned len val = Fixed name len True (fromIntegral val :: Int64)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> | otherwise = error $ "mkFixed " ++ name ++ ": cannot represent this bit field"</span><br>
<br><br><div class="gmail_quote">On Thu, Aug 23, 2012 at 11:47 AM, Scott Michel <span dir="ltr"><<a href="mailto:scooter.phd@gmail.com" target="_blank">scooter.phd@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Here's an example (not a complete module) I was using to represent bit-oriented structures as they occur in certain space applications, notably GPS frames. "Fixed" allows for fixed-sized fields and lets the end user choose the integral type that's best for the structure.<br>
<br>At least it's not a parser or language example. :-)<br><br><br>-scooter<br><br><span style="font-family:times new roman,serif">-- | Member fields, etc., that comprise a 'BitStruct'</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif">data Member where</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> Field :: String -- Field name</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Bool -- Signed (True) or unsigned (False)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> ZeroPad :: String -- Field name</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> OnesPad :: String -- Field name</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> ArbPad :: String -- Field name</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> Reserved :: String -- Field name</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> Fixed :: (Integral x, Show x) =></span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> String -- Field name</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Int -- Field length</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Bool -- Signed (True) or unsigned (False)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> x -- Type of the fixed field's value</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> Variant :: (Integral x, Show x) =></span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> String -- Variant prefix name</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Maybe BitStruct -- Header before the tag</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> TagElement -- The tag element itself</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Maybe BitStruct -- Common elements after the tag</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Seq (x, BitStruct) -- Variant element tuples (value, structure)</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -- Mult-value variant: Use this when multiple variant tag values have the</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -- same structure:</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> MultiValueVariant :: (Integral x, Show x) =></span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> String -- Variant prefix name</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Maybe BitStruct -- Header before the tag</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> TagElement -- The tag element itself</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Maybe BitStruct -- Common elements after the tag</span><br style="font-family:times new roman,serif"><span style="font-family:times new roman,serif"> -> Seq ([x], BitStruct) -- Variant element tuples ([values], structure)</span><br style="font-family:times new roman,serif">
<span style="font-family:times new roman,serif"> -> Member</span><br style="font-family:times new roman,serif"><br>
</blockquote></div><br>