【问题标题】:haskell how to remove list usage from this code?haskell 如何从此代码中删除列表使用情况?
【发布时间】:2015-09-17 09:41:08
【问题描述】:

我正在努力学习 Haskell 并在二进制 IO 上苦苦挣扎。 此代码改编自 this answer 中给出的代码,用于我之前的一个问题。

我正在尝试从给定文件中读取大量 Word32 值和一些 Word8 值(元数据)。目前,我编写了一个程序,它只将文件中的Word32 值读取到未装箱的向量中。

此代码的问题在于它使用列表(通过replicateM)从文件中读取多个Word32 值。我想摆脱中间列表(出于效率原因),并希望使用 ByteString 从文件中直接读取向量中的数据。

这是我完整的工作代码。

import Data.Word
import qualified Data.ByteString.Lazy as BIN
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.Vector.Unboxed as V
import Control.Monad
import System.IO

main = do
  h_in  <- openFile "dat.bin" ReadMode
  v <- readInVector 10 h_in 
  putStrLn (show v)
  hClose h_in

readInVector n h_in = do
 bin1 <- BIN.hGet h_in (n*100)
 let ints1 = runGet (replicateM n getWord32le) bin1
 let v = V.fromList (ints1) :: V.Vector Word32
 return v

如何做到这一点?我希望有一个完整的工作代码作为答案,而不仅仅是指向 Haskell 网站上的文档,该网站有很多文本,几乎没有工作示例。

【问题讨论】:

  • 我想知道中间列表会因为融合而被优化出来。

标签: haskell vector io binary


【解决方案1】:

vector-package 有自己的 replicateM 向量函数,您可以使用它直接初始化向量,而无需构建中间列表。

readInVector n h_in = do
  bin1 <- BIN.hGet h_in (n*100)
  return $ runGet (V.replicateM n getWord32le) bin1

【讨论】:

    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2011-01-07
    • 2016-01-13
    相关资源
    最近更新 更多