úÎ!Žp‰´H      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFG Brent Yorgeybyorgey@gmail.comNone4FX_kÄË$simple-enumerationÿiAn enumeration of a finite or countably infinite set of values. An enumeration is represented as a function from the natural numbers (for infinite enumerations) or a finite prefix of the natural numbers (for finite ones) to values. Enumerations can thus easily be constructed for very large sets, and support efficient indexing and random sampling.. is an instance of the following type classes:H> (you can map a function over every element of an enumeration)I7 (representing Cartesian product of enumerations; see ())J4 (representing disjoint union of enumerations; see ()) is not a K(, since there is no way to implement P that works for any combination of finite and infinite enumerations (but see ).simple-enumeration&Get the cardinality of an enumeration.simple-enumerationÐSelect the value at a particular index of an enumeration. Precondition: the index must be strictly less than the cardinality. For infinite sets, every possible value must occur at some finite index.simple-enumerationAn index into an enumeration.simple-enumerationfThe cardinality of a countable set: either a specific finite natural number, or countably infinite.simple-enumerationPCreate an enumeration primitively out of a cardinality and an index function.simple-enumeration&Test whether an enumeration is finite.isFinite (finiteList [1,2,3])True isFinite natFalse simple-enumeration=List the elements of an enumeration in order. Inverse of .Lsimple-enumeration=The empty enumeration, with cardinality zero and no elements. card voidFinite 0enumerate void[] simple-enumeration-The unit enumeration, with a single value of (). card unitFinite 1enumerate unit[()] simple-enumeration)An enumeration of a single given element.card (singleton 17)Finite 1enumerate (singleton 17)[17] simple-enumeration A constant infinite enumeration.card (always 17)Infinite enumerate . takeE 10 $ always 17[17,17,17,17,17,17,17,17,17,17] simple-enumeration'A finite prefix of the natural numbers.card (finite 5)Finite 5!card (finite 1234567890987654321)Finite 1234567890987654321enumerate (finite 5) [0,1,2,3,4]enumerate (finite 0)[]simple-enumeration0Construct an enumeration from the elements of a finite8 list. To turn an enumeration back into a list, use  . enumerate (finiteList [2,3,8,1]) [2,3,8,1]select (finiteList [2,3,8,1]) 28ÿ does not work on infinite lists: inspecting the cardinality of the resulting enumeration (something many of the enumeration combinators need to do) will hang trying to compute the length of the infinite list. To make an infinite enumeration, use something like f M  where f: is a function to compute the value at any given index. uses (Nÿ%) internally, so you probably want to avoid using it on long lists. It would be possible to make a version with better indexing performance by allocating a vector internally, but I am too lazy to do it. If you have a good use case let me know (better yet, submit a pull request).simple-enumeration&Enumerate all the values of a bounded O instance.enumerate (boundedEnum @Bool) [False,True]select (boundedEnum @Char) 97'a'card (boundedEnum @Int)Finite 18446744073709551616select (boundedEnum @Int) 0-9223372036854775808simple-enumerationThe natural numbers,  0, 1, 2, ....enumerate . takeE 10 $ nat[0,1,2,3,4,5,6,7,8,9]simple-enumerationAll integers in the order 0, 1, -1, 2, -2, 3, -3, ....simple-enumeration>The positive rational numbers, enumerated according to the  Ahttp://www.cs.ox.ac.uk/publications/publication1664-abstract.htmlCalkin-Wilf sequence.enumerate . takeE 10 $ cw=[1 % 1,1 % 2,2 % 1,1 % 3,3 % 2,2 % 3,3 % 1,1 % 4,4 % 3,3 % 5]simple-enumeration|An enumeration of all rational numbers: 0 first, then each rational in the Calkin-Wilf sequence followed by its negative.enumerate . takeE 10 $ ratI[0 % 1,1 % 1,(-1) % 1,1 % 2,(-1) % 2,2 % 1,(-2) % 1,1 % 3,(-1) % 3,3 % 2]simple-enumeration<Take a finite prefix from the beginning of an enumeration.  takeE k e) always yields the empty enumeration for k \leq 0, and results in e whenever kO is greater than or equal to the cardinality of the enumeration. Otherwise  takeE k e has cardinality k and matches e from 0 to k-1.&enumerate $ takeE 3 (boundedEnum @Int)@[-9223372036854775808,-9223372036854775807,-9223372036854775806]'enumerate $ takeE 2 (finiteList [1..5])[1,2]'enumerate $ takeE 0 (finiteList [1..5])[]'enumerate $ takeE 7 (finiteList [1..5]) [1,2,3,4,5]simple-enumeration:Drop some elements from the beginning of an enumeration.  dropE k e yields e unchanged if k \leq 03, and results in the empty enumeration whenever k3 is greater than or equal to the cardinality of e.'enumerate $ dropE 2 (finiteList [1..5])[3,4,5]'enumerate $ dropE 0 (finiteList [1..5]) [1,2,3,4,5]'enumerate $ dropE 7 (finiteList [1..5])[]simple-enumerationÿ"Explicitly mark an enumeration as having an infinite cardinality, ignoring the previous cardinality. It is sometimes necessary to use this as a "hint" when constructing a recursive enumeration whose cardinality would otherwise consist of an infinite sum of finite cardinalities.0For example, consider the following definitions: _data Tree = L | B Tree Tree deriving Show treesBad :: Enumeration Tree treesBad = singleton L P B M treesBad QD treesBad trees :: Enumeration Tree trees = infinite $ singleton L P B M trees Q trees Trying to use treesBada at all will simply hang, since trying to compute its cardinality leads to infinite recursion. %>>> select treesBad 5 ^CInterrupted. However, using , as in the definition of trees", provides the needed laziness: card treesInfiniteenumerate . takeE 3 $ trees[L,B L L,B L (B L L)]select trees 87239862967296ËB (B (B (B (B L L) (B (B (B L L) L) L)) (B L (B L (B L L)))) (B (B (B L (B L (B L L))) (B (B L L) (B L L))) (B (B L (B L (B L L))) L))) (B (B L (B (B (B L (B L L)) (B L L)) L)) (B (B (B L (B L L)) L) L))simple-enumerationFairly interleave a set of infinite enumerations.ÿuFor a finite set of infinite enumerations, a round-robin interleaving is used. That is, if we think of an enumeration of enumerations as a 2D matrix read off row-by-row, this corresponds to taking the transpose of a matrix with finitely many infinite rows, turning it into one with infinitely many finite rows. For an infinite set of infinite enumerations, i.e.P an infinite 2D matrix, the resulting enumeration reads off the matrix by s.Senumerate . takeE 15 $ interleave (finiteList [nat, negate <$> nat, (*10) <$> nat])'[0,0,0,1,-1,10,2,-2,20,3,-3,30,4,-4,40].enumerate . takeE 15 $ interleave (always nat)[0,0,1,0,1,2,0,1,2,3,0,1,2,3,4]This function is similar to  in a hypothetical K instance for D, but it only works when the inner enumerations are all infinite.`To interleave a finite enumeration of enumerations, some of which may be finite, you can use  .  f. If you want to interleave an infinite enumeration of finite enumerations, you are out of luck.simple-enumerationµZip two enumerations in parallel, producing the pair of elements at each index. The resulting enumeration is truncated to the cardinality of the smaller of the two arguments.(enumerate $ zipE nat (boundedEnum @Bool)[(0,False),(1,True)]simple-enumerationæZip two enumerations in parallel, applying the given function to the pair of elements at each index to produce a new element. The resulting enumeration is truncated to the cardinality of the smaller of the two arguments.Renumerate $ zipWithE replicate (finiteList [1..10]) (dropE 35 (boundedEnum @Char))V["#","$$","%%%","&&&&","'''''","((((((",")))))))","********","+++++++++",",,,,,,,,,,"]simple-enumerationSum, i.e.ÿm disjoint union, of two enumerations. If both are finite, all the values of the first will be enumerated before the values of the second. If only one is finite, the values from the finite enumeration will be listed first. If both are infinite, a fair (alternating) interleaving is used, so that every value ends up at a finite index in the result.Note that the () operator is a synonym for (P) from the J instance for ,, which should be used in preference to (). (Q) is provided as a separate standalone operator to make it easier to document.+enumerate . takeE 10 $ singleton 17 <|> nat[17,0,1,2,3,4,5,6,7,8]+enumerate . takeE 10 $ nat <|> singleton 17[17,0,1,2,3,4,5,6,7,8]/enumerate . takeE 10 $ nat <|> (negate <$> nat)[0,0,1,-1,2,-2,3,-3,4,-4]–Note that this is not associative in a strict sense. In particular, it may fail to be associative when mixing finite and infinite enumerations:5enumerate . takeE 10 $ nat <|> (singleton 17 <|> nat)[0,17,1,0,2,1,3,2,4,3]5enumerate . takeE 10 $ (nat <|> singleton 17) <|> nat[17,0,0,1,1,2,2,3,3,4]4However, it is associative in several weaker senses:"If all the enumerations are finite$If all the enumerations are infinite”If enumerations are considered equivalent up to reordering (they are not, but considering them so may be acceptable in some applications).simple-enumeration$One half of the isomorphism between  \mathbb{N} and \mathbb{N} \times \mathbb{N}› which enumerates by diagonals: turn a particular natural number index into its position in the 2D grid. That is, given this numbering of a 2D grid: " 0 1 3 6 ... 2 4 7 5 8 9  maps 70 \mapsto (0,0), 1 \mapsto (0,1), 2 \mapsto (1,0) \dotssimple-enumerationÿ)Cartesian product of enumerations. If both are finite, uses a simple lexicographic ordering. If only one is finite, the resulting enumeration is still in lexicographic order, with the infinite enumeration as the most significant component. For two infinite enumerations, uses a fair  interleaving.2enumerate $ finiteList [1..3] >< finiteList "abcd"a[(1,'a'),(1,'b'),(1,'c'),(1,'d'),(2,'a'),(2,'b'),(2,'c'),(2,'d'),(3,'a'),(3,'b'),(3,'c'),(3,'d')].enumerate . takeE 10 $ finiteList "abc" >< natQ[('a',0),('b',0),('c',0),('a',1),('b',1),('c',1),('a',2),('b',2),('c',2),('a',3)].enumerate . takeE 10 $ nat >< finiteList "abc"Q[(0,'a'),(0,'b'),(0,'c'),(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a')]!enumerate . takeE 10 $ nat >< nat=[(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)]Like (S), this operation is also not associative (not even up to reassociating tuples).simple-enumerationMEnumerate all possible values of type `Maybe a`, where the values of type a& are taken from the given enumeration.(enumerate $ maybeOf (finiteList [1,2,3])[Nothing,Just 1,Just 2,Just 3]simple-enumeration%Enumerae all possible values of type  Either a b8 with inner values taken from the given enumerations.&enumerate . takeE 6 $ eitherOf nat nat.[Left 0,Right 0,Left 1,Right 1,Left 2,Right 2]simple-enumerationQEnumerate all possible finite lists containing values from the given enumeration.!enumerate . takeE 15 $ listOf natZ[[],[0],[0,0],[1],[0,0,0],[1,0],[2],[0,1],[1,0,0],[2,0],[3],[0,0,0,0],[1,1],[2,0,0],[3,0]] simple-enumerationKEnumerate all possible finite subsets of values from the given enumeration.%enumerate $ finiteSubsetOf (finite 3)*[[],[0],[1],[0,1],[2],[0,2],[1,2],[0,1,2]]!simple-enumerationfiniteEnumerationOf n aZ creates an enumeration of all sequences of exactly n items taken from the enumeration a."simple-enumeration Cardinality has a Num“ instance for convenience, so we can use numeric literals as finite cardinalities, and add, subtract, and multiply cardinalities. Note that:subtraction is saturating (i.e. 3 - 5 = 0)&infinity - infinity is treated as zerodzero is treated as a "very strong" annihilator for multiplication: even infinity * zero = zero.#simple-enumerationThe  Alternative instance for  Enumeration; represents the sum monoidal structure on enumerations: empty" is the empty enumeration, and (P) = () is disjoint union.$simple-enumerationThe  Applicative instance for  Enumeration/ works similarly to the instance for lists: pure = singleton, and f Q x# takes the Cartesian product of f and x (see (4)) and applies each paired function and argument."  !"  ! Brent Yorgeybyorgey@gmail.comNone4X_kˆ˜)simple-enumerationÿÆAn invertible enumeration is a bijection between a set of enumerated values and the natural numbers, or a finite prefix of the natural numbers. An invertible enumeration is represented as a function from natural numbers to values, paired with an inverse function that returns the natural number index of a given value. Enumerations can thus easily be constructed for very large sets, and support efficient indexing and random sampling. Note that ) cannot be made an instance of H, I, or J#. However, it does support the G, combinator which cannot be supported by Data.Enumeration.*simple-enumerationWCompute the index of a particular value in its enumeration. Note that the result of *W is only valid when given a value which is actually in the range of the enumeration.+simple-enumerationEMap a pair of inverse functions over an invertible enumeration of a5 values to turn it into an invertible enumeration of b7 values. Because invertible enumerations contain a  bijectionX to the natural numbers, we really do need both directions of a bijection between a and b" in order to map. This is why ) cannot be an instance of H.,simple-enumerationoSelect the value at a particular index. Precondition: the index must be strictly less than the cardinality.-simple-enumeration&Get the cardinality of an enumeration..simple-enumeration&Test whether an enumeration is finite.isFinite (finiteList [1,2,3])True isFinite natFalse/simple-enumeration=List the elements of an enumeration in order. Inverse of 4.0simple-enumeration=The empty enumeration, with cardinality zero and no elements. card voidFinite 0enumerate void[]1simple-enumeration-The unit enumeration, with a single value of () at index 0. card unitFinite 1enumerate unit[()]locate unit ()02simple-enumeration4An enumeration of a single given element at index 0.card (singleton 17)Finite 1enumerate (singleton 17)[17]locate (singleton 17) 1703simple-enumeration'A finite prefix of the natural numbers.card (finite 5)Finite 5!card (finite 1234567890987654321)Finite 1234567890987654321enumerate (finite 5) [0,1,2,3,4]enumerate (finite 0)[]locate (finite 5) 224simple-enumeration0Construct an enumeration from the elements of a finitei list. The elements of the list must all be distinct. To turn an enumeration back into a list, use /. enumerate (finiteList [2,3,8,1]) [2,3,8,1]select (finiteList [2,3,8,1]) 28locate (finiteList [2,3,8,1]) 824Ú does not work on infinite lists: inspecting the cardinality of the resulting enumeration (something many of the enumeration combinators need to do) will hang trying to compute the length of the infinite list.4 uses (N) and RÿE internally (which both take $O(n)$ time), so you probably want to avoid using it on long lists. It would be possible to make a version with better indexing performance by allocating a vector internally, but I am too lazy to do it. If you have a good use case let me know (better yet, submit a pull request).5simple-enumeration&Enumerate all the values of a bounded O instance.enumerate (boundedEnum @Bool) [False,True]select (boundedEnum @Char) 97'a'locate (boundedEnum @Char) 'Z'90card (boundedEnum @Int)Finite 18446744073709551616select (boundedEnum @Int) 0-92233720368547758086simple-enumerationThe natural numbers,  0, 1, 2, ....enumerate . takeE 10 $ nat[0,1,2,3,4,5,6,7,8,9]7simple-enumerationAll integers in the order 0, 1, -1, 2, -2, 3, -3, ....8simple-enumeration>The positive rational numbers, enumerated according to the  Ahttp://www.cs.ox.ac.uk/publications/publication1664-abstract.htmlCalkin-Wilf sequence.enumerate . takeE 10 $ cw=[1 % 1,1 % 2,2 % 1,1 % 3,3 % 2,2 % 3,3 % 1,1 % 4,4 % 3,3 % 5]locate cw (3 % 2)4locate cw (23 % 99)31839simple-enumeration|An enumeration of all rational numbers: 0 first, then each rational in the Calkin-Wilf sequence followed by its negative.enumerate . takeE 10 $ ratI[0 % 1,1 % 1,(-1) % 1,1 % 2,(-1) % 2,2 % 1,(-2) % 1,1 % 3,(-1) % 3,3 % 2]locate rat (-45 % 61)2540:simple-enumeration<Take a finite prefix from the beginning of an enumeration.  takeE k e) always yields the empty enumeration for k \leq 0, and results in e whenever kO is greater than or equal to the cardinality of the enumeration. Otherwise  takeE k e has cardinality k and matches e from 0 to k-1.&enumerate $ takeE 3 (boundedEnum @Int)@[-9223372036854775808,-9223372036854775807,-9223372036854775806]'enumerate $ takeE 2 (finiteList [1..5])[1,2]'enumerate $ takeE 0 (finiteList [1..5])[]'enumerate $ takeE 7 (finiteList [1..5]) [1,2,3,4,5];simple-enumeration:Drop some elements from the beginning of an enumeration.  dropE k e yields e unchanged if k \leq 03, and results in the empty enumeration whenever k3 is greater than or equal to the cardinality of e.'enumerate $ dropE 2 (finiteList [1..5])[3,4,5]'enumerate $ dropE 0 (finiteList [1..5]) [1,2,3,4,5]'enumerate $ dropE 7 (finiteList [1..5])[]<simple-enumerationÿ"Explicitly mark an enumeration as having an infinite cardinality, ignoring the previous cardinality. It is sometimes necessary to use this as a "hint" when constructing a recursive enumeration whose cardinality would otherwise consist of an infinite sum of finite cardinalities.0For example, consider the following definitions: ÿ%data Tree = L | B Tree Tree deriving Show toTree :: Either () (Tree, Tree) -> Tree toTree = either (const L) (uncurry B) fromTree :: Tree -> Either () (Tree, Tree) fromTree L = Left () fromTree (B l r) = Right (l,r) treesBad :: IEnumeration Tree treesBad = mapE toTree fromTree (unit ? (treesBad AV treesBad)) trees :: IEnumeration Tree trees = infinite $ mapE toTree fromTree (unit ? (trees A trees)) Trying to use treesBada at all will simply hang, since trying to compute its cardinality leads to infinite recursion. %>>> select treesBad 5 ^CInterrupted. However, using <, as in the definition of trees", provides the needed laziness: card treesInfiniteenumerate . takeE 3 $ trees[L,B L L,B L (B L L)]select trees 87239862967296ËB (B (B (B (B L L) (B (B (B L L) L) L)) (B L (B L (B L L)))) (B (B (B L (B L (B L L))) (B (B L L) (B L L))) (B (B L (B L (B L L))) L))) (B (B L (B (B (B L (B L L)) (B L L)) L)) (B (B (B L (B L L)) L) L))select trees 123/B (B L (B L L)) (B (B L (B L L)) (B L (B L L)))>locate trees (B (B L (B L L)) (B (B L (B L L)) (B L (B L L))))123=simple-enumerationFairly interleave a set of infinite enumerations.ÿuFor a finite set of infinite enumerations, a round-robin interleaving is used. That is, if we think of an enumeration of enumerations as a 2D matrix read off row-by-row, this corresponds to taking the transpose of a matrix with finitely many infinite rows, turning it into one with infinitely many finite rows. For an infinite set of infinite enumerations, i.e.P an infinite 2D matrix, the resulting enumeration reads off the matrix by s.UNote that the type of this function is slightly different than its counterpart in Data.EnumerationÝ: each enumerated value in the output is tagged with an index indicating which input enumeration it came from. This is required to make the result invertible, and is analogous to the way the output values of ? are tagged with S or T ; in fact, =0 can be thought of as an iterated version of ?., but with a more efficient implementation.>simple-enumerationµZip two enumerations in parallel, producing the pair of elements at each index. The resulting enumeration is truncated to the cardinality of the smaller of the two arguments.Note that defining zipWithE as in Data.Enumerationa is not possible since there would be no way to invert it in general. However, one can use > in combination with + to achieve a similar result.(enumerate $ zipE nat (boundedEnum @Bool)[(0,False),(1,True)]jcs = mapE (uncurry replicate) (length &&& head) (zipE (finiteList [1..10]) (dropE 35 (boundedEnum @Char))) enumerate csV["#","$$","%%%","&&&&","'''''","((((((",")))))))","********","+++++++++",",,,,,,,,,,"]locate cs "********"7?simple-enumerationSum, i.e.ÿm disjoint union, of two enumerations. If both are finite, all the values of the first will be enumerated before the values of the second. If only one is finite, the values from the finite enumeration will be listed first. If both are infinite, a fair (alternating) interleaving is used, so that every value ends up at a finite index in the result.;Note that this has a different type than the version in Data.Enumeration6. Here we require the output to carry an explicit U tag to make it invertible.*enumerate . takeE 5 $ singleton 17 <+> nat)[Left 17,Right 0,Right 1,Right 2,Right 3]*enumerate . takeE 5 $ nat <+> singleton 17&[Right 17,Left 0,Left 1,Left 2,Left 3]!enumerate . takeE 5 $ nat <+> nat&[Left 0,Right 0,Left 1,Right 1,Left 2]locate (nat <+> nat) (Right 35)71@simple-enumeration*The other half of the isomorphism between  \mathbb{N} and \mathbb{N} \times \mathbb{N}¦ which enumerates by diagonals: turn a pair of natural numbers giving a position in the 2D grid into the number in the cell, according to this numbering scheme: " 0 1 3 6 ... 2 4 7 5 8 9 Asimple-enumerationÿ)Cartesian product of enumerations. If both are finite, uses a simple lexicographic ordering. If only one is finite, the resulting enumeration is still in lexicographic order, with the infinite enumeration as the most significant component. For two infinite enumerations, uses a fair  interleaving.2enumerate $ finiteList [1..3] >< finiteList "abcd"a[(1,'a'),(1,'b'),(1,'c'),(1,'d'),(2,'a'),(2,'b'),(2,'c'),(2,'d'),(3,'a'),(3,'b'),(3,'c'),(3,'d')].enumerate . takeE 10 $ finiteList "abc" >< natQ[('a',0),('b',0),('c',0),('a',1),('b',1),('c',1),('a',2),('b',2),('c',2),('a',3)].enumerate . takeE 10 $ nat >< finiteList "abc"Q[(0,'a'),(0,'b'),(0,'c'),(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a')]!enumerate . takeE 10 $ nat >< nat=[(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)]locate (nat >< nat) (1,1)4locate (nat >< nat) (36,45)3357Like (?S), this operation is also not associative (not even up to reassociating tuples).Bsimple-enumerationMEnumerate all possible values of type `Maybe a`, where the values of type a& are taken from the given enumeration.(enumerate $ maybeOf (finiteList [1,2,3])[Nothing,Just 1,Just 2,Just 3]?locate (maybeOf (maybeOf (finiteList [1,2,3]))) (Just (Just 2))3Csimple-enumeration%Enumerae all possible values of type  Either a b8 with inner values taken from the given enumerations.'Note that for invertible enumerations, C is simply a synonym for ?.&enumerate . takeE 6 $ eitherOf nat nat.[Left 0,Right 0,Left 1,Right 1,Left 2,Right 2]Dsimple-enumerationREnumerate all possible finite lists containing values from the given enumeration.!enumerate . takeE 15 $ listOf natZ[[],[0],[0,0],[1],[0,0,0],[1,0],[2],[0,1],[1,0,0],[2,0],[3],[0,0,0,0],[1,1],[2,0,0],[3,0]]!locate (listOf nat) [3,4,20,5,19]!666270815854068922513792635440014Esimple-enumeration»Enumerate all possible finite subsets of values from the given enumeration. The elements in each list will always occur in increasing order of their index in the given enumeration.%enumerate $ finiteSubsetOf (finite 3)*[[],[0],[1],[0,1],[2],[0,2],[1,2],[0,1,2]]%locate (finiteSubsetOf nat) [2,3,6,8]332332 == 2^8 + 2^6 + 2^3 + 2^2TrueFsimple-enumerationfiniteEnumerationOf n aZ creates an enumeration of all sequences of exactly n items taken from the enumeration a.>map E.enumerate . enumerate $ finiteEnumerationOf 2 (finite 3)7[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]Amap E.enumerate . take 10 . enumerate $ finiteEnumerationOf 3 natQ[[0,0,0],[0,0,1],[1,0,0],[0,1,0],[1,0,1],[2,0,0],[0,0,2],[1,1,0],[2,0,1],[3,0,0]]Gsimple-enumerationfunctionOf a bO creates an enumeration of all functions taking values from the enumeration a. and returning values from the enumeration b. As a precondition, a must be finite; otherwise  functionOf throws an error.8bbs = functionOf (boundedEnum @Bool) (boundedEnum @Bool)card bbsFinite 4 map (select bbs 2) [False, True] [True,False]locate bbs not2:locate (functionOf bbs (boundedEnum @Bool)) (\f -> f True)5#)*+,-./0123456789:;<=>?@ABCDEFG#)-,*./0123456789+:;><?A=BCDEFG@V      !"#$%&'()*+,-./012  3 "4#$%&'(567867967:67;36<=6>?6@A67B67C6DE6FG6FH6FIJ,simple-enumeration-0.2-CcMiP6nnB38dyVpQZnErrData.EnumerationData.Enumeration.Invertible Control.Monadjoin Data.Foldableasumdiagonal EnumerationcardselectIndex CardinalityFiniteInfinite mkEnumerationisFinite enumerateunit singletonalwaysfinite finiteList boundedEnumnatintcwrattakeEdropEinfinite interleavezipEzipWithE<+>><maybeOfeitherOflistOffiniteSubsetOffiniteEnumerationOf$fNumCardinality$fAlternativeEnumeration$fApplicativeEnumeration$fShowCardinality$fEqCardinality$fOrdCardinality$fFunctorEnumeration IEnumerationlocatemapEvoid undiagonal functionOfbaseGHC.BaseFunctor Applicative AlternativeMonad Data.Functor<$>GHC.List!!GHC.EnumEnum<|><*> Data.OldList findIndex Data.EitherLeftRightEither