Search code examples
haskellbytestring

Mysterious word ("LPS") appears in a list of Haskell output


I am new to Haskell and trying to fiddle with some test cases I usually run into in the real world. Say I have the text file "foo.txt" which contains the following:

45.4 34.3 377.8
33.2 98.4 456.7
99.1 44.2 395.3

I am trying to produce the output

[[45.4,34.3,377.8],[33.2,98.4,456.7],[99.1,44.2,395.3]]

My code is below, but I'm getting some bogus "LPS" in the output... not sure what it represents.

import qualified Data.ByteString.Lazy.Char8 as BStr
import qualified Data.Map as Map

readDatafile = (map (BStr.words) . BStr.lines)

testFunc path = do
    contents <- BStr.readFile path
    print (readDatafile contents)

When invocated with testFunc "foo.txt" the output is

[[LPS ["45.4"],LPS ["34.3"],LPS ["377.8"]],[LPS ["33.2"],LPS ["98.4"],LPS ["456.7"]],[LPS ["99.1"],LPS ["44.2"],LPS ["395.3"]]]

Any help is appreciated! Thanks. PS: Using ByteString as this will be used on massive files in the future.

EDIT:

I am also puzzled as to why the output list is grouped as above (with each number bound in []), when in ghci the below line gives a different arrangment.

*Main> (map words . lines) "45.4 34.3 377.8\n33.2 98.4 456.7\n99.1 44.2 395.3"
[["45.4","34.3","377.8"],["33.2","98.4","456.7"],["99.1","44.2","395.3"]]

Solution

  • What you're seeing is indeed a constructor. When you read the file, the result is of course a list of lists of Bytestrings, but what you want is a list of lists of Floats.

    What you could do :

    readDatafile :: BStr.ByteString -> [[Float]]
    readDatafile = (map ((map (read .  BStr.unpack)) . BStr.words)) . BStr.lines
    

    This unpacks the Bytestring (i.e. converts it to a string). The read converts the string to a float.

    Not sure if using bytestrings here even helps your performance though.