h2jvm
Safe HaskellNone
LanguageGHC2021

H2JVM.Data.TypeMergingList

Description

A Snoc List type that merges elements of the same constructor. We use this for managing class attributes, where adding a new attribute of the same type should merge with the existing one rather than just being added to the list. For example, suppose we have some data type:

data Entry = IntEntry Int | StringEntry String deriving (Eq, Data, Show)
instance Semigroup Entry where
   IntEntry a <> IntEntry b = IntEntry (a + b)
   StringEntry a <> StringEntry b = StringEntry (a ++ b)
   _ <> b = b -- if the constructors don't match, just take the right one

Then we can do:

snoc (TypeMergingList []) (IntEntry 1) = TypeMergingList [IntEntry 1]
snoc (TypeMergingList [IntEntry 1]) (IntEntry 2) = TypeMergingList [IntEntry 3]
snoc (TypeMergingList [IntEntry 1]) (StringEntry "hello") = TypeMergingList [IntEntry 1, StringEntry "hello"]
snoc (TypeMergingList [IntEntry 1, StringEntry "hello"]) (StringEntry "world") = TypeMergingList [IntEntry 1, StringEntry "helloworld"]
Synopsis

Data types

newtype TypeMergingList a Source #

A list type that merges elements of the same constructor using the merge function from the DataMergeable class.

Constructors

TypeMergingList [a] 

Instances

Instances details
Foldable TypeMergingList Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

Methods

fold :: Monoid m => TypeMergingList m -> m #

foldMap :: Monoid m => (a -> m) -> TypeMergingList a -> m #

foldMap' :: Monoid m => (a -> m) -> TypeMergingList a -> m #

foldr :: (a -> b -> b) -> b -> TypeMergingList a -> b #

foldr' :: (a -> b -> b) -> b -> TypeMergingList a -> b #

foldl :: (b -> a -> b) -> b -> TypeMergingList a -> b #

foldl' :: (b -> a -> b) -> b -> TypeMergingList a -> b #

foldr1 :: (a -> a -> a) -> TypeMergingList a -> a #

foldl1 :: (a -> a -> a) -> TypeMergingList a -> a #

toList :: TypeMergingList a -> [a] #

null :: TypeMergingList a -> Bool #

length :: TypeMergingList a -> Int #

elem :: Eq a => a -> TypeMergingList a -> Bool #

maximum :: Ord a => TypeMergingList a -> a #

minimum :: Ord a => TypeMergingList a -> a #

sum :: Num a => TypeMergingList a -> a #

product :: Num a => TypeMergingList a -> a #

DataMergeable a => Monoid (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

DataMergeable a => Semigroup (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

DataMergeable a => IsList (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

Associated Types

type Item (TypeMergingList a) 
Instance details

Defined in H2JVM.Data.TypeMergingList

type Item (TypeMergingList a) = a
Show a => Show (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

Eq a => Eq (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

Ord a => Ord (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

Pretty a => Pretty (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

type Item (TypeMergingList a) Source # 
Instance details

Defined in H2JVM.Data.TypeMergingList

type Item (TypeMergingList a) = a

class Data a => DataMergeable a where Source #

Class of partially mergeable types. Instances of this class may assume that the constructors of the two arguments are the same (i.e. toConstr x == toConstr y), and are permitted to be partial if this is not the case. The helper function errorDifferentConstructors is provided for conveniently throwing an error in this case.

Methods

merge :: a -> a -> a Source #

Merge two values of the same constructor. This function is partial if the constructors of the two arguments are different.

errorDifferentConstructors :: (Data a, HasCallStack) => a -> a -> b Source #

Convenience function for writing invalid merge errors.

Operations

snoc :: DataMergeable a => TypeMergingList a -> a -> TypeMergingList a Source #

Append an element to the end of a TypeMergingList, merging it with the last element if they have the same constructor. \(O(1)\)

>>> data Entry = IntEntry Int | StringEntry String deriving (Eq, Data, Show)
>>> instance DataMergeable Entry where { IntEntry a `merge` IntEntry b = IntEntry (a + b); StringEntry a `merge` StringEntry b = StringEntry (a ++ b); _ `merge` b = b}
>>> snoc (TypeMergingList [IntEntry 1]) (IntEntry 2)
TypeMergingList [IntEntry 3]
>>> snoc (TypeMergingList [IntEntry 1]) (StringEntry "hello")
TypeMergingList [StringEntry "hello",IntEntry 1]
>>> snoc (TypeMergingList [IntEntry 1, StringEntry "hello"]) (StringEntry "world")
TypeMergingList [StringEntry "world",IntEntry 1,StringEntry "hello"]

Conversions

toList :: TypeMergingList a -> [a] Source #

Convert a TypeMergingList to a regular list. \(O(N)\)

toVector :: TypeMergingList a -> Vector a Source #

Convert a TypeMergingList to a Vector. \(O(N)\)

fromList :: (DataMergeable a, Data a) => [a] -> TypeMergingList a Source #

Create a TypeMergingList from a regular list. \(O(N)\)