Last active
December 23, 2015 23:39
-
-
Save davidallsopp/6711935 to your computer and use it in GitHub Desktop.
Converting integers into Roman numerals. An example of defining and using the "unfold" higher-order function in Scala (as an Eclipse Scala Worksheet).Adapted from http://daily-scala.blogspot.co.uk/2009/09/unfoldleft-and-right.html and http://www.scala-blogs.org/2008/01/roman-numerals-in-scala.html for the romanize example. See also Haskell versi…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object unfold { | |
def unfoldRight[A, B](seed: B)(f: B => Option[(A, B)]): List[A] = f(seed) match { | |
case Some((a, b)) => a :: unfoldRight(b)(f) | |
case None => Nil | |
} | |
def unfoldLeft[A, B](seed: B)(f: B => Option[(B, A)]) = { | |
def loop(seed: B)(ls: List[A]): List[A] = f(seed) match { | |
case Some((b, a)) => loop(b)(a :: ls) | |
case None => ls | |
} | |
loop(seed)(Nil) | |
} | |
// Romanize example | |
val numerals = List(("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), ("C", 100), ("XC", 90), | |
("L", 50), ("XL", 40), ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), ("I", 1)) | |
def next(in: Int) = numerals.collectFirst{ case (s, v) if v <= in => (s, in - v) } | |
def romanize(number: Int) = unfoldRight(number)(next).mkString | |
romanize(1984) // MCMLXXXIV |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment