Converting bytes to Int64s/Floats/Doubles in Haskell

bit, haskell

Solution

If you aren't aware, `fromIntegral` converts integrals perfectly well. Also, the binary package and associated data-binary-ieee754 package are very applicable to your problem.

λ> :set -XOverloadedStrings
λ> import           Data.Binary.Get       (runGet)
λ> import qualified Data.Binary.IEEE754   as I
λ> runGet I.getFloat32le "\STX\SOH\SOH\SOH"
2.369428e-38
λ> runGet I.getFloat32le "\STX\SOH\SOH\SOHtrailing characters are ignored"
2.369428e-38
λ> runGet I.getFloat32le "\STX\SOH\SOH" -- remember to use `catch`:
*** Exception: Data.Binary.Get.runGet at position 0: not enough bytes
CallStack (from HasCallStack):
  error, called at libraries/binary/src/Data/Binary/Get.hs:351:5 in binary-0.8.5.1:Data.Binary.Get

Problem

I'm trying to parse a binary file format in Haskell (Apple's binary property list format), and one of the things required by the format is to treat sequences of bytes as either (a) unsigned 1-, 2-, or 4-byte integers; (b) signed 8-byte integers; (c) 32-bit `float`s; and (d) 64-bit `double`s. Converting sequences of bytes to unsigned integers is easy, and even dealing with signed integers wouldn't be terrible. But for signed integers, and especially for `Float`s and `Double`s, I don't really want to implement the logic myself. I've been able to find functions `int2Float# :: Int# -> Float#` and `int2Double# :: Int# -> Double#` in GHC.Prim, but these don't seem ideal (I don't particularly want to be working with unboxed types). My hope is that there's some way to cast from either a `[Word8]` or `Word32`s/`Word64`s. Are there any functions of type `Word32 -> Float`, `Word64 -> Double`, `Word64 -> Int64`, or similar?

Original source

Related problems