- 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)
>>= - извлечь результат I/O action'а, передать дальше
>> - тоже что и >>=, но результат игнорируется
Приоритет выше у композиции ф-ций.
Тогда я пас, я не могу разгадать, что тут написано :)
1. (+ ("char ch" ("return" ("Just" (x y)))) y)
2. (+ ("return" ("char ch" ("Just" (x y)))) y)
спайдермен.
Кстати, состояние, изменяемое putState, доступно в течении всей работы парсера?
Да, состояние доступно везде: там runP применяется и начальное 0 передается - не очень хорошо :).
С другой стороны "парсить не больше 3" сводится к "небольше 2" - можно и переписать.
Может просто переписать дле строчки с on в одно 4-строчное определение? :
do let Just .. = .. ; .. ; .. <- nextCode ; return ..
parseBormand