2009-08-31 9 views
2

私はハスケルには新しく、実際には私が実際に実行しているいくつかのテストケースを試してみようとしています。私は、次を含むテキストファイル「foo.txtの」を持っていると言う:Haskell出力のリストに不思議な単語( "LPS")が表示される

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

あるとinvocated!ありがとう。 PS:ByteStringを使用すると、将来大量のファイルに使用されるようになります。

編集:私はまた、出力リストは、上記のようにグループ化される理由として困惑してい

GHCiの中に次の行が異なる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"]] 

答えて

8

あなたが見ているのは確かにコンストラクタです。ファイルを読むと、結果はもちろんバイトストリングのリストになりますが、浮動小数点のリストのリストが必要です。あなたは何ができるか

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

これは、バイト文字列(すなわち文字列に変換)を解凍します。 readは文字列をfloatに変換します。

ここでbytestringsを使用してもパフォーマンスに役立つかどうかは不明です。

2

これは、内部遅延バイト文字列表現型pre-1.4.4.3の表示(「LPS」のページを検索する)です。 LPSはコンストラクタです。

+0

私はそれが怠惰な評価に関連していたと思っていた。私は他のどのようにしかし私はリストを扱うことができますか? – jparanich

+0

私はそう思う - 私の理解は、あなたが(大抵の場合は)心配してはならないという別の内部表現であるということです。しかし、私はHaskell super-wellを知らない。ちょっと怪しいものが見えたら、これを忘れないでください。 –

2

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" 
+0

マイケルの情報ありがとうございました...マットボールは、LPS [45.4]の代わりに新しいリリースの「チャンク」になっていました。私はハスケルの魔法使いが私が理解できないほど上手く説明できると確信しています。 :) – jparanich

1

これは単なる怠け者バイト文字列コンストラクタです。これらの文字列をまだ解析していないので、基になる文字列が表示されます。遅延文字列はStringと同じではないので、 'Show'nのときには異なる印刷表現をしていることに注意してください。

1

LPSは古いLazy ByteString newtypeの古いコンストラクタでした。それ以来、明示的なデータ型に置き換えられているため、現在の動作は若干異なります。

「Lazy ByteStringで表示」を呼び出すと、あなたが与えたのとほぼ同じレイジー・バイトが生成されるコードが出力されます。ただし、ByteStringsを使用する通常のインポートでは、LPSまたはそれ以降のリビジョンのChunk/Emptyコンストラクタはエクスポートされません。それで、LPSコンストラクタが文字列として自分自身を表示する厳密なバイトストリングのチャンクのリストを囲んでいることを示しています。

怠惰延ByteStringショーインスタンスは複雑なデータ構造のため、他のほとんどのショーのインスタンスが行うのと同じことを行うなど、何か言うべき一方、私は疑問に思う:

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

かさえ:

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

は、結果コードがHaskellコードとして実際に解析可能であるため、{-# LANGUAGE OverloadedStrings #-}に依存しているようです。一方、文字列であるかのようにテストリングを印刷するのは本当に便利です。残念なことに、どちらのオプションも古いLPS構文よりも冗長ですが、現在のChunk "Foo" Emptyよりも簡潔です。結局のところ、ShowはReadによって可逆のままにする必要があります。そのため、おそらく変わっていることを気にしないでください。 ;)

あなたの問題については、[[Float]]ではなく、[[ByteString]]があなたの行にマッピングされています。あなたはそのByteStringを解凍してから、浮動小数点数を生成するために結果の文字列にreadを呼び出す必要があります。

関連する問題