problem-specifications
problem-specifications copied to clipboard
Exercise Idea: composite-resistors
This exercise is proposed in the context of the Haskell track, but I'm posting it here because I like the idea of sharing exercise ideas across, and monoid abstractions exist in other languages, too. In the process of porting resistor-color-trio in exercism/haskell#869, it occurred to me that resistors are monoids in two ways:
When you put them in series, they form an additive monoid (resistance adds up) with (black, black, black), better known as a wire, as the identity resistor. And when you put them in parallel, you don't exactly get a multiplicative monoid, since n resistors in parallel add up like 1/R = 1/R₁ + 1/R₂ + ... + 1/Rₙ. What's the identity resistor for a parallel circuit?
It isn't a wire, since then the current would follow the path of least resistance, which would always end up being the wire. A neutral resistor in a parallel circuit is any non-conductive material with infinite resistance. For example, my willingness to code in another language than Haskell.
Putting resistors in series and in parallel is neat in practice for making non-standard resistors or when you run out of a certain kind of resistor.
Haskell has some machinery for dealing with types that are monoids in more than one way: while one can define instance Monoid (Sum Resistor) where ...
for the built-in Sum
type, it seems necessary to define one's own Parallel
type and make instance Monoid (Parallel Resistor) where ...
instead.
Having this exercise in succession of resistor-color-trio leads to interesting thoughts:
- The data type
Resistor
is given as a newtype wrapper around(Color, Color, Color)
. - But that means there is no constructor for a resistor with infinite resistance.
- But that means some composite resistors don't have such a representation:
let r50 = Resistor (Green, Black, Black) r1000 = Resistor (Brown, Black, Orange) r1050 = getSum (Sum r50 <> Sum r1000) r1050 == Resistor (???)
- But that's okay, because this representation has another bad property:
(We don't comparelet ten1 = Resistor (Brown, Black, Black) ten2 = Resistor (Black, Brown, Brown) ohms ten1 == ohms ten2 -- True ten1 == ten2 -- False
Resistor
s for equality in -trio, so we live with it there.) - A necessary part of this exercise would then be to refactor the representation of -trio.
- This is an excellent opportunity for property-based tests of monoidal laws.