Copyright | (c) 2020 Galois Inc. |
---|---|

License | BSD3 |

Maintainer | cryptol@galois.com |

Stability | provisional |

Portability | portable |

Safe Haskell | Safe |

Language | Haskell2010 |

This module implements an "order insensitive" datastructure for record types and values. For most purposes, we want to deal with record fields in a canonical order; but for user interaction purposes, we generally want to display the fields in the order they were specified by the user (in source files, at the REPL, etc.).

## Synopsis

- data RecordMap a b
- displayOrder :: RecordMap a b -> [a]
- canonicalFields :: RecordMap a b -> [(a, b)]
- displayFields :: (Show a, Ord a) => RecordMap a b -> [(a, b)]
- recordElements :: RecordMap a b -> [b]
- fieldSet :: Ord a => RecordMap a b -> Set a
- recordFromFields :: (Show a, Ord a) => [(a, b)] -> RecordMap a b
- recordFromFieldsErr :: (Show a, Ord a) => [(a, b)] -> Either (a, b) (RecordMap a b)
- recordFromFieldsWithDisplay :: (Show a, Ord a) => [a] -> [(a, b)] -> RecordMap a b
- lookupField :: Ord a => a -> RecordMap a b -> Maybe b
- adjustField :: forall a b. Ord a => a -> (b -> b) -> RecordMap a b -> Maybe (RecordMap a b)
- traverseRecordMap :: Applicative t => (a -> b -> t c) -> RecordMap a b -> t (RecordMap a c)
- mapWithFieldName :: (a -> b -> c) -> RecordMap a b -> RecordMap a c
- zipRecordsM :: forall t a b c d. (Ord a, Monad t) => (a -> b -> c -> t d) -> RecordMap a b -> RecordMap a c -> t (Either (Either a a) (RecordMap a d))
- zipRecords :: forall a b c d. Ord a => (a -> b -> c -> d) -> RecordMap a b -> RecordMap a c -> Either (Either a a) (RecordMap a d)
- recordMapAccum :: (a -> b -> (a, c)) -> a -> RecordMap k b -> (a, RecordMap k c)

# Documentation

An "order insensitive" datastructure. The fields can be accessed either according to a "canonical" order, or based on a "display" order, which matches the order in which the fields were originally specified.

## Instances

displayOrder :: RecordMap a b -> [a] Source #

The order in which the fields originally appeared.

canonicalFields :: RecordMap a b -> [(a, b)] Source #

Return a list of field/value pairs in canonical order.

displayFields :: (Show a, Ord a) => RecordMap a b -> [(a, b)] Source #

Return a list of field/value pairs in display order.

recordElements :: RecordMap a b -> [b] Source #

Retrieve the elements of the record in canonical order of the field names

recordFromFields :: (Show a, Ord a) => [(a, b)] -> RecordMap a b Source #

Generate a record from a list of field/value pairs. Precondition: each field identifier appears at most once in the given list.

recordFromFieldsErr :: (Show a, Ord a) => [(a, b)] -> Either (a, b) (RecordMap a b) Source #

Generate a record from a list of field/value pairs. If any field name is repeated, the first repeated name/value pair is returned. Otherwise the constructed record is returned.

recordFromFieldsWithDisplay :: (Show a, Ord a) => [a] -> [(a, b)] -> RecordMap a b Source #

Generate a record from a list of field/value pairs, and also provide the "display" order for the fields directly. Precondition: each field identifier appears at most once in each list, and a field name appears in the display order iff it appears in the field list.

adjustField :: forall a b. Ord a => a -> (b -> b) -> RecordMap a b -> Maybe (RecordMap a b) Source #

Update the value of a field by applying the given function. If the field is not present in the record, return Nothing.

traverseRecordMap :: Applicative t => (a -> b -> t c) -> RecordMap a b -> t (RecordMap a c) Source #

Traverse the elements of the given record map in canonical order, applying the given action.

mapWithFieldName :: (a -> b -> c) -> RecordMap a b -> RecordMap a c Source #

Apply the given function to each element of a record.

zipRecordsM :: forall t a b c d. (Ord a, Monad t) => (a -> b -> c -> t d) -> RecordMap a b -> RecordMap a c -> t (Either (Either a a) (RecordMap a d)) Source #

Zip together the fields of two records using the provided action.
If some field is present in one record, but not the other,
an `Either a a`

will be returned, indicating which record is missing
the field, and returning the name of the missing field.

The `displayOrder`

of the resulting record will be taken from the first
argument (rather arbitrarily).

zipRecords :: forall a b c d. Ord a => (a -> b -> c -> d) -> RecordMap a b -> RecordMap a c -> Either (Either a a) (RecordMap a d) Source #

Pure version of `zipRecordsM`

recordMapAccum :: (a -> b -> (a, c)) -> a -> RecordMap k b -> (a, RecordMap k c) Source #

The function recordMapAccum threads an accumulating argument through the map in canonical order of fields.