- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
import Text.Parsec
import Control.Monad
romanToArabic :: String -> Either ParseError Integer
romanToArabic = parse (genParser (Nothing : Nothing : map Just romans)) "" where
romans = [('M', 1000), ('D', 500), ('C', 100),
('L', 50), ('X', 10), ('V', 5), ('I', 1)]
genParser [_] = eof >> return 0
genParser (ten : five : one : rest) = state1 where
state1 = choice [on one state2, on five state3, next]
state2 = choice [on (sub2 five one) next, on (sub2 ten one) next,
on one state5, next]
state3 = choice [on one state4, next]
state4 = choice [on one state5, next]
state5 = choice [on one next, next]
next = genParser (one : rest)
on Nothing _ = fail ""
on (Just (ch, val)) nextNode = char ch >> nextNode >>= return . (+val)
sub2 = liftM2 $ \(ch1, val1) (ch2, val2) -> (ch1, val1-2*val2)