primitive-0.6.4.0: Primitive memory-related operations

Copyright | (c) Dan Doel 2016
License | BSD-style
Maintainer | Libraries <libraries@haskell.org>
Portability | non-portable
Safe Haskell | None
Language | Haskell2010

Data.Primitive.UnliftedArray

Contents

- Types
- Operations
- List Conversion
- Folding
- Mapping

Description

GHC contains three general classes of value types:

1. Unboxed types: values are machine values made up of fixed numbers of bytes
2. Unlifted types: values are pointers, but strictly evaluated
3. Lifted types: values are pointers, lazily evaluated

The first category can be stored in a `ByteArray`, and this allows types in category 3 that are simple wrappers around category 1 types to be stored more efficiently using a `ByteArray`. This module provides the same facility for category 2 types.

GHC has two primitive types, `ArrayArray#` and `MutableArrayArray#`. These are arrays of pointers, but of category 2 values, so they are known to not be bottom. This allows types that are wrappers around such types to be stored in an array without an extra level of indirection.

The way that the `ArrayArray#` API works is that one can read and write `ArrayArray#` values to the positions. This works because all category 2 types share a uniform representation, unlike unboxed values which are represented by varying (by type) numbers of bytes. However, using the this makes the internal API very unsafe to use, as one has to coerce values to and from `ArrayArray#`.

The API presented by this module is more type safe. `UnliftedArray` and `MutableUnliftedArray` are parameterized by the type of arrays they contain, and the coercions necessary are abstracted into a class, `PrimUnlifted`, of things that are eligible to be stored.

Synopsis

