旅行に行ったので間があいてしまった。
数式
相変わらずdo記法を使わずにオレオレbindとオレオレreturnで書いてみる。
expr :: Parser Int expr = term >>- \t -> (symbol "+" >>- \d -> expr >>- \e -> return' (t + e)) +++ return' t term :: Parser Int term = factor >>- \f -> (symbol "*" >>- \d -> term >>- \t -> return' (f * t)) +++ return' f factor :: Parser Int factor = (symbol "(" >>- \d1 -> expr >>- \e -> symbol ")" >>- \d2 -> return' e) +++ natural eval :: String -> Int eval xs = case parse expr xs of [(n,[])] -> n [(_,out)] -> error ("unused input " ++ out) [] -> error "invalid input"
練習問題
問題1
symbol
にしたけどchar
でもよかったな。
int :: Parser Int int = (symbol "-" >>- \d -> natural >>- \n -> return' (-n)) +++ natural
問題2
1行読んで無視するline
を定義してみた。
comment :: Parser () comment = string "--" >>- \d1 -> line where line = item >>- \x -> case x of '\n' -> return' () _ -> line
問題3
1個目
expr _______|___ | | | expr + expr ____|___ | | | | term expr + expr | | | factor term term | | | nat factor factor | | | 4 nat nat | | 2 3
2個目
expr ____|_______ | | | expr + expr | ____|___ term | | | | expr + expr factor | | | term term nat | | | factor factor 2 | | nat nat | | 3 4