Convert roman to arabic 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 ((&gt;&gt;&gt;))
import Data.Maybe (fromJust)

fromRoman :: String -&gt; Int
fromRoman = translateFromRoman &gt;&gt;&gt; applyNegationRule &gt;&gt;&gt; sum

translateFromRoman :: String -&gt; [Int]
translateFromRoman = map (\r -&gt; fromJust $ lookup r [('I',1),('V',5),('X',10),('L',50),('C',100),('D',500),('M',1000)])

applyNegationRule :: [Int] -&gt; [Int]
applyNegationRule [x]      = [x]
applyNegationRule (x:y:xs) = (if x &lt; 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 -&gt; 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 -&gt; Int
fromRoman = translateFromRoman
        &gt;&gt;&gt; applyNegationRule
        &gt;&gt;&gt; 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 translateFromRoman and applyNegationRule in 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 translateFromRoman and applyNegationRule or are there some better (faster/shorter or ofcourse more readable) alternatives?
Since the Roman numerals are fixed and known in advance, it would be more efficient to write:

translateRomanDigit :: Char -&gt; Int
translateRomanDigit 'I' = 1
translateRomanDigit 'V' = 5
...

translateFromRoman = map translateRomanDigit


The compiler can implement translateRomanDigit as a jump table or as a binary search. Using lookup will always perform a linear search.

As for &gt;&gt;&gt; vs . - there should be no difference except that &gt;&gt;&gt; requires you to import Control.Arrow whereas . is provided for in the Prelude.