Skip to content

Instantly share code, notes, and snippets.

@davidallsopp
Last active December 23, 2015 23:39
Show Gist options
  • Save davidallsopp/6711935 to your computer and use it in GitHub Desktop.
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…
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