第8章 関数型パーサー #7

演習問題

問題7

累乗を定義。

term' :: Parser Int
term'  = pow >>- \p ->
         (symbol "*" >>- \d ->
          term' >>- \t ->
          return' (p * t))
         +++
         (symbol "/" >>- \d ->
          term' >>- \t ->
          return' (p `div` t))
         +++
         return' p

pow :: Parser Int
pow  = factor >>- \f ->
       (symbol "^" >>- \d ->
        pow >>- \p ->
        return' (f ^ p))
       +++
       return' f

問題8

expr ::= expr '-' nat | nat
nat  ::= '0' | '1' | '2' | ...
expr'' :: Parser Int
expr''  = (expr'' >>- \e->
           symbol "-" >>- \d ->
           natural >>- \n ^>
           return' (e - n))
          +++ natural
  1. 再帰なので無限ループになる。 (expr ::= nat | expr '-' nat にしてみたら、減算がパースされなかったので、これではだめ。)

expr'' :: Parser Int
expr''  = natural >>- \n ->
          many (symbol "-" >>- \d -> natural) >>- \ns ->
          return' (foldl (-) n ns)

おー、綺麗に動いた。

まとまった時間が取れないのでちまちましか進まなかったが、やっと第8章が終わった! ※といっても、本物のモナドが教科書で登場したら、また戻ってきて復習するつもりだけど。