神秘词(“LPS”)出现在Haskell输出列表中

时间:2009-08-31 20:03:02

标签: haskell bytestring

我是Haskell的新手并试图摆弄一些我经常在现实世界中遇到的测试用例。假设我有文本文件“foo.txt”,其中包含以下内容:

45.4 34.3 377.8
33.2 98.4 456.7
99.1 44.2 395.3

我正在尝试生成输出

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

我的代码在下面,但我在输出中得到一些虚假的“LPS”......不确定它代表什么。

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)

当使用 testFunc“foo.txt”调用时输出为

[[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"]]]

任何帮助表示赞赏!谢谢。 PS:使用ByteString,因为将来会在大量文件中使用它。

编辑:

我也很困惑为什么输出列表如上所述(每个数字都绑定在[]中),当在ghci中时,下面的行给出了不同的排列。

*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"]]

5 个答案:

答案 0 :(得分:8)

你所看到的确实是一个构造函数。当您读取文件时,结果当然是Bytestrings列表的列表,但您想要的是Floats列表的列表。

你能做什么:

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

这将解包Bytestring(即将其转换为字符串)。 read将字符串转换为float。

不确定在这里使用字节串是否有助于提高性能。

答案 1 :(得分:2)

这是内部惰性字节串表示类型pre-1.4.4.3的指示(在页面中搜索“LPS”)。 LPS是一个构造函数。

答案 2 :(得分:2)

readDatafile返回一个[[ByteString]],你看到的是你读过的所有字符的'packed'表示。

readDatafile = map (map Bstr.unpack . bStr.words) . Bstr.lines

这是一个展示问题的ghci运行示例。我的输出与你的不同,因为我使用的是GHC 6.10.4:

*Data.ByteString.Lazy.Char8> let myString = "45.4"
*Data.ByteString.Lazy.Char8> let myByteString = pack "45.4"
*Data.ByteString.Lazy.Char8> :t myString
myString :: [Char]
*Data.ByteString.Lazy.Char8> :t myByteString
myByteString :: ByteString
*Data.ByteString.Lazy.Char8> myString
"45.4"
*Data.ByteString.Lazy.Char8> myByteString
Chunk "45.4" Empty
*Data.ByteString.Lazy.Char8> unpack myByteString
"45.4"

答案 3 :(得分:1)

这只是lazy bytestring构造函数。您还没有将这些字符串解析为整数,因此您将看到基础字符串。请注意,延迟字节串与String不同,因此在“Show'n”时它们具有不同的打印表示。

答案 4 :(得分:1)

LPS是旧的Lazy ByteString newtype的旧构造函数。它已被替换为显式数据类型,因此当前行为略有不同。

当您在Lazy ByteString上调用Show时,它会打印出生成与您提供的lazy字符串大致相同的代码。但是,使用ByteStrings的常规导入不会导出LPS - 或者在以后的版本中导出Chunk / Empty构造函数。所以它用LPS构造函数显示它包含一个严格的字节串块的列表,它们将自己打印为字符串。

另一方面,我想知道懒惰的ByteString Show实例是否应该执行与复杂数据结构的大多数其他显示实例相同的事情,并说出如下内容:

fromChunks ["foo","bar","baz"]

甚至:

fromChunks [pack "foo",pack "bar", pack "baz"]

因为前者似乎依赖于{-# LANGUAGE OverloadedStrings #-},因此生成的代码片段可以作为Haskell代码真正解析。另一方面,打印字节串就好像它们是字符串一样非常方便。唉,这两个选项都比旧的LPS语法更冗长,但它们比当前的Chunk“Foo”Empty更简洁。最后,Show只需要通过Read保持可逆性,因此最好不要改变事物,以免随机破坏大量的序列化数据。 ;)

至于你的问题,你通过在你的线上映射单词来获得[[ByteString]]而不是[[Float]]。您需要解压缩ByteString,然后在结果字符串上调用read以生成浮点数。