- data UnliftedArray e = UnliftedArray ArrayArray#
- data MutableUnliftedArray s e = MutableUnliftedArray (MutableArrayArray# s)
- class PrimUnlifted a where
  - toArrayArray# :: a -> ArrayArray#
  - fromArrayArray# :: ArrayArray# -> a
- unsafeNewUnliftedArray :: PrimMonad m => Int -> m (MutableUnliftedArray (PrimState m) a)
- newUnliftedArray :: (PrimMonad m, PrimUnlifted a) => Int -> a -> m (MutableUnliftedArray (PrimState m) a)
- setUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> a -> m ()
- sizeofUnliftedArray :: UnliftedArray e -> Int
- sizeofMutableUnliftedArray :: MutableUnliftedArray s e -> Int
- readUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> m a
- writeUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> a -> m ()
- indexUnliftedArray :: PrimUnlifted a => UnliftedArray a -> Int -> a
- indexUnliftedArrayM :: (PrimUnlifted a, Monad m) => UnliftedArray a -> Int -> m a
- unsafeFreezeUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> m (UnliftedArray a)
- freezeUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> Int -> Int -> m (UnliftedArray a)
- thawUnliftedArray :: PrimMonad m => UnliftedArray a -> Int -> Int -> m (MutableUnliftedArray (PrimState m) a)
- runUnliftedArray :: (forall s. ST s (MutableUnliftedArray s a)) -> UnliftedArray a
- sameMutableUnliftedArray :: MutableUnliftedArray s a -> MutableUnliftedArray s a -> Bool
- copyUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> Int -> UnliftedArray a -> Int -> Int -> m ()
- copyMutableUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> Int -> MutableUnliftedArray (PrimState m) a -> Int -> Int -> m ()
- cloneUnliftedArray :: UnliftedArray a -> Int -> Int -> UnliftedArray a
- cloneMutableUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> Int -> Int -> m (MutableUnliftedArray (PrimState m) a)
- unliftedArrayToList :: PrimUnlifted a => UnliftedArray a -> [a]
- unliftedArrayFromList :: PrimUnlifted a => [a] -> UnliftedArray a
- unliftedArrayFromListN :: forall a. PrimUnlifted a => Int -> [a] -> UnliftedArray a
- foldrUnliftedArray :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> UnliftedArray a -> b
- foldrUnliftedArray' :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> UnliftedArray a -> b
- foldlUnliftedArray :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> UnliftedArray a -> b
- foldlUnliftedArray' :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> UnliftedArray a -> b
- mapUnliftedArray :: (PrimUnlifted a, PrimUnlifted b) => (a -> b) -> UnliftedArray a -> UnliftedArray b

# Types

data UnliftedArray e #

Immutable arrays that efficiently store types that are simple wrappers around unlifted primitive types. The values of the unlifted type are stored directly, eliminating a layer of indirection.

Constructors

UnliftedArray ArrayArray# |

Instances

PrimUnlifted a => IsList (UnliftedArray a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Associated Types type Item (UnliftedArray a) :: Type # Methods fromList :: [Item (UnliftedArray a)] -> UnliftedArray a # fromListN :: Int -> [Item (UnliftedArray a)] -> UnliftedArray a # toList :: UnliftedArray a -> [Item (UnliftedArray a)] #
(Eq a, PrimUnlifted a) => Eq (UnliftedArray a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods (==) :: UnliftedArray a -> UnliftedArray a -> Bool # (/=) :: UnliftedArray a -> UnliftedArray a -> Bool #
(Ord a, PrimUnlifted a) => Ord (UnliftedArray a) # | Lexicographic ordering. Subject to change between major versions. Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods compare :: UnliftedArray a -> UnliftedArray a -> Ordering # (<) :: UnliftedArray a -> UnliftedArray a -> Bool # (<=) :: UnliftedArray a -> UnliftedArray a -> Bool # (>) :: UnliftedArray a -> UnliftedArray a -> Bool # (>=) :: UnliftedArray a -> UnliftedArray a -> Bool # max :: UnliftedArray a -> UnliftedArray a -> UnliftedArray a # min :: UnliftedArray a -> UnliftedArray a -> UnliftedArray a #
(Show a, PrimUnlifted a) => Show (UnliftedArray a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods showsPrec :: Int -> UnliftedArray a -> ShowS # show :: UnliftedArray a -> String # showList :: [UnliftedArray a] -> ShowS #
PrimUnlifted a => Semigroup (UnliftedArray a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods (<>) :: UnliftedArray a -> UnliftedArray a -> UnliftedArray a # sconcat :: NonEmpty (UnliftedArray a) -> UnliftedArray a # stimes :: Integral b => b -> UnliftedArray a -> UnliftedArray a #
PrimUnlifted a => Monoid (UnliftedArray a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods mempty :: UnliftedArray a # mappend :: UnliftedArray a -> UnliftedArray a -> UnliftedArray a # mconcat :: [UnliftedArray a] -> UnliftedArray a #
PrimUnlifted (UnliftedArray e) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: UnliftedArray e -> ArrayArray# # fromArrayArray# :: ArrayArray# -> UnliftedArray e #
type Item (UnliftedArray a) # |
Instance details Defined in Data.Primitive.UnliftedArray type Item (UnliftedArray a) = a

data MutableUnliftedArray s e #

Mutable arrays that efficiently store types that are simple wrappers around unlifted primitive types. The values of the unlifted type are stored directly, eliminating a layer of indirection.

Constructors

MutableUnliftedArray (MutableArrayArray# s) |

Instances

Eq (MutableUnliftedArray s a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods (==) :: MutableUnliftedArray s a -> MutableUnliftedArray s a -> Bool # (/=) :: MutableUnliftedArray s a -> MutableUnliftedArray s a -> Bool #
PrimUnlifted (MutableUnliftedArray s e) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutableUnliftedArray s e -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutableUnliftedArray s e #

class PrimUnlifted a where #

Classifies the types that are able to be stored in `UnliftedArray` and `MutableUnliftedArray`. These should be types that are just liftings of the unlifted pointer types, so that their internal contents can be safely coerced into an `ArrayArray#`.

Methods

toArrayArray# :: a -> ArrayArray# #

fromArrayArray# :: ArrayArray# -> a #

Instances

PrimUnlifted ThreadId # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: ThreadId -> ArrayArray# # fromArrayArray# :: ArrayArray# -> ThreadId #
PrimUnlifted ByteArray # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: ByteArray -> ArrayArray# # fromArrayArray# :: ArrayArray# -> ByteArray #
PrimUnlifted (StablePtr a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: StablePtr a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> StablePtr a #
PrimUnlifted (TVar a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: TVar a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> TVar a #
PrimUnlifted (Weak a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: Weak a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> Weak a #
PrimUnlifted (MVar a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MVar a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MVar a #
PrimUnlifted (Array a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: Array a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> Array a #
PrimUnlifted (SmallArray a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: SmallArray a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> SmallArray a #
PrimUnlifted (MutableByteArray s) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutableByteArray s -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutableByteArray s #
PrimUnlifted (PrimArray a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: PrimArray a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> PrimArray a #
PrimUnlifted (UnliftedArray e) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: UnliftedArray e -> ArrayArray# # fromArrayArray# :: ArrayArray# -> UnliftedArray e #
PrimUnlifted (MutableArray s a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutableArray s a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutableArray s a #
PrimUnlifted (MutVar s a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutVar s a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutVar s a #
PrimUnlifted (SmallMutableArray s a) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: SmallMutableArray s a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> SmallMutableArray s a #
PrimUnlifted (MutablePrimArray s a) # | Since: 0.6.4.0
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutablePrimArray s a -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutablePrimArray s a #
PrimUnlifted (MutableUnliftedArray s e) # |
Instance details Defined in Data.Primitive.UnliftedArray Methods toArrayArray# :: MutableUnliftedArray s e -> ArrayArray# # fromArrayArray# :: ArrayArray# -> MutableUnliftedArray s e #

# Operations

unsafeNewUnliftedArray #

Arguments

:: PrimMonad m |
=> Int | size
-> m (MutableUnliftedArray (PrimState m) a) |

Creates a new `MutableUnliftedArray`. This function is unsafe because it initializes all elements of the array as pointers to the array itself. Attempting to read one of these elements before writing to it is in effect an unsafe coercion from the `MutableUnliftedArray s a` to the element type.

newUnliftedArray #

Arguments

:: (PrimMonad m, PrimUnlifted a) |
=> Int | size
-> a | initial value
-> m (MutableUnliftedArray (PrimState m) a) |

Creates a new `MutableUnliftedArray` with the specified value as initial contents. This is slower than `unsafeNewUnliftedArray`, but safer.

setUnliftedArray #

Arguments

:: (PrimMonad m, PrimUnlifted a) |
=> MutableUnliftedArray (PrimState m) a | destination
-> a | value to fill with
-> m () |

Sets all the positions in an unlifted array to the designated value.

sizeofUnliftedArray :: UnliftedArray e -> Int #

Yields the length of an `UnliftedArray`.

sizeofMutableUnliftedArray :: MutableUnliftedArray s e -> Int #

Yields the length of a `MutableUnliftedArray`.

readUnliftedArray #

Arguments

:: (PrimMonad m, PrimUnlifted a) |
=> MutableUnliftedArray (PrimState m) a | source
-> Int | index
-> m a |

Gets the value at the specified position of a `MutableUnliftedArray`.

writeUnliftedArray #

Arguments

:: (PrimMonad m, PrimUnlifted a) |
=> MutableUnliftedArray (PrimState m) a | destination
-> Int | index
-> a | value
-> m () |

Sets the value at the specified position of a `MutableUnliftedArray`.

indexUnliftedArray #

Arguments

:: PrimUnlifted a |
=> UnliftedArray a | source
-> Int | index
-> a |

Gets the value at the specified position of an `UnliftedArray`.

indexUnliftedArrayM #

Arguments

:: (PrimUnlifted a, Monad m) |
=> UnliftedArray a | source
-> Int | index
-> m a |

Gets the value at the specified position of an `UnliftedArray`. The purpose of the `Monad` is to allow for being eager in the `UnliftedArray` value without having to introduce a data dependency directly on the result value.

It should be noted that this is not as much of a problem as with a normal `Array`, because elements of an `UnliftedArray` are guaranteed to not be exceptional. This function is provided in case it is more desirable than being strict in the result value.

unsafeFreezeUnliftedArray :: PrimMonad m => MutableUnliftedArray (PrimState m) a -> m (UnliftedArray a) #

Freezes a `MutableUnliftedArray`, yielding an `UnliftedArray`. This simply marks the array as frozen in place, so it should only be used when no further modifications to the mutable array will be performed.

freezeUnliftedArray #

Arguments

:: PrimMonad m |
=> MutableUnliftedArray (PrimState m) a | source
-> Int | offset
-> Int | length
-> m (UnliftedArray a) |

Freezes a portion of a `MutableUnliftedArray`, yielding an `UnliftedArray`. This operation is safe, in that it copies the frozen portion, and the existing mutable array may still be used afterward.

thawUnliftedArray #

Arguments

:: PrimMonad m |
=> UnliftedArray a | source
-> Int | offset
-> Int | length
-> m (MutableUnliftedArray (PrimState m) a) |

Thaws a portion of an `UnliftedArray`, yielding a `MutableUnliftedArray`. This copies the thawed portion, so mutations will not affect the original array.

runUnliftedArray :: (forall s. ST s (MutableUnliftedArray s a)) -> UnliftedArray a #

Execute a stateful computation and freeze the resulting array.

sameMutableUnliftedArray :: MutableUnliftedArray s a -> MutableUnliftedArray s a -> Bool #

Determines whether two `MutableUnliftedArray` values are the same. This is object/pointer identity, not based on the contents.

copyUnliftedArray #

Arguments

:: PrimMonad m |
=> MutableUnliftedArray (PrimState m) a | destination
-> Int | offset into destination
-> UnliftedArray a | source
-> Int | offset into source
-> Int | number of elements to copy
-> m () |

Copies the contents of an immutable array into a mutable array.

copyMutableUnliftedArray #

Arguments

:: PrimMonad m |
=> MutableUnliftedArray (PrimState m) a | destination
-> Int | offset into destination
-> MutableUnliftedArray (PrimState m) a | source
-> Int | offset into source
-> Int | number of elements to copy
-> m () |

Copies the contents of one mutable array into another.

cloneUnliftedArray #

Arguments

:: UnliftedArray a | source
-> Int | offset
-> Int | length
-> UnliftedArray a |

Creates a copy of a portion of an `UnliftedArray`

cloneMutableUnliftedArray #

Arguments

:: PrimMonad m |
=> MutableUnliftedArray (PrimState m) a | source
-> Int | offset
-> Int | length
-> m (MutableUnliftedArray (PrimState m) a) |

Creates a new `MutableUnliftedArray` containing a copy of a portion of another mutable array.

# List Conversion

unliftedArrayToList :: PrimUnlifted a => UnliftedArray a -> [a] #

Convert the unlifted array to a list.

unliftedArrayFromList :: PrimUnlifted a => [a] -> UnliftedArray a #

unliftedArrayFromListN :: forall a. PrimUnlifted a => Int -> [a] -> UnliftedArray a #

# Folding

foldrUnliftedArray :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> UnliftedArray a -> b #

Lazy right-associated fold over the elements of an `UnliftedArray`.

foldrUnliftedArray' :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> UnliftedArray a -> b #

Strict right-associated fold over the elements of an 'UnliftedArray.

foldlUnliftedArray :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> UnliftedArray a -> b #

Lazy left-associated fold over the elements of an `UnliftedArray`.

foldlUnliftedArray' :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> UnliftedArray a -> b #

Strict left-associated fold over the elements of an `UnliftedArray`.

# Mapping

mapUnliftedArray :: (PrimUnlifted a, PrimUnlifted b) => (a -> b) -> UnliftedArray a -> UnliftedArray b #

Map over the elements of an `UnliftedArray`.