gpt4 book ai didi

haskell - 在haskell中从stdin懒惰地读取和操作 float

转载 作者:行者123 更新时间:2023-12-01 05:28:49 25 4
gpt4 key购买 nike

我正在尝试从标准输入读取数据作为 double 数据,操作它们并写入它们。到目前为止我想出的是:

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

这个想法是将数据提供给程序,然后在将数据写入标准输出之前通过反馈系统。虽然现在它只打印前 10 个值。

这有效,但似乎不会懒惰地评估。即它必须将所有输入读入内存。
所以:
dd if=/dev/urandom bs=8 count=10 | runhaskell feedback.hs

会工作得很好,但是:
dd if=/dev/urandom | runhaskell feedback.hs

将不会。我猜是 listOfFloat64le使事情无法正常工作的功能。那么我如何创建一个迭代来传递到我的 sys功能而不必将所有内容读入内存?

我不是一个非常有经验的haskeller。

最佳答案

我采取了另一条路线,而是以 8 个字节的间隔拆分 ByteString 并对其进行映射:

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)

这似乎至少有效,但我不知道性能如何。

编辑:我从 chunk 切换过来的至 chunker它使用 runGetState 代替:
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

关于haskell - 在haskell中从stdin懒惰地读取和操作 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12514013/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com