As an excercise to "Haskell: The Craft of Functional Programming", I created some code to convert an Integer to Roman numerals.
This is the first version and I think I'm probably not doing it in the "Haskell way" since my background is in imperative programming.
Any advice on how to improve this? Sometimes I think I'm missing a obvious way to do it in just one function.
convMap = [(1000,"M"), (900,"CM"), (500,"D"), (400,"CD"), (100,"C"),
(90,"XC"), (50,"L"), (40,"XL"), (10,"X"), (9,"IX"), (5,"V"),
(4,"IV"), (1,"I")]
toRoman :: Integer -> String
toRoman x
| x == 0 = "N"
| otherwise = (snd . numToSubtract $ x) ++ toRoman'(nextNum)
where nextNum = x - (fst. numToSubtract $ x)
-- Auxiliary function just so we treat 0 differently
-- (avoids 3 == "IIIN" if not used)
toRoman' :: Integer -> String
toRoman' x
| x == 0 = ""
| x > 0 = (snd . numToSubtract $ x) ++ toRoman'(nextNum)
where nextNum = x - (fst. numToSubtract $ x)
-- Returns which item in the convMap should be subtracted
numToSubtract :: Integer -> (Integer, String)
numToSubtract x = head (filter (lessThan x) convMap)
-- Filter function to work on the tuples in convMap
lessThan :: Integer -> (Integer, String) -> Bool
lessThan n (a, b)
| a <= n = True
| otherwise = False