 -- Technically it might make better sense to make the second argument a Set rather than a list
 -- but the order is significant in the groupIncl function (the other function, not this one).
 -- For the sake of keeping their types in sync, a list is used instead.
+{- | Create a new @Group@ from the given one. Exclude processes
+with given @Rank@s from the new @Group@. Processes in new @Group@ will
+have ranks @[0...]@.
+-}
 {# fun unsafe Group_excl as ^
                {fromGroup `Group', withRanksAsInts* `[Rank]'&, alloca- `Group' peekGroup*} -> `()' checkError*- #}
+{- | Create a new @Group@ from the given one. Include only processes
+with given @Rank@s in the new @Group@. Processes in new @Group@ will
+have ranks @[0...]@.
+-}
 {# fun unsafe Group_incl as ^
                {fromGroup `Group', withRanksAsInts* `[Rank]'&, alloca- `Group' peekGroup*} -> `()' checkError*- #}
 
+{- | Given two @Group@s and list of @Rank@s of some processes in the
+first @Group@, return @Rank@s of those processes in the second
+@Group@. If there are no corresponding @Rank@ in the second @Group@,
+'mpiUndefined' is returned.
+
+This function is important for determining the relative numbering of the same processes
+in two different groups. For instance, if one knows the ranks of certain processes in the group
+of 'commWorld', one might want to know their ranks in a subset of that group.
+Note that 'procNull' is a valid rank for input to @groupTranslateRanks@, which
+returns 'procNull' as the translated rank.
+-}
 groupTranslateRanks :: Group -> [Rank] -> Group -> [Rank]
 groupTranslateRanks group1 ranks group2 =
    unsafePerformIO $ do

* If both communicators are identical in constituents and rank
    order, result is `Congruent';

* If they have the same members, nbut with different ranks, then
    result is 'Similar';

* Otherwise, result is 'Unequal'.


withRanksAsInts ranks f = withArrayLen (map fromEnum ranks) $ \size ptr -> f (cIntConv size, castPtr ptr)

-- | Return the number of bytes used to store an MPI @Datatype@.
typeSize :: Datatype -> Int
typeSize = unsafePerformIO . typeSize'
  where
    typeSize' =
