神秘的单词(“LPS”)出现在Haskell输出列表中
我是Haskell的新手,尝试处理现实世界中经常遇到的一些测试用例。假设我有文本文件“foo.txt”,其中包含以下内容:神秘的单词(“LPS”)出现在Haskell输出列表中,haskell,bytestring,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.L
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)
感谢您的帮助!谢谢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"]]
这是内部lazy bytestring表示类型的指示(在页面中搜索“LPS”)。LPS是一个构造器。你看到的确实是一个构造器。当您读取文件时,结果当然是一个bytestring列表,但您需要的是一个float列表 你能做的是:
readDatafile :: BStr.ByteString -> [[Float]]
readDatafile = (map ((map (read . BStr.unpack)) . BStr.words)) . BStr.lines
这将解压Bytestring(即将其转换为字符串)。读取将字符串转换为浮点
但不确定在这里使用ByTestring是否有助于提高性能 readDatafile返回[[ByteString]],您看到的是您读取的所有字符的“压缩”表示
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"
这只是懒惰的bytestring构造函数。您还没有将这些字符串解析为整数,因此您将看到底层字符串。请注意,lazy-ByteString与String不同,因此当'Show'n.LPS是旧lazy-ByteString新类型的旧构造函数时,它们具有不同的打印表示形式。此后,它被显式数据类型取代,因此当前的行为略有不同 当您在lazybytestring上调用Show时,它会打印出生成与您提供的lazybytestring大致相同的代码。但是,通常用于使用ByTestRing的导入不会导出LPS——或者在以后的版本中,不会导出Chunk/Empty构造函数。因此,它显示了LPS构造函数,它围绕着一系列严格的bytestring块,这些块将自己打印为字符串 另一方面,我想知道lazy ByteString Show实例是否应该做与大多数其他复杂数据结构的Show实例相同的事情,比如:
fromChunks ["foo","bar","baz"]
甚至:
fromChunks [pack "foo",pack "bar", pack "baz"]
因为前者似乎依赖于{-#语言重载字符串#-}
,因此生成的代码片段可以真正解析为Haskell代码。另一方面,像字符串一样打印bytestring非常方便。唉,这两个选项都比旧的LPS语法更冗长,但它们比当前的块“Foo”Empty更简洁。最后,Show只需要通过Read保持可逆性,所以最好不要随意更改内容,以免随机破坏大量序列化数据
至于你的问题,你得到的是一个
[[ByteString]]
而不是[[Float]]]]
,通过在你的行上映射单词。你需要解包ByteString,然后调用结果字符串上的read
,以生成你的浮点数。是的,我开始认为它与延迟计算有关。然而,我可以像对待其他人一样对待这份清单?我想是的-我的理解是,这只是另一种你不应该(大部分情况下)担心的内部表现。不过,我对哈斯克尔并不十分了解。如果你开始看到不可靠的东西,不要忘记这一点。谢谢你的信息,迈克尔。。。我注意到在Matt Ball的链接中,它现在在新版本中是一个“块”,而不是像我一样的“LPS[45.4]”。我相信哈斯凯尔巫师有一个很好的解释,我太新鲜了,无法理解
fromChunks [pack "foo",pack "bar", pack "baz"]