{-# LANGUAGE PackageImports, FlexibleContexts #-} -- | Read and write vectors as ASCII text files. -- -- The file format is like: -- -- @ -- VECTOR -- header -- 100 -- length of vector -- 1.23 1.56 1.23 ... -- data, separated by whitespace -- .... -- @ module Data.Array.Repa.IO.Vector ( readVectorFromTextFile , writeVectorToTextFile) where import Data.Array.Repa as A import Data.Array.Repa.Repr.Unboxed as A import Data.Array.Repa.IO.Internals.Text import Data.List as L import Prelude as P import System.IO import Control.Monad import Data.Char -- | Read a vector from a text file. -- -- * WARNING: This is implemented fairly naively, just using `Strings` -- under the covers. It will be slow for large data files. -- -- * It also doesn't do graceful error handling. -- If the file has the wrong format you'll get a confusing `error`. -- readVectorFromTextFile :: (Num e, Read e, Unbox e) => FilePath -> IO (Array U DIM1 e) readVectorFromTextFile fileName = do handle <- openFile fileName ReadMode "VECTOR" <- hGetLine handle [len] <- liftM (P.map readInt . words) $ hGetLine handle str <- hGetContents handle let vals = readValues str let dims = Z :. len return $ fromListUnboxed dims vals readInt :: String -> Int readInt str | and $ P.map isDigit str = read str | otherwise = error "Data.Array.Repa.IO.Vector.readVectorFromTextFile parse error when reading data" -- | Write a vector as a text file. writeVectorToTextFile :: (Show e, Source r e) => Array r DIM1 e -> FilePath -> IO () writeVectorToTextFile arr fileName = do file <- openFile fileName WriteMode hPutStrLn file "VECTOR" let Z :. len = extent arr hPutStrLn file $ show len hWriteValues file $ toList arr hClose file hFlush file