diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+0.3.3      11 June 2015
+  * add primitive species of bracelets
+
 0.3.2.4    17 April 2015
   * update to work with GHC 7.8 and 7.10
   * drop support for GHC < 7.8
diff --git a/Math/Combinatorics/Species.hs b/Math/Combinatorics/Species.hs
--- a/Math/Combinatorics/Species.hs
+++ b/Math/Combinatorics/Species.hs
@@ -31,7 +31,7 @@
       -- Explicitly export methods of the Species class since
       -- we don't want to export all of them
 
-      Species ( singleton, set, cycle, linOrd
+      Species ( singleton, set, cycle, bracelet, linOrd
               , subset, ksubset, element
               , o, (><), (@@)
               , ofSize, ofSizeExactly, nonEmpty
@@ -42,7 +42,7 @@
       -- $synonyms
 
     , oneHole
-    , x, sets, cycles
+    , x, sets, cycles, bracelets
     , linOrds
     , subsets
     , ksubsets
diff --git a/Math/Combinatorics/Species/AST.hs b/Math/Combinatorics/Species/AST.hs
--- a/Math/Combinatorics/Species/AST.hs
+++ b/Math/Combinatorics/Species/AST.hs
@@ -1,12 +1,11 @@
-{-# LANGUAGE NoImplicitPrelude
-           , CPP
-           , GADTs
-           , TypeFamilies
-           , KindSignatures
-           , FlexibleContexts
-           , RankNTypes
-           , TypeOperators
-  #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE GADTs             #-}
+{-# LANGUAGE KindSignatures    #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes        #-}
+{-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE TypeOperators     #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -48,19 +47,17 @@
 
     ) where
 
-import Math.Combinatorics.Species.Structures
-import Math.Combinatorics.Species.Util.Interval
+import           Math.Combinatorics.Species.Structures
+import           Math.Combinatorics.Species.Util.Interval
 import qualified Math.Combinatorics.Species.Util.Interval as I
 
-import Data.Typeable
-import Unsafe.Coerce
-
-import Data.Maybe (fromMaybe)
+import           Data.Typeable
+import           Unsafe.Coerce
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase hiding (cycle)
+import           PreludeBase                              hiding (cycle)
 #endif
 
 ------------------------------------------------------------
@@ -78,15 +75,16 @@
   X             :: SpeciesAST
   E             :: SpeciesAST
   C             :: SpeciesAST
+  B             :: SpeciesAST
   L             :: SpeciesAST
   Subset        :: SpeciesAST
   KSubset       :: Integer -> SpeciesAST
   Elt           :: SpeciesAST
-  (:+)         :: SpeciesAST -> SpeciesAST -> SpeciesAST
-  (:*)         :: SpeciesAST -> SpeciesAST -> SpeciesAST
-  (:.)         :: SpeciesAST -> SpeciesAST -> SpeciesAST
-  (:><)        :: SpeciesAST -> SpeciesAST -> SpeciesAST
-  (:@)         :: SpeciesAST -> SpeciesAST -> SpeciesAST
+  (:+)          :: SpeciesAST -> SpeciesAST -> SpeciesAST
+  (:*)          :: SpeciesAST -> SpeciesAST -> SpeciesAST
+  (:.)          :: SpeciesAST -> SpeciesAST -> SpeciesAST
+  (:><)         :: SpeciesAST -> SpeciesAST -> SpeciesAST
+  (:@)          :: SpeciesAST -> SpeciesAST -> SpeciesAST
   Der           :: SpeciesAST -> SpeciesAST
   OfSize        :: SpeciesAST -> (Integer -> Bool) -> SpeciesAST
   OfSizeExactly :: SpeciesAST -> Integer -> SpeciesAST
@@ -122,6 +120,7 @@
    TX        :: TSpeciesAST Id
    TE        :: TSpeciesAST Set
    TC        :: TSpeciesAST Cycle
+   TB        :: TSpeciesAST Bracelet
    TL        :: TSpeciesAST []
    TSubset   :: TSpeciesAST Set
    TKSubset  :: Integer -> TSpeciesAST Set
@@ -148,10 +147,11 @@
 interval :: TSpeciesAST s -> Interval
 interval TZero                = emptyI
 interval TOne                 = zero
-interval (TN n)               = zero
+interval (TN _)               = zero
 interval TX                   = one
 interval TE                   = natsI
 interval TC                   = fromI one
+interval TB                   = fromI one
 interval TL                   = natsI
 interval TSubset              = natsI
 interval (TKSubset k)         = fromI (fromInteger k)
@@ -160,7 +160,7 @@
 interval (f :*:: g)           = getI f + getI g
 interval (f :.:: g)           = getI f * getI g
 interval (f :><:: g)          = getI f `I.intersect` getI g
-interval (f :@:: g)           = natsI
+interval (_ :@:: _)           = natsI
     -- Note, the above interval for functor composition is obviously
     -- overly conservative.  To do this right we'd have to compute the
     -- generating function for g --- and actually it would depend on
@@ -234,6 +234,7 @@
 erase' TX                   = X
 erase' TE                   = E
 erase' TC                   = C
+erase' TB                   = B
 erase' TL                   = L
 erase' TSubset              = Subset
 erase' (TKSubset k)         = KSubset k
@@ -258,6 +259,7 @@
 annotate X                   = wrap TX
 annotate E                   = wrap TE
 annotate C                   = wrap TC
+annotate B                   = wrap TB
 annotate L                   = wrap TL
 annotate Subset              = wrap TSubset
 annotate (KSubset k)         = wrap (TKSubset k)
diff --git a/Math/Combinatorics/Species/AST/Instances.hs b/Math/Combinatorics/Species/AST/Instances.hs
--- a/Math/Combinatorics/Species/AST/Instances.hs
+++ b/Math/Combinatorics/Species/AST/Instances.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE CPP, GADTs #-}
+{-# LANGUAGE CPP   #-}
+{-# LANGUAGE GADTs #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -25,22 +26,20 @@
     where
 
 #if MIN_VERSION_numeric_prelude(0,2,0)
-import NumericPrelude hiding (cycle)
+import           NumericPrelude                   hiding (cycle)
 #else
-import NumericPrelude
-import PreludeBase hiding (cycle)
+import           NumericPrelude
+import           PreludeBase                      hiding (cycle)
 #endif
 
-import Math.Combinatorics.Species.Class
-import Math.Combinatorics.Species.AST
-import Math.Combinatorics.Species.Util.Interval hiding (omega)
-import qualified Math.Combinatorics.Species.Util.Interval as I
+import           Math.Combinatorics.Species.AST
+import           Math.Combinatorics.Species.Class
 
-import qualified Algebra.Additive as Additive
-import qualified Algebra.Ring as Ring
-import qualified Algebra.Differential as Differential
+import qualified Algebra.Additive                 as Additive
+import qualified Algebra.Differential             as Differential
+import qualified Algebra.Ring                     as Ring
 
-import Data.Typeable
+import           Data.Typeable
 
 ------------------------------------------------------------
 --  SpeciesAST instances  ----------------------------------
@@ -62,15 +61,16 @@
   X                   == X                    = True
   E                   == E                    = True
   C                   == C                    = True
+  B                   == B                    = True
   L                   == L                    = True
   Subset              == Subset               = True
   (KSubset k)         == (KSubset j)          = k == j
   Elt                 == Elt                  = True
-  (f1 :+ g1)         == (f2 :+ g2)          = f1 == f2 && g1 == g2
-  (f1 :* g1)         == (f2 :* g2)          = f1 == f2 && g1 == g2
-  (f1 :. g1)         == (f2 :. g2)          = f1 == f2 && g1 == g2
-  (f1 :>< g1)        == (f2 :>< g2)         = f1 == f2 && g1 == g2
-  (f1 :@ g1)         == (f2 :@ g2)          = f1 == f2 && g1 == g2
+  (f1 :+ g1)          == (f2 :+ g2)           = f1 == f2 && g1 == g2
+  (f1 :* g1)          == (f2 :* g2)           = f1 == f2 && g1 == g2
+  (f1 :. g1)          == (f2 :. g2)           = f1 == f2 && g1 == g2
+  (f1 :>< g1)         == (f2 :>< g2)          = f1 == f2 && g1 == g2
+  (f1 :@ g1)          == (f2 :@ g2)           = f1 == f2 && g1 == g2
   Der f1              == Der f2               = f1 == f2
   -- note, OfSize will always compare False since we can't compare the functions for equality
   OfSizeExactly f1 k1 == OfSizeExactly f2 k2  = f1 == f2 && k1 == k2
@@ -98,6 +98,8 @@
   compare _ E                       = GT
   compare C _                       = LT
   compare _ C                       = GT
+  compare B _                       = LT
+  compare _ B                       = GT
   compare L _                       = LT
   compare _ L                       = GT
   compare Subset _                  = LT
@@ -130,7 +132,7 @@
   compare (Der f1) (Der f2)         = compare f1 f2
   compare (Der _) _                 = LT
   compare _ (Der _)                 = GT
-  compare (OfSize f1 p1) (OfSize f2 p2)
+  compare (OfSize f1 _) (OfSize f2 _)
                                     = compare f1 f2
   compare (OfSize _ _) _            = LT
   compare _ (OfSize _ _)            = GT
@@ -158,6 +160,7 @@
   showsPrec _ X                   = showChar 'X'
   showsPrec _ E                   = showChar 'E'
   showsPrec _ C                   = showChar 'C'
+  showsPrec _ B                   = showChar 'B'
   showsPrec _ L                   = showChar 'L'
   showsPrec _ Subset              = showChar 'p'
   showsPrec _ (KSubset n)         = showChar 'p' . shows n
@@ -212,6 +215,7 @@
   singleton     = X
   set           = E
   cycle         = C
+  bracelet      = B
   linOrd        = L
   subset        = Subset
   ksubset k     = KSubset k
@@ -254,6 +258,7 @@
   singleton                 = wrap TX
   set                       = wrap TE
   cycle                     = wrap TC
+  bracelet                  = wrap TB
   linOrd                    = wrap TL
   subset                    = wrap TSubset
   ksubset k                 = wrap $ TKSubset k
@@ -294,6 +299,7 @@
 reflect X                   = singleton
 reflect E                   = set
 reflect C                   = cycle
+reflect B                   = bracelet
 reflect L                   = linOrd
 reflect Subset              = subset
 reflect (KSubset k)         = ksubset k
diff --git a/Math/Combinatorics/Species/Class.hs b/Math/Combinatorics/Species/Class.hs
--- a/Math/Combinatorics/Species/Class.hs
+++ b/Math/Combinatorics/Species/Class.hs
@@ -34,6 +34,8 @@
       -- instead of @'set' `o` 'nonEmpty' 'set'@.
     , sets
     , cycles
+    , necklace, necklaces
+    , bracelets
     , linOrds
     , subsets
     , ksubsets
@@ -95,6 +97,10 @@
   -- | The species @C@ of cyclical orderings (cycles/rings).
   cycle :: s
 
+  -- | The species of bracelets (i.e. cycles that can also be
+  --   flipped).
+  bracelet :: s
+
   -- | The species @L@ of linear orderings (lists). Since linear
   --   orderings are isomorphic to cyclic orderings with a hole, we
   --   may take @'linOrd' = 'oneHole' 'cycle'@ as the default
@@ -172,7 +178,7 @@
   --   in for recursive occurrences of a species.
   omega :: s
 
-  {-# MINIMAL singleton, set, cycle, o, (><), (@@), ofSize #-}
+  {-# MINIMAL singleton, set, cycle, bracelet, o, (><), (@@), ofSize #-}
 
 -- | A convenient synonym for differentiation.  @'oneHole'
 -- f@-structures look like @f@-structures on a set formed by adjoining
@@ -193,6 +199,14 @@
 
 cycles :: Species s => s
 cycles = cycle
+
+-- | A synonym for 'cycle'.
+necklace, necklaces :: Species s => s
+necklace = cycle
+necklaces = cycle
+
+bracelets :: Species s => s
+bracelets = bracelet
 
 -- $derived_ops
 -- Some derived operations on species.
diff --git a/Math/Combinatorics/Species/CycleIndex.hs b/Math/Combinatorics/Species/CycleIndex.hs
--- a/Math/Combinatorics/Species/CycleIndex.hs
+++ b/Math/Combinatorics/Species/CycleIndex.hs
@@ -1,7 +1,6 @@
-{-# LANGUAGE NoImplicitPrelude
-           , CPP
-           , FlexibleInstances
-  #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -30,30 +29,32 @@
     , cyclePower
     ) where
 
-import Math.Combinatorics.Species.Types
-import Math.Combinatorics.Species.Class
-import Math.Combinatorics.Species.Labeled
+import           Math.Combinatorics.Species.Class
+import           Math.Combinatorics.Species.Labeled
+import           Math.Combinatorics.Species.Types
 
-import Math.Combinatorics.Species.NewtonRaphson
+import           Math.Combinatorics.Species.NewtonRaphson
 
-import qualified MathObj.PowerSeries as PowerSeries
-import qualified MathObj.MultiVarPolynomial as MVP
-import qualified MathObj.Monomial as Monomial
-import qualified MathObj.FactoredRational as FQ
+import qualified MathObj.FactoredRational                 as FQ
+import qualified MathObj.Monomial                         as Monomial
+import qualified MathObj.MultiVarPolynomial               as MVP
+import qualified MathObj.PowerSeries                      as PowerSeries
 
-import qualified Algebra.Ring as Ring
-import qualified Algebra.ZeroTestable as ZeroTestable
+import qualified Algebra.Ring                             as Ring
+import qualified Algebra.ZeroTestable                     as ZeroTestable
 
-import qualified Data.Map as M
-import Data.List ( genericReplicate, genericDrop, groupBy, sort, intercalate, scanl
-                 , genericIndex)
-import Data.Function (on)
-import Control.Arrow ((&&&), first, second)
+import           Control.Arrow                            ((&&&))
+import           Data.Function                            (on)
+import           Data.List                                (genericDrop,
+                                                           genericIndex,
+                                                           genericReplicate,
+                                                           groupBy, sort)
+import qualified Data.Map                                 as M
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase hiding (cycle)
+import           PreludeBase                              hiding (cycle)
 #endif
 
 -- | An interpretation of species expressions as cycle index series.
@@ -65,6 +66,8 @@
 
   cycle      = ciFromMonomials . concatMap cycleMonomials $ [1..]
 
+  bracelet   = ciFromMonomials . concatMap braceletMonomials $ [1..]
+
   o          = liftCI2 MVP.compose
 
   (><)       = liftCI2 . MVP.lift2 $ hadamard
@@ -112,7 +115,7 @@
 intPartitions n = intPartitions' n n
   where intPartitions' :: Integer -> Integer -> [[(Integer,Integer)]]
         intPartitions' 0 _ = [[]]
-        intPartitions' n 0 = []
+        intPartitions' _ 0 = []
         intPartitions' n k =
           [ if (j == 0) then js else (k,j):js
             | j <- reverse [0..n `div` k]
@@ -127,6 +130,26 @@
         cycleMonomial d = Monomial.Cons (FQ.eulerPhi (n' / d) % n)
                                         (M.singleton (n `div` (toInteger d)) (toInteger d))
 
+-- | @braceletMonomials d@ generates all monomials of partition degree
+--   @d@ in the cycle index series for the species B of bracelets.
+braceletMonomials :: Integer -> [Monomial.T Rational]
+braceletMonomials 1 = [ Monomial.Cons 1 (M.singleton 1 1)]
+braceletMonomials 2 = [ Monomial.Cons (1%2) (M.singleton 2 1)
+                      , Monomial.Cons (1%2) (M.singleton 1 2)
+                      ]
+braceletMonomials n = sort $ flips : map rotations ds
+  where n' = fromIntegral n
+        ds = sort . FQ.divisors $ n'
+        rotations k
+          = Monomial.Cons
+              ((FQ.eulerPhi k + (if kI == 2 then n `div` kI else 0)) % (2*n))
+              (M.singleton kI (n `div` kI))
+          where
+            kI = toInteger k
+        flips
+          | odd n     = Monomial.Cons (1 % 2) (M.fromList [(1,1), (2, n `div` 2)])
+          | otherwise = Monomial.Cons (1 % 4) (M.fromList [(1,2), (2, n `div` 2 - 1)])
+
 -- | Convert a cycle index series to an exponential generating
 --   function:  F(x) = Z_F(x,0,0,0,...).
 zToEGF :: CycleIndex -> EGF
@@ -266,6 +289,6 @@
         truncToPartitionOf _ 0 = []
         truncToPartitionOf p n = map snd $ takeUntil ((>=n) . fst) partials
           where partials = zip (tail $ scanl (\soFar cyc -> soFar + uncurry (*) cyc) 0 p) p
-                takeUntil p [] = []
+                takeUntil _ [] = []
                 takeUntil p (x:xs) | p x = [x]
                                    | otherwise = x : takeUntil p xs
diff --git a/Math/Combinatorics/Species/Enumerate.hs b/Math/Combinatorics/Species/Enumerate.hs
--- a/Math/Combinatorics/Species/Enumerate.hs
+++ b/Math/Combinatorics/Species/Enumerate.hs
@@ -1,13 +1,12 @@
-{-# LANGUAGE NoImplicitPrelude
-           , CPP
-           , GADTs
-           , FlexibleContexts
-           , ScopedTypeVariables
-           , KindSignatures
-           , TypeFamilies
-           , DeriveDataTypeable
-           , TypeOperators
-  #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DeriveDataTypeable  #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE GADTs               #-}
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies        #-}
+{-# LANGUAGE TypeOperators       #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -48,21 +47,19 @@
 
     ) where
 
-import Math.Combinatorics.Species.Class
-import Math.Combinatorics.Species.Types
-import Math.Combinatorics.Species.AST
-import Math.Combinatorics.Species.Structures
+import           Math.Combinatorics.Species.AST
+import           Math.Combinatorics.Species.Structures
 import qualified Math.Combinatorics.Species.Util.Interval as I
 
-import qualified Math.Combinatorics.Multiset as MS
-import Math.Combinatorics.Multiset (Multiset(..), (+:))
+import           Math.Combinatorics.Multiset              (Multiset (..), (+:))
+import qualified Math.Combinatorics.Multiset              as MS
 
-import Data.Typeable
+import           Data.Typeable
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase hiding (cycle)
+import           PreludeBase                              hiding (cycle)
 #endif
 
 -- | Given an AST describing a species, with a phantom type parameter
@@ -93,10 +90,11 @@
 enumerate' TOne _                = []
 enumerate' (TN n) (MS [])        = map Const [1..n]
 enumerate' (TN _) _              = []
-enumerate' TX (MS [(x,1)])       = [Id x]
+enumerate' TX (MS [(a,1)])       = [Id a]
 enumerate' TX _                  = []
 enumerate' TE xs                 = [Set (MS.toList xs)]
 enumerate' TC m                  = map Cycle (MS.cycles m)
+enumerate' TB m                  = map Bracelet (MS.bracelets m)
 enumerate' TL xs                 = MS.permutations xs
 enumerate' TSubset xs            = map (Set . MS.toList . fst) (MS.splits xs)
 enumerate' (TKSubset k) xs       = map (Set . MS.toList)
@@ -122,7 +120,7 @@
                                    , xs' <- MS.sequenceMS . fmap (enumerate' (stripI g)) $ p
                                    , y   <- enumerate' (stripI f) xs'
                                    ]
-enumerate' (f :><:: g) xs
+enumerate' (_ :><:: _) xs
   | any (/= 1) $ MS.getCounts xs
   = error "Unlabeled enumeration does not (yet) work with cartesian product."
 enumerate' (f :><:: g) xs        = [ x :*: y
@@ -130,7 +128,7 @@
                                    , y <- enumerate' (stripI g) xs
                                    ]
 
-enumerate' (f :@:: g) xs
+enumerate' (_ :@:: _) xs
   | any (/= 1) $ MS.getCounts xs
   = error "Unlabeled enumeration does not (yet) work with functor composition."
 enumerate' (f :@:: g) xs         = map Comp
@@ -141,7 +139,7 @@
 enumerate' (TDer f) xs           = map Comp
                                    . enumerate' (stripI f)
                                    $ (Star,1) +: fmap Original xs
-enumerate' (TNonEmpty f) (MS []) = []
+enumerate' (TNonEmpty _) (MS []) = []
 enumerate' (TNonEmpty f) xs      = enumerate' (stripI f) xs
 enumerate' (TRec f) xs           = map Mu $ enumerate' (apply f (TRec f)) xs
 enumerate' (TOfSize f p) xs
@@ -420,6 +418,10 @@
 
 instance Enumerable Cycle where
   type StructTy Cycle = Cycle
+  iso = id
+
+instance Enumerable Bracelet where
+  type StructTy Bracelet = Bracelet
   iso = id
 
 instance Enumerable Set where
diff --git a/Math/Combinatorics/Species/Labeled.hs b/Math/Combinatorics/Species/Labeled.hs
--- a/Math/Combinatorics/Species/Labeled.hs
+++ b/Math/Combinatorics/Species/Labeled.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , CPP
-           , GeneralizedNewtypeDeriving
-           , PatternGuards
-  #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoImplicitPrelude          #-}
+{-# LANGUAGE PatternGuards              #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -28,20 +27,18 @@
 -- zipping/unzipping with factorial denominators as necessary, which
 -- is the current approach.
 
-import Math.Combinatorics.Species.Types
-import Math.Combinatorics.Species.Class
+import           Math.Combinatorics.Species.Class
+import           Math.Combinatorics.Species.Types
 
-import Math.Combinatorics.Species.AST
-import Math.Combinatorics.Species.AST.Instances
-import Math.Combinatorics.Species.NewtonRaphson
+import           Math.Combinatorics.Species.NewtonRaphson
 
-import qualified MathObj.PowerSeries as PS
-import qualified MathObj.FactoredRational as FQ
+import qualified MathObj.FactoredRational                 as FQ
+import qualified MathObj.PowerSeries                      as PS
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase hiding (cycle)
+import           PreludeBase                              hiding (cycle)
 #endif
 
 facts :: [Integer]
@@ -51,18 +48,18 @@
   singleton  = egfFromCoeffs [0,1]
   set        = egfFromCoeffs (map (1%) facts)
   cycle      = egfFromCoeffs (0 : map (1%) [1..])
+  bracelet   = egfFromCoeffs (0 : 1 : 1%2 : map (1%) [6, 8 ..])
   o          = liftEGF2 PS.compose
   (><)       = liftEGF2 . PS.lift2 $ \xs ys ->
-                 zipWith3 mult xs ys (map fromIntegral facts)
-                   where mult x y z = x * y * z
+                 zipWith3 (\a b c -> a*b*c) xs ys (map fromIntegral facts)
   (@@)       = liftEGF2 . PS.lift2 $ \fs gs ->
                  map (\(n,gn) -> let gn' = numerator $ gn
                                  in  (fs `safeIndex` gn') *
                                      toRational (FQ.factorial gn' / FQ.factorial n))
                      (zip [0..] $ zipWith (*) (map fromIntegral facts) gs)
     where safeIndex [] _     = 0
-          safeIndex (x:_)  0 = x
-          safeIndex (_:xs) n = safeIndex xs (n-1)
+          safeIndex (a:_)  0 = a
+          safeIndex (_:as) n = safeIndex as (n-1)
 
   ofSize s p        = (liftEGF . PS.lift1 $ filterCoeffs p) s
   ofSizeExactly s n = (liftEGF . PS.lift1 $ selectIndex n) s
diff --git a/Math/Combinatorics/Species/Structures.hs b/Math/Combinatorics/Species/Structures.hs
--- a/Math/Combinatorics/Species/Structures.hs
+++ b/Math/Combinatorics/Species/Structures.hs
@@ -1,12 +1,11 @@
-{-# LANGUAGE NoImplicitPrelude
-           , CPP
-           , GeneralizedNewtypeDeriving
-           , FlexibleContexts
-           , DeriveDataTypeable
-           , TypeFamilies
-           , EmptyDataDecls
-           , TypeOperators
-  #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE EmptyDataDecls             #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE NoImplicitPrelude          #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE TypeOperators              #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -33,6 +32,7 @@
     , (:*:)(..)
     , (:.:)(..)
     , Cycle(..)
+    , Bracelet(..)
     , Set(..)
     , Star(..)
 
@@ -40,14 +40,14 @@
 
     ) where
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase
+import           PreludeBase
 #endif
-import Data.List (intercalate, foldl', delete, inits, tails)
+import           Data.List      (delete, foldl', inits, intercalate, tails)
 
-import Data.Typeable
+import           Data.Typeable
 
 --------------------------------------------------------------------------------
 --  Structure functors  --------------------------------------------------------
@@ -151,8 +151,20 @@
   show (Cycle xs) = "<" ++ intercalate "," (map show xs) ++ ">"
 instance Eq a => Eq (Cycle a) where
   Cycle xs == Cycle ys = any (==ys) (rotations xs)
-    where rotations xs = zipWith (++)  (tails xs)
-                                       (inits xs)
+    where rotations zs = zipWith (++)  (tails zs)
+                                       (inits zs)
+
+-- | Bracelet structure.  A value of type @'Bracelet' a@ is implemented as
+--   @[a]@, but thought of as an undirected cycle (i.e. equivalent up
+--   to rotations as well as flips/reversals).
+newtype Bracelet a = Bracelet { getBracelet :: [a] }
+  deriving (Functor, Typeable)
+instance (Show a) => Show (Bracelet a) where
+  show (Bracelet xs) = "<<" ++ intercalate "," (map show xs) ++ ">>"
+instance Eq a => Eq (Bracelet a) where
+  Bracelet xs == Bracelet ys = any (==ys) (rotations xs ++ rotations (reverse xs))
+    where rotations zs = zipWith (++)  (tails zs)
+                                       (inits zs)
 
 -- | Set structure.  A value of type @'Set' a@ is implemented as @[a]@,
 --   but thought of as an unordered set.
diff --git a/Math/Combinatorics/Species/Unlabeled.hs b/Math/Combinatorics/Species/Unlabeled.hs
--- a/Math/Combinatorics/Species/Unlabeled.hs
+++ b/Math/Combinatorics/Species/Unlabeled.hs
@@ -15,21 +15,21 @@
 module Math.Combinatorics.Species.Unlabeled
     ( unlabeled, unlabelled ) where
 
-import Math.Combinatorics.Species.Types
-import Math.Combinatorics.Species.Class
-import Math.Combinatorics.Species.AST
-import Math.Combinatorics.Species.AST.Instances (reflect)
-import Math.Combinatorics.Species.CycleIndex
-import Math.Combinatorics.Species.NewtonRaphson
+import           Math.Combinatorics.Species.AST
+import           Math.Combinatorics.Species.AST.Instances (reflect)
+import           Math.Combinatorics.Species.Class
+import           Math.Combinatorics.Species.CycleIndex
+import           Math.Combinatorics.Species.NewtonRaphson
+import           Math.Combinatorics.Species.Types
 
-import qualified MathObj.PowerSeries as PS
+import qualified MathObj.PowerSeries                      as PS
 
-import qualified Algebra.Differential as Differential
+import qualified Algebra.Differential                     as Differential
 
-import NumericPrelude
+import           NumericPrelude
 #if MIN_VERSION_numeric_prelude(0,2,0)
 #else
-import PreludeBase hiding (cycle)
+import           PreludeBase                              hiding (cycle)
 #endif
 
 ciErr :: String -> a
@@ -42,6 +42,7 @@
   singleton         = gfFromCoeffs [0,1]
   set               = gfFromCoeffs (repeat 1)
   cycle             = set
+  bracelet          = set
   o                 = ciErr "composition"
   (><)              = ciErr "cartesian product"
   (@@)              = ciErr "functor composition"
diff --git a/species.cabal b/species.cabal
--- a/species.cabal
+++ b/species.cabal
@@ -1,5 +1,5 @@
 name:           species
-version:        0.3.2.4
+version:        0.3.3
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
@@ -24,7 +24,7 @@
                  numeric-prelude >= 0.3 && < 0.5,
                  np-extras >= 0.3 && < 0.4,
                  containers >= 0.2 && < 0.6,
-                 multiset-comb >= 0.2.3 && < 0.3,
+                 multiset-comb >= 0.2.4 && < 0.3,
                  template-haskell >= 2.7 && < 3.0
   exposed-modules:
     Math.Combinatorics.Species
