I am trying to to little endian conversion in haskell, so that I can turn a Word16 into two Word8 (for example 258 = 1*256 + 2, so result should be [2, 1]). I then pack the result into a ByteString.
I created the following code for this purpose:
import Data.Word
import Data.Bits
getByte b num = shift (relevantBits b num) (shiftNum b)
where bitMask b = sum $ map (2^) [8*b-8 .. 8*b-1]
relevantBits b num = num .&. bitMask b
shiftNum b = 8-8*b
encodeWord16 x = [getByte 1 x, getByte 2 x]
input :: Word16
input = 355
output :: [Word8]
output = encodeWord16 input
The function getByte
gets Byte number b
from a number num
. The function encodeWord16
uses this helper function to do the little endian conversion.
This however does not compile, I get the error:
Couldn't match expected type `Word8' with actual type `Word16'
In the first argument of `encodeWord16', namely `input'
In the expression: encodeWord16 input
In an equation for `output': output = encodeWord16 input
I (very unsystematically) tried to achieve the desired result by randomly distributing fromIntegral
expressions, but obviously my understanding of the haskell type system is not good enough to solve this problem. Is there a systematic way to approach this problem?
Basically I want the function encodeWord16
to have the type signature Word16 -> [Word8]
.
fromIntegral
can be used for conversion between various integral types.
fromIntegral :: (Num b, Integral a) => a -> b
encodeWord16 :: Word16 -> [Word8]
encodeWord16 x = map fromIntegral [getByte 1 x, getByte 2 x]
It'd be nicer though to have getByte
return Word8
-s:
getByte :: Int -> Word16 -> Word8
getByte b num = fromIntegral $ shift (relevantBits b num) (shiftNum b)
-- where ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With