In my previous post, I began describing the primitive species and species operations supported by my combinatorial species library; we looked at the ring structure on species, that is, the primitive species and , and the operations of species sum and product. Today we’ll continue by looking at a few more primitive species: singletons, sets, and cycles.
[By the way, all the diagrams for this post and the previous one were generated programmatically using my diagrams library. I’ll probably put the code up as an example on the diagrams website sometime in the near future.]
The species , also known as the species of singletons, is picky in a way similar to the species . Whereas only puts a structure on the empty set of labels, X only puts a (single) structure on singleton label sets. If you give it more than one label, or none, it turns up its nose and refuses to do anything.
> take 10 $ labelled singleton
> generate singleton (['a'] :: [Char])
> generate singleton ("abc" :: [Char])
A few exercises: try to work them out yourself, then use the species library to check if you are correct!
- Describe the species . Show that it is isomorphic to the species .
- Describe the species .
The species of sets, on the other hand, isn’t picky at all: it will happily put a singleton structure on any label set. Usually we identify this structure with the label set itself; that is, the only -structure on a label set is itself.
> take 10 $ labelled sets
> take 10 $ unlabelled sets
> generate set ([1..3] :: [Int])
> generate set ( :: [Int])
We can now also describe the derived species of elements, also known as the species of pointed sets. The only way to get any structures is by partitioning the label set into a singleton and all the rest, in which case we get exactly one structure; so there is one structure for each element of .
> take 10 $ labelled (x * set)
> take 10 $ unlabelled (x * set)
> generate (x * set) ([1..3] :: [Int])
x is just a synonym for
singleton.) Noteworthy is the fact that this is the first species we’ve looked at which has different numbers of labelled and unlabelled structures! This makes sense: there are labelled -structures on a size set; but if we can’t tell the difference between the labels, any one of them is just as good as any other, so we only get one unlabelled structure (unless the label set is empty, when we don’t get any structures: the still requires us to have at least one element!). Note also that
element is a special synonym for
x * set with a special semantics under
generate: if we really want to pick elements of the label set, then we probably don’t want to actually see each element paired with a set of the leftover elements, we just want to see the element itself:
> generate elements ([1..3]::[Int])
The final primitive species—and the only one so far that doesn’t feel quite so utterly trivial—is the species of cycles. puts no structures on an empty label set, but given any non-empty label set, generates the set of all cyclical orderings of the labels.
Of course, the above diagram only shows six of the cycle structures on five labels; the ellipsis is meant to suggest the others not shown. So… how many labelled cycle structures are there on five labels, or generally on labels? (Of course there is only one unlabelled -cycle.) I’ll leave it as a (hopefully easy) exercise; and of course you know how to check your answer!
> generate cycles ([1..4] :: [Int])
As you can see, cycles are indicated with angle brackets; it is understood that
<4,1,2,3> are all equivalent.
At this point, you’re probably thinking about a certain species and wondering why I haven’t mentioned it yet—it seems pretty fundamental and primitive. Are you thinking of… the species of lists? It turns out that we don’t have to take lists as primitive—we can define the species of lists as the derivative of the species of cycles! The derivative of a regular type is its type of one-hole… but I’m getting ahead of myself. We’ll look at species differentiation (along with several other operations on species) in the next post!