2-- Module : Streamly.Data.Array
3-- Copyright : (c) 2019 Composewell Technologies
6-- Maintainer : streamly@composewell.com
10-- This module provides APIs to create and use unboxed immutable arrays. Once
11-- created, their contents cannot be modified. Only types that are unboxable
12-- via the 'Unbox' type class can be stored in these arrays. Note that the
13-- array memory grows automatically when creating a new array, therefore, an
14-- array can be created from a variable length stream.
16-- See "Streamly.Internal.Data.Array" for more, unreleased APIs. See
17-- "Streamly.Data.Array.Generic" for arrays that work for boxed types i.e. not
18-- requiring the 'Unbox' constraint. See "Streamly.Data.MutArray" for arrays
19-- that can be mutated in-place.
23-- Convert array to stream, and fold the stream:
25-- >>> fold f arr = Stream.unfold Array.reader arr & Stream.fold f
26-- >>> fold Fold.sum (Array.fromList [1,2,3::Int])
29-- = Transforming Arrays
31-- Convert array to stream, transform, and fold back to array:
33-- >>> amap f arr = Stream.unfold Array.reader arr & fmap f & Stream.fold Array.write
34-- >>> amap (+1) (Array.fromList [1,2,3::Int])
37-- = Pinned and Unpinned Arrays
39-- The array type can use both pinned and unpinned memory under the hood.
40-- Currently the array creation APIs create arrays in pinned memory but it will
41-- change to unpinned in future releases. The change should not affect users
42-- functionally unless they are directly accessing the internal memory of the
43-- array via internal APIs. As of now unpinned arrays can be created using
46-- Unpinned arrays have the advantage of allowing automatic defragmentation of
47-- the memory by GC. Whereas pinned arrays have the advantage of not requiring
48-- a copy by GC. Normally you would want to use unpinned arrays. However, in
49-- some cases, for example, for long lived large data storage, and for
50-- interfacing with the operating system or foreign (non-Haskell) consumers you
51-- may want to use pinned arrays.
53-- = Creating Arrays from Non-IO Streams
55-- Array creation folds require 'MonadIO' because they need to sequence effects
56-- in IO streams. To operate on streams in pure Monads like 'Identity' you can
57-- morph it to IO monad as follows:
59-- The 'MonadIO' based folds can be morphed to 'Identity' stream folds:
61-- >>> purely = Fold.morphInner (Identity . unsafePerformIO)
62-- >>> Stream.fold (purely Array.write) $ Stream.fromList [1,2,3::Int]
63-- Identity fromList [1,2,3]
65-- Since it is a pure stream we can use 'unsafePerformIO' to extract the result
68-- Alternatively, 'Identity' streams can be generalized to IO streams:
70-- >>> pure = Stream.fromList [1,2,3] :: Stream Identity Int
71-- >>> generally = Stream.morphInner (return . runIdentity)
72-- >>> Stream.fold Array.write (generally pure :: Stream IO Int)
77-- This module is designed to be imported qualified:
79-- >>> import qualified Streamly.Data.Array as Array
81-- For experimental APIs see "Streamly.Internal.Data.Array".
83module Streamly.Data.Array
85 -- * Imports for Examples
92 -- | When performance matters, the fastest way to generate an array is
93 -- 'writeN'. 'IsList' and 'IsString' instances can be
94 -- used to conveniently construct arrays from literal values.
95 -- 'OverloadedLists' extension or 'fromList' can be used to construct an
96 -- array from a list literal. Similarly, 'OverloadedStrings' extension or
97 -- 'fromList' can be used to construct an array from a string literal.
104 , A.writeN -- drop new
105 , A.write -- full buffer
106 , writeLastN -- drop old (ring buffer)
109 -- 'GHC.Exts.toList' from "GHC.Exts" can be used to convert an array to a
126 -- * Unbox Type Class
137import Streamly.Internal.Data.Unfold (Unfold)
138import Streamly.Internal.Data.Array as A hiding (read, readRev)
140import Streamly.Internal.Data.Unboxed (Unbox (..))
141import Prelude hiding (read)
145-- >>> :set -XFlexibleContexts
146-- >>> import Data.Function ((&))
147-- >>> import Data.Functor.Identity (Identity(..))
148-- >>> import Streamly.Data.Array (Array)
149-- >>> import Streamly.Data.Stream (Stream)
150-- >>> import System.IO.Unsafe (unsafePerformIO)
151-- >>> import qualified Streamly.Data.Array as Array
152-- >>> import qualified Streamly.Data.Fold as Fold
153-- >>> import qualified Streamly.Data.Stream as Stream
157{-# DEPRECATED read "Please use 'reader' instead" #-}
158{-# INLINE_NORMAL read #-}
159read :: (Monad m, Unbox a) => Unfold m (Array a) a
162-- | Same as 'readerRev'
164{-# DEPRECATED readRev "Please use 'readerRev' instead" #-}
165{-# INLINE_NORMAL readRev #-}
166readRev :: (Monad m, Unbox a) => Unfold m (Array a) a
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list