"Write Yourself a Scheme in 48 Hours/Parsing" http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing を読む

Parsingの後半の練習問題を解く。

Excercise 3 Instead of using the try combinator, left-factor the grammar so that the common subsequence is its own parser.

リストもしくはドットリストをパースするところは、tryコンビネータを使って

do char '('
    x <- (try parseList) <|> parseDottedList
    char ')'
    return x

のようになっている。ここの部分を、tryコンビネータを使わずに書き直せ、という問題っぽい。
かなり手間取った。ラーメン食べて喫茶店よってから帰ってきて、もう一度今やってみたら、なんとかできたっぽい。ほんとにできてるかな?

do char '('
    x <- myparseList
    char ')'
    return x

myparseList = 
    do {
        x <- parseExpr;
        (spaces >> do{
            y <- myparseAList;
            return $ pac x y;
        }) <|> (return x);
    }<|> return (List )

myparseAList = do{ 
    tail <- char '.' >> spaces >> parseExpr;
    return $ DottedList  tail;
    } <|> do {
    x <- parseExpr;
    do {
        _ <- spaces;
        y <- myparseAList;
        return $pac x y;
        } <|> return (List [x]);
    };
    
pac x (DottedList head tail) = (DottedList (x:head) tail)
pac x (List xs) = List (x:xs)

とにかく長いし汚い。が、今日は眠いのでここらへんで勘弁してやる。
勘弁してください。むにゃむにゃ。。。