Safe Haskell | None |
---|
Libraries.Auxiliary
Contents
- List operations
- Set and Map related operations
- XIntMaps
- Various map- and fold-like list combinators
- Monadic versions of list combinators
- Loops
- Operations for monads
- Operations for disjoint unions
- Operations for tuples
- Arithmetic operations
- Bit vectors
- Formatting of lists and strings
- Lists optimized for fast concatenation
- Strings optimized for fast concatenation
- The identity monad
- Identity types
- Error messages
- The Curry type class
Description
This module provides miscellaneous general-purpose auxiliary functions.
- applyAt :: Int -> (a -> a) -> [a] -> [a]
- overwriteAt :: Int -> a -> [a] -> [a]
- has_duplicates :: Ord a => [a] -> Bool
- substitute :: Eq a => [a] -> a -> [a] -> [a]
- map_provide :: Ord k => k -> a -> Map k a -> Map k a
- intset_inserts :: [Int] -> IntSet -> IntSet
- intmap_zip :: IntMap x -> IntMap y -> IntMap (x, y)
- intmap_zip_errmsg :: IntMap x -> IntMap y -> String -> IntMap (x, y)
- intmap_map :: (x -> y) -> IntMap x -> IntMap y
- intmap_mapM :: Monad m => (x -> m y) -> IntMap x -> m (IntMap y)
- data XIntMap a
- xintmap_delete :: Int -> XIntMap a -> XIntMap a
- xintmap_deletes :: [Int] -> XIntMap a -> XIntMap a
- xintmap_insert :: Int -> a -> XIntMap a -> XIntMap a
- xintmap_inserts :: [(Int, a)] -> XIntMap a -> XIntMap a
- xintmap_lookup :: Int -> XIntMap a -> Maybe a
- xintmap_member :: Int -> XIntMap a -> Bool
- xintmap_empty :: XIntMap a
- xintmap_freshkey :: XIntMap a -> Int
- xintmap_freshkeys :: Int -> XIntMap a -> [Int]
- xintmap_to_intmap :: XIntMap a -> IntMap a
- xintmap_size :: XIntMap a -> Int
- xintmap_dirty :: XIntMap a -> IntSet
- xintmap_reserves :: IntSet -> XIntMap a -> XIntMap a
- xintmap_unreserves :: IntSet -> XIntMap a -> XIntMap a
- xintmap_makeclean :: XIntMap a -> XIntMap a
- loop :: (Eq int, Num int) => int -> t -> (t -> t) -> t
- loop_with_index :: (Eq int, Num int) => int -> t -> (int -> t -> t) -> t
- fold_right_zip :: ((w, a, b) -> (w, c)) -> (w, [a], [b]) -> (w, [c])
- zip_strict :: [a] -> [b] -> [(a, b)]
- zip_strict_errmsg :: [a] -> [b] -> String -> [(a, b)]
- zip_rightstrict :: [a] -> [b] -> [(a, b)]
- zip_rightstrict_errmsg :: [a] -> [b] -> String -> [(a, b)]
- zipWith_strict :: (a -> b -> c) -> [a] -> [b] -> [c]
- zipWith_rightstrict :: (a -> b -> c) -> [a] -> [b] -> [c]
- loopM :: (Eq int, Num int, Monad m) => int -> t -> (t -> m t) -> m t
- loop_with_indexM :: (Eq int, Num int, Monad m) => int -> t -> (int -> t -> m t) -> m t
- zipRightWithRightStrictM :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]
- zipRightWithRightStrictM_ :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m ()
- fold_right_zipM :: Monad m => ((w, a, b) -> m (w, c)) -> (w, [a], [b]) -> m (w, [c])
- foldRightPairM :: Monad m => (w, [a], [b]) -> ((w, a, b) -> m w) -> m w
- foldRightPairM_ :: Monad m => (w, [a], [b]) -> ((w, a, b) -> m w) -> m ()
- sequence_right :: Monad m => [m a] -> m [a]
- sequence_right_ :: Monad m => [m a] -> m ()
- for :: Monad m => Int -> Int -> Int -> (Int -> m ()) -> m ()
- endfor :: Monad m => m ()
- foreach :: Monad m => [a] -> (a -> m b) -> m ()
- mmap :: Monad m => (a -> b) -> m a -> m b
- monad_join1 :: Monad m => m (a -> m b) -> a -> m b
- map_either :: (a -> b) -> (c -> d) -> Either a c -> Either b d
- map_eitherM :: Monad m => (a -> m b) -> (c -> m d) -> Either a c -> m (Either b d)
- map_pair :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
- map_pairM :: Monad m => (a -> m b) -> (c -> m d) -> (a, c) -> m (b, d)
- int_ceiling :: RealFrac a => a -> Integer
- type Boollist = [Bool]
- boollist_of_int_bh :: Integral a => Int -> a -> Boollist
- boollist_of_int_lh :: Integral a => Int -> a -> Boollist
- int_of_boollist_unsigned_bh :: Integral a => Boollist -> a
- int_of_boollist_signed_bh :: Integral a => Boollist -> a
- bool_xor :: Bool -> Bool -> Bool
- boollist_xor :: Boollist -> Boollist -> Boollist
- string_of_list :: String -> String -> String -> String -> (t -> String) -> [t] -> String
- optional :: Bool -> String -> String
- data BList a
- blist_of_list :: [a] -> BList a
- list_of_blist :: BList a -> [a]
- (+++) :: BList a -> BList a -> BList a
- blist_empty :: BList a
- blist_concat :: [BList a] -> BList a
- type Strbuf = BList Char
- strbuf_of_string :: String -> Strbuf
- string_of_strbuf :: Strbuf -> String
- strbuf_empty :: Strbuf
- strbuf_concat :: [Strbuf] -> Strbuf
- newtype Id a = Id {
- getId :: a
- data Identity a b
- reflexivity :: Identity a a
- symmetry :: Identity a b -> Identity b a
- transitivity :: Identity a b -> Identity b c -> Identity a c
- identity :: Identity a b -> a -> b
- type ErrMsg = String -> String
- class Curry fun args res | args res -> fun where
List operations
overwriteAt :: Int -> a -> [a] -> [a]Source
Overwrite an element at a specified position in a list.
has_duplicates :: Ord a => [a] -> BoolSource
Check whether a list has duplicates.
substitute :: Eq a => [a] -> a -> [a] -> [a]Source
:
Replace the first occurrence of character in string by replacement.
substitute
string character replacement
Set and Map related operations
map_provide :: Ord k => k -> a -> Map k a -> Map k aSource
Insert the given key-value pair in a Map
, but only if the given
key is not already present. If the key is present, keep the old
value.
intset_inserts :: [Int] -> IntSet -> IntSetSource
intmap_zip :: IntMap x -> IntMap y -> IntMap (x, y)Source
intmap_zip_errmsg :: IntMap x -> IntMap y -> String -> IntMap (x, y)Source
Like intmap_zip
, but also takes an error message to use in case of
domain mismatch.
intmap_map :: (x -> y) -> IntMap x -> IntMap ySource
Map a function over all values in an IntMap
.
intmap_mapM :: Monad m => (x -> m y) -> IntMap x -> m (IntMap y)Source
Monadic version of intmap_map
. Map a function over all values
in an IntMap
.
XIntMaps
A XIntMap
is just like an IntMap
, except that it supports
some additional efficient operations: to find the smallest unused
key, to find the set of all keys ever used in the past, and to
reserve a set of keys so that they will not be allocated. Moreover,
it keeps track of the highest key ever used (whether or not it is
still used in the current map).
xintmap_insert :: Int -> a -> XIntMap a -> XIntMap aSource
Insert a new key-value pair in the XIntMap
.
xintmap_inserts :: [(Int, a)] -> XIntMap a -> XIntMap aSource
Insert a list of key-value pairs in the XIntMap
.
xintmap_lookup :: Int -> XIntMap a -> Maybe aSource
xintmap_empty :: XIntMap aSource
The empty XIntMap
.
xintmap_freshkey :: XIntMap a -> IntSource
Return the first free key in the XIntMap
, but without actually
using it yet.
xintmap_freshkeys :: Int -> XIntMap a -> [Int]Source
Return the next k unused keys in the XIntMap
, but without
actually using them yet.
xintmap_size :: XIntMap a -> IntSource
Return the smallest key never used in the XIntMap
.
xintmap_dirty :: XIntMap a -> IntSetSource
A wire is dirty if it is touched but currently free.
xintmap_reserves :: IntSet -> XIntMap a -> XIntMap aSource
Reserve a set of keys in the XIntMap
. For any keys that are not
free, do nothing. All keys must have been used before; for example,
this is the case if they were returned by xintmap_dirty
.
xintmap_unreserves :: IntSet -> XIntMap a -> XIntMap aSource
Unreserve a list of keys in the XIntMap
. If any key is
currently used, do nothing. All keys must have been reserved
before, and (therefore) must have been used before.
xintmap_makeclean :: XIntMap a -> XIntMap aSource
Make an exact copy of the XIntMap
, except that the set of
touched wires is initially set to the set of used wires. In other
words, we mark all free and reserved wires as untouched.
Various map- and fold-like list combinators
loop :: (Eq int, Num int) => int -> t -> (t -> t) -> tSource
Iterate a function n times. Example:
loop 3 x f = f (f (f x))
loop_with_index :: (Eq int, Num int) => int -> t -> (int -> t -> t) -> tSource
Like loop
, but also pass a loop counter to the function being
iterated. Example:
loop_with_index 3 x f = f 2 (f 1 (f 0 x))
fold_right_zip :: ((w, a, b) -> (w, c)) -> (w, [a], [b]) -> (w, [c])Source
Combine right-to-left zipping and folding. Example:
fold_right_zip f (w0, [a,b,c], [x,y,z]) = (w3, [a',b',c']) where f (w0,c,z) = (w1,c') f (w1,b,y) = (w2,b') f (w2,a,x) = (w3,a')
zip_strict :: [a] -> [b] -> [(a, b)]Source
A "strict" version of zip
, i.e., raises an error when the
lists are not of the same length.
zip_strict_errmsg :: [a] -> [b] -> String -> [(a, b)]Source
Like zip_strict
, but also takes an explicit error message to
use in case of failure.
zip_rightstrict :: [a] -> [b] -> [(a, b)]Source
A "right strict" version of zip
, i.e., raises an error when the
left list is shorter than the right one.
zip_rightstrict_errmsg :: [a] -> [b] -> String -> [(a, b)]Source
A version of zip_rightstrict
that also takes an explicit error
message to use in case of failure.
zipWith_strict :: (a -> b -> c) -> [a] -> [b] -> [c]Source
A "strict" version of zipWith
, i.e., raises an error when the
lists are not of the same length.
zipWith_rightstrict :: (a -> b -> c) -> [a] -> [b] -> [c]Source
A "right strict" version of zipWith
, i.e., raises an error when the
right list is shorter than the left one.
Monadic versions of list combinators
loop_with_indexM :: (Eq int, Num int, Monad m) => int -> t -> (int -> t -> m t) -> m tSource
Monadic version of loop_with_index
. Thus,
loop_with_indexM 3 x0 f
will do the following:
do x1 <- f 0 x0 x2 <- f 1 x1 x3 <- f 2 x2 return x3
zipRightWithRightStrictM :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]Source
A right-to-left version of zipWithM
, which is also "right
strict", i.e., raises an error when the right list is shorter than
the left one. Example:
zipRightWithM f [a,b] [x,y] = [f a x, f b y],
computed right-to-left.
zipRightWithRightStrictM_ :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m ()Source
Same as zipRightWithM
, but ignore the result.
fold_right_zipM :: Monad m => ((w, a, b) -> m (w, c)) -> (w, [a], [b]) -> m (w, [c])Source
Monadic version of fold_right_zip
.
foldRightPairM :: Monad m => (w, [a], [b]) -> ((w, a, b) -> m w) -> m wSource
Fold over two lists with state, and do it right-to-left. For example,
foldRightPairM (w0, [1,2,3], [a,b,c]) f
will do the following:
do w1 <- f (w0, 3, c) w2 <- f (w1, 2, b) w3 <- f (w2, 1, a) return w3
foldRightPairM_ :: Monad m => (w, [a], [b]) -> ((w, a, b) -> m w) -> m ()Source
Like foldRightPairM
, but ignore the final result.
sequence_right :: Monad m => [m a] -> m [a]Source
A right-to-left version of sequence
: Evaluate each action in the
sequence from right to left, and collect the results.
sequence_right_ :: Monad m => [m a] -> m ()Source
Same as sequence_right
, but ignore the result.
Loops
We provide a syntax for "for"-style loops.
for :: Monad m => Int -> Int -> Int -> (Int -> m ()) -> m ()Source
A "for" loop. Counts from a to b in increments of s.
Standard notation:
for i = a to b by s do commands end for
Our notation:
for a b s $ \i -> do commands endfor
endfor :: Monad m => m ()Source
Mark the end of a "for"-loop. This command actually does nothing, but can be used to make the loop look prettier.
foreach :: Monad m => [a] -> (a -> m b) -> m ()Source
Iterate a parameter over a list of values. It can be used as follows:
foreach [1,2,3,4] $ \n -> do <<<loop body depending on the parameter n>>> endfor
The loop body will get executed once for each n ∈ {1,2,3,4}.
Operations for monads
mmap :: Monad m => (a -> b) -> m a -> m bSource
Every monad is a functor. Input a function f : a → b and output m f : m a → m b.
monad_join1 :: Monad m => m (a -> m b) -> a -> m bSource
Remove an outer application of a monad from a monadic function.
Operations for disjoint unions
map_either :: (a -> b) -> (c -> d) -> Either a c -> Either b dSource
Take two functions f : a → b and g : c → d, and return f ⊕ g : a ⊕ c → c ⊕ d.
map_eitherM :: Monad m => (a -> m b) -> (c -> m d) -> Either a c -> m (Either b d)Source
Monadic version of map_either
.
Operations for tuples
map_pair :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)Source
Take two functions f : a → b and g : c → d, and return f × g : a × c → c × d.
map_pairM :: Monad m => (a -> m b) -> (c -> m d) -> (a, c) -> m (b, d)Source
Monadic version of mappair
.
Arithmetic operations
int_ceiling :: RealFrac a => a -> IntegerSource
Bit vectors
boollist_of_int_bh :: Integral a => Int -> a -> BoollistSource
Convert an integer to a bit vector. The first argument is the length in bits, and the second argument the integer to be converted. The conversion is big-headian (or equivalently, little-tailian), i.e., the head of the list holds the integer's most significant digit.
boollist_of_int_lh :: Integral a => Int -> a -> BoollistSource
Convert an integer to a bit vector. The first argument is the length in bits, and the second argument the integer to be converted. The conversion is little-headian (or equivalently, big-tailian), i.e., the head of the list holds the integer's least significant digit.
int_of_boollist_unsigned_bh :: Integral a => Boollist -> aSource
Convert a bit vector to an integer. The conversion is big-headian (or equivalently, little-tailian), i.e., the head of the list holds the integer's most significant digit. This function is unsigned, i.e., the integer returned is ≥ 0.
int_of_boollist_signed_bh :: Integral a => Boollist -> aSource
Convert a bit vector to an integer, signed.
boollist_xor :: Boollist -> Boollist -> BoollistSource
Exclusive or operation on bit vectors.
Formatting of lists and strings
string_of_list :: String -> String -> String -> String -> (t -> String) -> [t] -> StringSource
A general list-to-string function. Example:
string_of_list "{" ", " "}" "{}" show [1,2,3] = "{1, 2, 3}"
Lists optimized for fast concatenation
The type of bidirectional lists. This is similar to [a], but optimized for fast concatenation and appending on both sides.
blist_of_list :: [a] -> BList aSource
Convert a List to a BList
.
list_of_blist :: BList a -> [a]Source
Convert a BList
to a List.
blist_empty :: BList aSource
The empty BList
.
blist_concat :: [BList a] -> BList aSource
Concatenate a list of Blist
s.
Strings optimized for fast concatenation
strbuf_of_string :: String -> StrbufSource
Convert a string to a string buffer.
string_of_strbuf :: Strbuf -> StringSource
Convert a string buffer to a string.
The empty string buffer.
strbuf_concat :: [Strbuf] -> StrbufSource
Concatenate a list of string buffers.
The identity monad
The identity monad. Using m = Id
gives useful special cases
of monadic functions.
Identity types
The type Identity
a b witnesses the fact that a and b
are the same type. In other words, this type is non-empty if and
only if a = b. This property is not guaranteed by the type
system, but by the API, via the fact that the operators
relexivity
, symmetry
, and transitivity
are the only exposed
constructors for this type. The implementation of this type is
deliberately hidden, as this is the only way to guarantee its
defining property.
Identity types are useful in certain situations. For example, they can be used to define a data type which is polymorphic in some type variable x, and which has certain constructors that are only available when x is a particular type. For example, in the declaration
data ExampleType x = Constructor1 x | Constructor2 x (Identity x Bool),
Constructor1
is available for all x, but Constructor2
is only
available when x = Bool
.
reflexivity :: Identity a aSource
Witness the fact that a=a.
transitivity :: Identity a b -> Identity b c -> Identity a cSource
Witness the fact that a=b and b=c implies a=c.
identity :: Identity a b -> a -> bSource
The identity function id
: a → b, provided that a and b
are the same type.
Error messages
type ErrMsg = String -> StringSource
Often a low-level function, such as qcdata_zip
and
qcdata_promote
, throws an error because of a failure of some
low-level condition, such as "list too short". To produce error
messages that are meaningful to user-level code, these functions do
not have a hard-coded error message. Instead, they input a stub
error message.
A meaningful error message typically consists of at least three parts:
- the name of the user-level function where the error occurred, for example: "reverse_generic";
- what the function was doing when the error occurred, for example: "operation not permitted in reversible circuit";
- a specific low-level reason for the error, for example: "dynamic lifting".
Thus, a meaningful error message may be: "reverse_generic: operation not permitted in reversible circuit: dynamic lifting".
The problem is that the three pieces of information are not usually present in the same place. The user-level function is often a wrapper function that performs several different mid-level operations (e.g., transforming, reversing). The mid-level function knows what operation was being performed when the error occurred, but often calls a lower-level function to do the actual work (e.g., encapsulating).
Therefore, a stub error message is a function that inputs some lower-level reason for a failure (example: "list too short") and translates this into a higher-level error message (example: "qterm: shape of parameter does not data: list too short").
Sometimes, the stub error message may also ignore the low-level message and completely replace it by a higher-level one. For example, a function that implements integers as bit lists may wish to report a problem with integers, rather than a problem with the underlying lists.
The Curry type class
class Curry fun args res | args res -> fun whereSource
The Curry
type class is used to implement functions that have a
variable number of arguments. It provides a family of type
isomorphisms
fun ≅ args -> res,
where
fun = a1 -> a2 -> ... -> an -> res, args = (a1, (a2, (..., (an, ())))).