on eecc006 help sign in
127 lines 4.0 kB history raw
1-- |
2-- Module : Streamly.Data.Array
3-- Copyright : (c) 2019 Composewell Technologies
4--
5-- License : BSD3
6-- Maintainer : streamly@composewell.com
7-- Stability : released
8-- Portability : GHC
9--
10-- This module provides immutable arrays in pinned memory (non GC memory)
11-- suitable for long lived data storage, random access and for interfacing with
12-- the operating system.
13--
14-- Arrays in this module are chunks of pinned memory that hold a sequence of
15-- 'Storable' values of a given type, they cannot store non-serializable data
16-- like functions. Once created an array cannot be modified. Pinned memory
17-- allows efficient buffering of long lived data without adding any impact to
18-- GC. One array is just one pointer visible to GC and it does not have to be
19-- copied across generations. Moreover, pinned memory allows communication
20-- with foreign consumers and producers (e.g. file or network IO) without
21-- copying the data.
22--
23-- = Programmer Notes
24--
25-- Array creation APIs require a 'MonadIO' Monad, except 'fromList' which is a
26-- pure API. To operate on streams in pure Monads like 'Identity' you can hoist
27-- it to IO monad as follows:
28--
29-- >>> import Data.Functor.Identity (Identity, runIdentity)
30-- >>> s = Stream.fromList [1..10] :: Stream Identity Int
31-- >>> s1 = Stream.hoist (return . runIdentity) s :: Stream IO Int
32-- >>> Stream.fold Array.write s1 :: IO (Array Int)
33-- [1,2,3,4,5,6,7,8,9,10]
34--
35-- 'unsafePerformIO' can be used to get a pure API from IO, as long as you know
36-- it is safe to do so:
37--
38-- >>> import System.IO.Unsafe (unsafePerformIO)
39-- >>> unsafePerformIO $ Stream.fold Array.write s1 :: Array Int
40-- [1,2,3,4,5,6,7,8,9,10]
41--
42-- To apply a transformation to an array use 'read' to unfold the array into a
43-- stream, apply a transformation on the stream and then use 'write' to fold it
44-- back to an array.
45--
46-- This module is designed to be imported qualified:
47--
48-- > import qualified Streamly.Data.Array as Array
49--
50-- For experimental APIs see "Streamly.Internal.Data.Array".
52module Streamly.Data.Array
53 (
54 -- * Types
55 Unbox (..)
56 , A.Array
58 -- * Construction
59 -- | When performance matters, the fastest way to generate an array is
60 -- 'writeN'. 'IsList' and 'IsString' instances can be
61 -- used to conveniently construct arrays from literal values.
62 -- 'OverloadedLists' extension or 'fromList' can be used to construct an
63 -- array from a list literal. Similarly, 'OverloadedStrings' extension or
64 -- 'fromList' can be used to construct an array from a string literal.
66 -- Pure List APIs
67 , A.fromListN
68 , A.fromList
70 -- Monadic APIs
71 , A.writeN -- drop new
72 , A.write -- full buffer
73 , writeLastN -- drop old (ring buffer)
75 -- * Conversion
76 -- 'GHC.Exts.toList' from "GHC.Exts" can be used to convert an array to a
77 -- list.
78 , A.toList
80 -- * Unfolds
81 , A.reader
82 , A.readerRev
84 -- * Casting
85 , cast
86 , asBytes
88 -- * Random Access
89 , A.length
90 -- , (!!)
91 , A.getIndex
93 -- * Deprecated
94 , read
95 , readRev
96 )
97where
99#include "inline.hs"
101import Streamly.Internal.Data.Unfold (Unfold)
102import Streamly.Internal.Data.Array as A hiding (read, readRev)
104import Streamly.Internal.Data.Unboxed (Unbox (..))
105import Prelude hiding (read)
107-- $setup
108-- >>> :m
109-- >>> :set -XFlexibleContexts
110-- >>> import Streamly.Internal.Data.Stream (Stream)
111-- >>> import Streamly.Data.Array (Array)
112-- >>> import qualified Streamly.Internal.Data.Stream as Stream
113-- >>> import qualified Streamly.Data.Array as Array
115-- | Same as 'reader'
116--
117{-# DEPRECATED read "Please use 'reader' instead" #-}
118{-# INLINE_NORMAL read #-}
119read :: (Monad m, Unbox a) => Unfold m (Array a) a
120read = reader
122-- | Same as 'readerRev'
123--
124{-# DEPRECATED readRev "Please use 'readerRev' instead" #-}
125{-# INLINE_NORMAL readRev #-}
126readRev :: (Monad m, Unbox a) => Unfold m (Array a) a
127readRev = readerRev