Jonathan
Jonathan

Reputation: 11321

How can I parse roman numerals in Haskell's Parsec?

I'm a Haskell beginner, and I'm trying to learn about Parsec by writing a parser that can consume either an arabic numeral, like "234," or a roman one, like "MCMLXIX." I found the library roman-numerals, and so I figured I'd try to use the fromRoman function somehow, in conjunction with Parsec, since I'll eventually need to get the arabic equivalent of the roman numeral. But I just don't quite yet know how to coerce the Maybe output of fromRoman into a Parser. This is what I have so far:

import Text.Parsec
import Text.Parsec.Text (Parser)
import Text.Numeral.Roman

arabicNum :: Parser Int
arabicNum = do
  n <- many1 digit
  return (read n)

isChapter :: Inline -> Bool
isChapter str = str == Str "CHAPTER"

number :: Parser Int
number = arabicNum <|> romanNum

romanNum :: Parser Int
romanNum = do
  str <- many1 char
  return case (fromRoman str) of
    Just n -> n
    Nothing -> Nothing

But, no dice, since I don't quite yet know what I'm doing.

Upvotes: 4

Views: 164

Answers (1)

that other guy
that other guy

Reputation: 123410

If your Maybe is Nothing, you can fail to generate a parser error. If it's something, you can return it:

romanNum :: Parser Int
romanNum = do
  str <- many1 $ oneOf "MDCLXVI"
  case fromRoman str of
    Just n -> return n
    Nothing -> fail $ str ++ " is not a valid roman numeral"

Upvotes: 5

Related Questions