13,557,606 members
Tip/Trick
Add your own
alternative version

#### Stats

5.8K views
1 bookmarked
Posted 23 Jun 2014
Licenced CPOL

# Arabic-Roman Number Converter in Haskell (Part 2: Converting Roman to Arabic Numbers)

, 24 Jun 2014
Arabic-Roman Number Converter in Haskell (Part 2: Converting Roman to Arabic Numbers)

## Introduction

This is the second part of my previous tip for converting arabic to roman numbers (see Arabic-Roman number converter part 1 for the first part).

In this part I want to add the missing part for the conversion of roman to arabic numbers.

## Background

In a recent coding dojo in my company, we worked on creating a JavaScript function to convert Arabic numbers to Roman numbers (Original task: http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals).

To refresh my functional programming skills, I decided to write a solution for the problem in Haskell.

## Using the code

Converting roman to arabic numbers turned out to be alot easier than expected. At first I created a list of the roman characters and the corresponding arabic numerals (similar to the previous article). This list is used as basis for the calculation.

In the romanToNum function I decided to handle three different cases for the input string: If it is empty, return 0, if the length is equal to 1 return the corresponding integer (e.g. "V" -> 5).

Otherwise we have to examine the remaining characters. Here comes the part which is a bit tricky: We have to decide whether to add the values of the next to roman characters (e.g. "II", "CX", "XV") or whether we have to use the subtraction rule (e.g. "IV", "CM", "XC"). We can see, that if the second character is greater than the first one, we have to use subtraction rule (as V > I), otherwise addition.

So, depending on which rule we have to use, we either add or subtract the current value from the remaining part of the roman number, which is represented in tl (which recursiveley calls romanToNum).

```arabics :: Map Char Int
arabics = fromList [('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)]

romanToNum :: [Char] -> Int
romanToNum xs = if (length xs == 0) then 0
else if (length xs == 1) then arabics ! (head xs)
else
let fst = arabics ! (xs !! 0)
snd = arabics ! (xs !! 1)
tl = romanToNum (tail xs)
in if (fst < snd) then tl - fst else tl + fst```

## Points of Interest

NOTE: 'Wrong' roman literals will result in incorrect arabic numbers. There is no logic to detect special cases so only use correct roman literals!

I added the (now complete) NumberConverter.hs module to the article, so you can test both conversions yourself.

After some tinkering, I am glad I could find such a small solution. Remember, I am no Haskell expert. Again, feel free to leave any hints or questions about the code.

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Software Developer (Senior) Germany
Hi there 🙂
My name is Philipp Engelmann, I work as a web developer at FIO SYSTEMS AG in Leipzig. I am interested in C#, Python, (REST-)API-Design, software architecture, algorithms and AI. Check out my blog at https://cheesyprogrammer.com/

## Comments and Discussions

 -- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01-2016 | 2.8.180515.1 | Last Updated 24 Jun 2014
Article Copyright 2014 by Philipp_Engelmann
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid