Safe Haskell | None |
---|---|
Language | Haskell2010 |
Data.BinaryList
Description
Binary lists are lists whose number of elements is a power of two. This data structure is efficient for some computations like:
- Splitting a list in half.
- Appending two lists of the same length.
- Extracting an element from the list.
All the functions exported are total except for fromListWithDefault
.
It is impossible for the user of this library to create a binary list
whose length is not a power of two.
Since many names in this module clash with the names of some Prelude functions, you probably want to import this module this way:
import Data.BinaryList (BinList,Exponent) import qualified Data.BinaryList as BL
Remember that binary lists are an instance of the Foldable
and Traversable
classes. If you are missing a function here, look for functions using those
instances.
Note that some functions like replicate
, generate
, or take
, don't use
the length of the list as argument, but the exponent of its length expressed
as a power of two. Throughout this document, this is referred
as the length exponent. For example, if the list has length 16, its length exponent
is 4 since 2^4 = 16. Therefore replicate 4 0
will create a list with 16 zeroes.
Keep this in mind when using this library. Note as well that this implies that
there is no need to check that the length argument is or is not a power of two.
Synopsis
- data BinList a
- type Exponent = Word8
- singleton :: a -> BinList a
- append :: BinList a -> BinList a -> Maybe (BinList a)
- replicate :: Exponent -> a -> BinList a
- replicateA :: Applicative f => Exponent -> f a -> f (BinList a)
- replicateAR :: Applicative f => Exponent -> f a -> f (BinList a)
- generate :: Exponent -> (Int -> a) -> BinList a
- generateM :: (Applicative m, Monad m) => Exponent -> (Int -> m a) -> m (BinList a)
- lengthExponent :: BinList a -> Exponent
- lookup :: BinList a -> Int -> Maybe a
- head :: BinList a -> a
- last :: BinList a -> a
- split :: BinList a -> Either a (BinList a, BinList a)
- take :: Exponent -> BinList a -> BinList a
- takeEnd :: Exponent -> BinList a -> BinList a
- replace :: Int -> a -> BinList a -> BinList a
- reverse :: BinList a -> BinList a
- joinPairs :: BinList (a, a) -> BinList a
- disjoinPairs :: BinList a -> Maybe (BinList (a, a))
- zip :: BinList a -> BinList b -> BinList (a, b)
- unzip :: BinList (a, b) -> (BinList a, BinList b)
- zipWith :: (a -> b -> c) -> BinList a -> BinList b -> BinList c
- fromList :: [a] -> Maybe (BinList a)
- fromListWithDefault :: a -> [a] -> BinList a
- fromListSplit :: a -> Exponent -> [a] -> (BinList a, [a])
- toListFilter :: (a -> Bool) -> BinList a -> [a]
- toListSegment :: Int -> Int -> BinList a -> [a]
- traverseSegment :: Applicative f => (a -> f ()) -> Int -> Int -> BinList a -> f ()
Type
A binary list is a list containing a power of two elements.
Note that a binary list is never empty because it has at
least 2^0 = 1
element.
Instances
Functor BinList Source # | |
Foldable BinList Source # | |
Defined in Data.BinaryList Methods fold :: Monoid m => BinList m -> m # foldMap :: Monoid m => (a -> m) -> BinList a -> m # foldMap' :: Monoid m => (a -> m) -> BinList a -> m # foldr :: (a -> b -> b) -> b -> BinList a -> b # foldr' :: (a -> b -> b) -> b -> BinList a -> b # foldl :: (b -> a -> b) -> b -> BinList a -> b # foldl' :: (b -> a -> b) -> b -> BinList a -> b # foldr1 :: (a -> a -> a) -> BinList a -> a # foldl1 :: (a -> a -> a) -> BinList a -> a # elem :: Eq a => a -> BinList a -> Bool # maximum :: Ord a => BinList a -> a # minimum :: Ord a => BinList a -> a # | |
Traversable BinList Source # | |
NFData a => NFData (BinList a) Source # | |
Defined in Data.BinaryList.Internal | |
Show a => Show (BinList a) Source # | |
Eq a => Eq (BinList a) Source # | |
Construction
append :: BinList a -> BinList a -> Maybe (BinList a) Source #
O(1). Append two binary lists. This is only possible
if both lists have the same length. If this condition
is not hold, Nothing
is returned.
replicate :: Exponent -> a -> BinList a Source #
O(log n). Calling replicate n x
builds a binary list with
2^n
occurences of x
.
replicateA :: Applicative f => Exponent -> f a -> f (BinList a) Source #
Calling replicateA n f
builds a binary list collecting the results of
executing 2^n
times the applicative action f
.
replicateAR :: Applicative f => Exponent -> f a -> f (BinList a) Source #
The same as replicateA
, but the actions are executed in reversed order.
generate :: Exponent -> (Int -> a) -> BinList a Source #
O(n). Build a binary list with the given length exponent (see lengthExponent
)
by applying a function to each index.
Queries
lengthExponent :: BinList a -> Exponent Source #
O(1). Given a binary list l
with length 2^k
:
lengthExponent l = k
lookup :: BinList a -> Int -> Maybe a Source #
O(log n). Lookup an element in the list by its index (starting from 0).
If the index is out of range, Nothing
is returned.
Deconstruction
split :: BinList a -> Either a (BinList a, BinList a) Source #
O(1). Split a binary list into two sublists of half the length, unless the list only contains one element. In that case, it just returns that element.
take :: Exponent -> BinList a -> BinList a Source #
O(log n). Calling take n xs
returns the first min (2^n) (length xs)
elements of xs
.
takeEnd :: Exponent -> BinList a -> BinList a Source #
O(log n). Calling takeEnd n xs
returns the last min (2^n) (length xs)
elements of xs
.
Transformation
O(log n). Replace a single element in the list. If the index is out of range, returns the original list.
Tuples
joinPairs :: BinList (a, a) -> BinList a Source #
O(n). Transform a list of pairs into a flat list. The resulting list will have twice more elements than the original.
Zipping and Unzipping
zipWith :: (a -> b -> c) -> BinList a -> BinList b -> BinList c Source #
O(n). Zip two binary lists using an operator.
Lists
From list
fromList :: [a] -> Maybe (BinList a) Source #
O(n). Build a binary list from a linked list. If the input list
has length different from a power of two, it returns Nothing
.
fromListWithDefault :: a -> [a] -> BinList a Source #
O(n). Build a binary list from a linked list. If the input list has length different from a power of two, fill to the next power of two with a default element.
Warning: this function crashes if the input list length is larger than any
power of two in the type Int
. However, this is very unlikely.
O(n). Build a binary list from a linked list. It returns a binary list
with length 2 ^ n
(where n
is the supplied Int
argument), and
the list of elements of the original list that were not used. If the
input list is shorter than 2 ^ n
, a default element will be used to
complete the binary list. This method for building binary lists is faster
than both fromList
and fromListWithDefault
.
To list
toListFilter :: (a -> Bool) -> BinList a -> [a] Source #
O(n). Create a list from the elements of a binary list matching a given condition.
toListSegment :: Int -> Int -> BinList a -> [a] Source #
O(n). Create a list extracting a sublist of elements from a binary list.
Others
traverseSegment :: Applicative f => (a -> f ()) -> Int -> Int -> BinList a -> f () Source #
Apply an applicative action to every element in a segment of a binary list, from left to right.
Example: Radix-2 FFT
This is an example demonstrating the use of binary lists to calculate the Discrete Fourier Transform of complex vectors with the Radix-2 Fast Fourier Transform algorithm.
import Data.BinaryList (BinList) import qualified Data.BinaryList as BL import Data.Complex import Data.Maybe (fromJust) i :: Complex Double i = 0 :+ 1 fft :: BinList (Complex Double) -> BinList (Complex Double) fft xs = case BL.disjoinPairs xs of Nothing -> xs Just ps -> let (evens,odds) = BL.unzip ps n = BL.lengthExponent xs - 1 q = negate $ pi * i / fromIntegral (2^n) twiddles = BL.generate n $ \k -> exp $ q * fromIntegral k oddsfft = BL.zipWith (*) twiddles $ fft odds evensfft = fft evens in fromJust $ BL.append (BL.zipWith (+) evensfft oddsfft) (BL.zipWith (-) evensfft oddsfft)
Orphan instances
Functor BinList Source # | |
Foldable BinList Source # | |
Methods fold :: Monoid m => BinList m -> m # foldMap :: Monoid m => (a -> m) -> BinList a -> m # foldMap' :: Monoid m => (a -> m) -> BinList a -> m # foldr :: (a -> b -> b) -> b -> BinList a -> b # foldr' :: (a -> b -> b) -> b -> BinList a -> b # foldl :: (b -> a -> b) -> b -> BinList a -> b # foldl' :: (b -> a -> b) -> b -> BinList a -> b # foldr1 :: (a -> a -> a) -> BinList a -> a # foldl1 :: (a -> a -> a) -> BinList a -> a # elem :: Eq a => a -> BinList a -> Bool # maximum :: Ord a => BinList a -> a # minimum :: Ord a => BinList a -> a # | |
Traversable BinList Source # | |
Show a => Show (BinList a) Source # | |