This is from the book Get Programming with Haskell
import Data.Semigroup
data Color = Red |
Yellow |
Blue |
Green |
Purple |
Orange |
Brown deriving (Show,Eq)
This is the first implementation of Semigroup Color. The author said it is “non-associative”:
instance Semigroup Color where
(<>) Red Blue = Purple
(<>) Blue Red = Purple
(<>) Yellow Blue = Green
(<>) Blue Yellow = Green
(<>) Yellow Red = Orange
(<>) Red Yellow = Orange
(<>) a b = if a == b
then a
else Brown
This implementation is said to be associative:
instance Semigroup Color where
(<>) Red Blue = Purple
(<>) Blue Red = Purple
(<>) Yellow Blue = Green
(<>) Blue Yellow = Green
(<>) Yellow Red = Orange
(<>) Red Yellow = Orange
(<>) a b | a == b = a
| all (`elem` [Red,Blue,Purple]) [a,b] = Purple
| all (`elem` [Blue,Yellow,Green]) [a,b] = Green
| all (`elem` [Red,Yellow,Orange]) [a,b] = Orange
| otherwise = Brown
Example usage:
First implementation
> (Green <> Blue) <> Yellow
-- Brown
Second implementation
> (Green <> Blue) <> Yellow returns Green
-- Green
It looks to me like the second implementation is just ignoring the 3rd argument and that isn’t really “associative”.
Is it ignoring the 3rd argument?
I don’t see anything that evaluates 3 colors. Even the last (<>)
only has a b
, not a b c
and then check if both a
and b
are in in one of the lists in the guards.