The following is an exercise in refactoring to remove code duplication. The implementation language is Scala. How would you solve it?
| object RefactorPuzzle { | |
| case class IntRdr[+A](read: Int => A) { | |
| def map[B](f: A => B): IntRdr[B] = | |
| IntRdr(f compose read) | |
| def flatMap[B](f: A => IntRdr[B]): IntRdr[B] = | |
| IntRdr(n => f(read(n)).read(n)) | |
| } | |
| object IntRdr { | |
| def apply[A](a: A): IntRdr[A] = | |
| IntRdr(_ => a) | |
| } | |
| // Return all the Some values, or None if not all are Some. | |
| def runOptions[A](x: List[Option[A]]): Option[List[A]] = | |
| x.foldRight[Option[List[A]]](Option(Nil))((a, b) => a.flatMap(aa => b.map(aa :: _))) | |
| // Apply an Int to a list of int readers and return the list of return values. | |
| def runIntRdrs[A](x: List[IntRdr[A]]): IntRdr[List[A]] = | |
| x.foldRight[IntRdr[List[A]]](IntRdr(Nil))((a, b) => a.flatMap(aa => b.map(aa :: _))) | |
| /* | |
| ======================== | |
| THE REFACTORING PUZZLE | |
| ======================== | |
| The two functions `runOptions` and `runIntRdrs` share a lot of duplicated code. | |
| This is demonstrated below. | |
| How to refactor this code to remove the code duplication? | |
| */ | |
| //------- ------------- ------- ----------- | |
| //def runOptions[A](x: List[Option[A]]): Option[List[A]] = | |
| //def runIntRdrs[A](x: List[IntRdr[A]]): IntRdr[List[A]] = | |
| // ------------ ----------- ------------------------------------------------- | |
| // x.foldRight[Option[List[A]]](Option(Nil))((a, b) => a.flatMap(aa => b.map(aa :: _))) | |
| // x.foldRight[IntRdr[List[A]]](IntRdr(Nil))((a, b) => a.flatMap(aa => b.map(aa :: _))) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment