Relationships.
Friend: Given two people, a friend relationship follows these general laws
- Have good will towards each other
- Thinks each other are a friend to them (so the laws must be fulfilled by both members in this relationship)
- Enjoys spending time with each other
Monoid: Given multiple items and a function that takes 2 of the items and returns 1, a monoidal relationship follows these general laws
- There is one of those items (only one, called identity) which passed to the function with any other item will ensure the function always returns the other item (0 + 1 = 1, thus 0 is the identity when the items are numbers and the function is addition)
- The function cannot operate on or return items not in the set it has a monoidal relationship with
- The function is associative and can be used with the items in a somewhat order independent manner, this means a * (b * c) = (a * b) * c which says you can multiply a by the result of b*c or c by the result of a*b and the result will be the same whichever you do first.
Functional programming is all about generalizations, friend is a very general relationship that can be seen in numerous scenarios, but in all various formats it generally follows the laws above.
Recognizing the laws that governs the relationships between things, you can create general implementations that work on any format of things that has that type of relationship. In functional programming you try to identify the relationships between things so that they can be classified and treated generally.
You want a metaphor from the real world? Look at how things are related and try to identify general laws (as in applicable to multiple scenarios where things other than the laws may vary). There is a relationship between a register clerk and a shopper at a store, it has some general laws, software has been developed to facilitate the goals of people in that general relationship in the way of POS systems. Similarly when you start seeing these general laws dictating how things are related, you can start relying on the laws of those relationships in writing your software rather than the specific particulars of an instance of a relationship.