I started to teach myself Haskell recently. Here is some code I wrote to convert a roman numeral into an arabic numeral:
import Control.Arrow ((>>>)) import Data.Maybe (fromJust) fromRoman :: String -> Int fromRoman = translateFromRoman >>> applyNegationRule >>> sum translateFromRoman :: String -> [Int] translateFromRoman = map (\r -> fromJust $ lookup r [('I',1),('V',5),('X',10),('L',50),('C',100),('D',500),('M',1000)]) applyNegationRule :: [Int] -> [Int] applyNegationRule [x] = [x] applyNegationRule (x:y:xs) = (if x < y then -x else x) : applyNegationRule (y:xs)
I like it quite a bit. But some questions remain. First of all I never (at least I can't remember) came across (>>>) in other code so far. Everyone seems to use:
fromRoman :: String -> Int fromRoman = sum . applyNegationRule . translateFromRoman
It produces the same output, but for me as someone used to read from top left to bottom right the first variant is just more readable. You could also write it like this:
fromRoman :: String -> Int fromRoman = translateFromRoman >>> applyNegationRule >>> sum
To make it even more text like readable. So where's the catch?
Another question arising from this code is: Should I define the functions
fromRoman ... where? Again I see it quite a lot but IMHO it also lacks readability. At the moment readability is one of the most important metrics for me to determine code quality.
And last but note least: Am I doing something bad in
applyNegationRule or are there some better (faster/shorter or ofcourse more readable) alternatives?