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