0

Repeating the books until I am sure to get it right. Got this in the Haskell Cookbook:

data Option = Option { boolOption :: Bool, selections :: [String] }
            deriving Show
instance Monoid Option where
        mempty = Option False []
       (Option b1 s1) `mappend` (Option b2 s2) = Option (b1 || b2) (s1 ++ s2)

Got this from compiler:

error:
    • No instance for (Semigroup Option)
        arising from the superclasses of an instance declaration
    • In the instance declaration for ‘Monoid Option’
    |
116 | instance Monoid Option where 
    |          ^^^^^^^^^^^^^
Failed, no modules loaded.

Is the book wrong or outdated here? Does Option also need to be an instance of Semigroup?

Madderote
  • 1,107
  • 10
  • 19
  • If I make `Option` an instance of Semigroup without explicit implementation it compiles with warnings. So first part answered, new question: can I avoid making `Option` an instance of `Semigroup` or at least make the process a little easier? Here the lack of profound knowledge rears its head. – Madderote Mar 06 '19 at 17:55
  • 1
    No, you can't. You have to give an instance of `Semigroup` – Fyodor Soikin Mar 06 '19 at 17:57
  • 1
    And also, you don't need to implement `mappend` now, it's been moved to `Semigroup`, which is why it's required. The book was probably written before the move (which is as of GHC 8.4) – Fyodor Soikin Mar 06 '19 at 17:59
  • @tgrez: if I implement `mempty` in the Monoid instance and move `mappend` to the `Semigroup` instance and change it to `<>` it compiles and works fine, but I don't get the logic of it anymore. Shouldn't `mempty` have a `Semigroup` equivalent as well then? – Madderote Mar 06 '19 at 18:13
  • @FyodorSoikin: You pointed out the direction, so thanks for that. – Madderote Mar 06 '19 at 18:14
  • 1
    `Monoid` has `mempty`, and not `Semigroup`, as `Monoid` is more restrictive than `Semigroup`. – Bob Dalgleish Mar 06 '19 at 18:21
  • @Bob Dalgeleish: that I found out, but how to make the instance, if my type needs to rely on two different typeclasses that are also related in terms of super and sub classes.... – Madderote Mar 06 '19 at 18:44
  • 3
    Whatever books you are reading were probably written before `Semigroup` became a superclass of `Monoid`. It used to be that `Monoid` defined both `mempty` and `mappend` by itself. Now, `Semigroup` provides `<>` (aka `mappend`), and any class that has a `Monoid` instance must already have a `Semigroup` instance. Further, you can still define `mappend` if you want for backwards compatibility, but its default value `mappend = (<>)` is sufficient. – chepner Mar 06 '19 at 18:49

0 Answers0