4

データを標準入力からダブルスとして読み取り、操作して、同様に書き込もうとしています。これまでに思いついたのは次のとおりです。

import qualified Data.ByteString.Lazy as B
import Data.Binary.IEEE754
import Data.Binary.Get

-- gives a list of doubles read from stdin
listOfFloat64le = do
  empty <- isEmpty
  if empty
     then return []
     else do v <- getFloat64le
             rest <- listOfFloat64le
             return (v : rest)


-- delay signal by one
delay us = 0 : us

-- feedback system, add delayed version of signal to signal
sys us = zipWith (+) us (delay us)

main = do
    input <- B.getContents
    let hs = sys $ runGet listOfFloat64le input
    print $ take 10 hs

アイデアは、データをプログラムにフィードし、それをフィードバック システムに渡してから stdout に書き込むことです。ただし、今は最初の 10 個の値を出力するだけです。

これは機能しますが、遅延評価しているようには見えません。つまり、すべての入力をメモリに読み込む必要があります。そう:

dd if=/dev/urandom bs=8 count=10 | runhaskell feedback.hs

うまくいきますが:

dd if=/dev/urandom | runhaskell feedback.hs

しない。私の推測では、listOfFloat64le物事が適切に機能しないのは機能です。sysでは、すべてをメモリに読み込まずに関数に渡す iterable を作成するにはどうすればよいでしょうか?

私はあまり経験豊富な Haskeller ではありません。

4

3 に答える 3

1

代わりに、ByteString を 8 バイト間隔で分割し、代わりにマッピングするという別のルートを取りました。

import qualified Data.ByteString.Lazy as L
import Data.Binary.IEEE754
import Data.Binary.Get

-- delay signal by one
delay us = 0 : us

-- feedback system, add delayed version of signal to signal
sys us = zipWith (+) us (delay us)

-- split ByteString into chunks of size n
chunk n xs = if (L.null xs)
        then []
        else y1 : chunk n y2
          where
            (y1, y2) = L.splitAt n xs


main = do
    input <- L.getContents

    let signal = map (runGet getFloat64le) (chunk 8 input)
    print $ take 10 (sys signal)

これは少なくとも機能しているようですが、パフォーマンスがどのようなものかはわかりません。

編集:代わりにrunGetStateを使用chunkするものに切り替えました:chunker

chunker :: Get a -> L.ByteString -> [a]
chunker f input = if (L.null input)
                     then []
                     else val : chunker f rest
                       where
                        (val, rest, _) = runGetState f input 0

そしてそれを次のように使用します:let signal = chunker getFloat64le input

于 2012-09-20T15:52:46.200 に答える
0

この質問を参照してください。Binary は昔使っていた時よりも厳しくなっているようです。

于 2012-09-20T14:45:06.610 に答える
0

pipesこれは、またはのようなものを簡単に使用できる標準の問題のようconduitsです。stdinソースとシンクとして作成しstdout、トランスを として適用できますconduit

于 2012-09-20T17:07:19.133 に答える