すごいHaskellたのしく学んでみる-その7
久々のHaskellです。
前回からの続きは「すごいH本」的にはIOの章なんですが、
この辺よりも、その次の章が面白かったので、
ブログに書くのはやめました。
と、いうわけで、今回のテーマは、、、
- 関数型問題解決法
- 逆ポーランド記法電卓
関数型問題解決法
関数型でなんかプログラム書いてみようぜ、的なノリ・・・?
逆ポーランド記法電卓
これは、初めて知りました。(常識なんでしょうか?)
RPN(reverse polish notation)と呼ばれるそうです。
具体的にどういう記法かというと。。。
通常の式
(1 + 3) * 10 / 2
RPN
1 3 + 10 * 2 /
こうなります。
簡単に言うと、左から順番に評価していき、
[数字][数字][記号]
という並びが出てきたら、計算する。
みたいな感じのようです。
[数字][数字][数字][記号]
だと
[数字]([数字][数字][記号])
こういう評価になります。
ではこの数式をパースして、計算する電卓を書いてみたいと思います。
rpn :: String -> Int rpn = head . foldl func [] . words where func (x:y:ys) "*" = (y * x) : ys func (x:y:ys) "+" = (y + x) : ys func (x:y:ys) "-" = (y - x) : ys func xs numberStr = read numberStr:xs
うん、なんかこんなにもスッキリ書けてしまうんですね。
すげぇ。
最初見た時、なんでyからx引くんだ???
ってなりましたが、
「read numberStr:xs」
なので、逆順に並ぶからでした、、orz
実行してみます。
*Main> rpn "10 4 3 + 2 * -" -4
よし、上手くできているようです。
では、これに演算子を足してみようと思います。
rpn :: String -> Int rpn = head . foldl func [] . words where func (x:y:ys) "*" = (y * x) : ys func (x:y:ys) "+" = (y + x) : ys func (x:y:ys) "-" = (y - x) : ys func (x:y:ys) "/" = (y / x) : ys func (x:y:ys) "^" = (y ** x) : ys func xs numberStr = read numberStr:xs
すごく簡単に演算子を追加できました。
今日はここまでにしようかと思います。
次回はFunctorかな?