Semigroup

A Semigroup has a multiplication operation. The operation must be associative.

This section refers to Data.Semigroup.

A Semigroup a has function called <>. That function’s type is a -> a -> a, so it takes in two things and puts out one. That’s all. This operation could be concatentation of lists or taking the maximum of two numbers.

You should always use a function that is associative. This means if are going to apply the function twice (so x <> y <> z) it doesn’t matter which operation you do first. Familiar operations like addition and multiplication are associative.

You will see people talking big about this function defining a “binary operation”. That’s a lot of vocabulary to explain that the function takes in two things and puts out one.

  1. Write the class declaration for Semigroup a.

  2. Define newtype Prod = Prod Int and make Prod an instance of Semigroup by using multiplication.

  3. Define data XList b = XList [b] and make (XList b) an instance of Semigroup by appending lists.

    Give two examples of variables of type XList Int. Make one simple and one more complicated.

  4. Define newtype Bite = Bite [String]. Consider making this a semigroup using swapped concatentation:

     instance (Semigroup Bite) where
         (Bite xs) <> (Bite ys) = Bite (ys ++ xs)
    
    1. What is (Bite ["Wolf"]) <> (Bite ["Dog"])?

    2. Is the operation <> associative? Evaluate the code below two different ways as a check. State your conclusion.

       (Bite ["A", "Wolf"]) <> (Bite ["Dancer"]) <> (Bite ["Fang"])
      
  1. Define newtype Trouble = Trouble [Int] and consider making this an instance of Semigroup using reversal followed by concatenation:

     instance (Semigroup Trouble) where
         (Trouble xs) <> (Trouble ys) = Trouble $ (reverse xs) ++ (reverse ys)
    
    1. Find (Trouble [1,2,3]) <> (Trouble [4,5,6]).
    2. Is the operation <> associative? Write an example with three lists and evaluate it in two different ways as a check. State your conclusion.

Notes

If you are reading Learn You a Haskell, you will find it has Monoid but not Semigroup. A Monoid is a Semigroup with an identity. This means the Monoid definition adds in mempty but a Semigroup only has the analog of mappend.

Last modified December 5, 2024: Small edits for clarity. (1c0fe52)