ポーランド記法の電卓のパーサをHaskellで書いた
9月といえど、まだまだ外は暑いですね。
子どもたちが公園で遊んでる声で起きました。まだ夏な気がします。
Haskellを初めて触ってみました。
超初心者。関数型言語も。
詳細な書き方の理解は全くなく、
イロイロなものを組み合わせてだんだん動くようになったから
生意気にもブログを書いてる感じです(`・∀・´)エッヘン!!
なので、細かい技術の話は、参考文献の方々のモノを読んでくださいね( ・∀・)ノ
とりあえずソース
daigorowhite/PNDentaku · GitHub
{-# LANGUAGE OverloadedStrings #-} import Control.Applicative import Data.Text(pack) import Data.Char (ord) import Data.Attoparsec.Text import Data.Attoparsec.Number import System.Environment (getArgs) -- Exp型?の定義 data Exp = Add Exp Exp | Sub Exp Exp | Mul Exp Exp | Div Exp Exp | Nat Int deriving Show -- プログラムの文法 1つ以上の式 prog = many1 expr -- 式の文法 足し算、引き算、掛け算、割り算、数字のどれか expr :: Parser Exp expr = add <|> sub <|> mul <|> divi <|> num -- 足し算の文法 "(+ EXP EXP)" add :: Parser Exp add = Add <$> ("(" *> ("+" *> (spaces *> expr))) <* spaces <*> expr <* spaces <* ")" -- (中略) -- 同じように引き算、掛け算、割り算を書く -- 数字の文法 "Num" num :: Parser Exp num = Nat . read <$> many1 digit -- 複数のスペースの文法 spaces = many space -- 引数をパースして出力する main :: IO () main = do args <- getArgs; print $ parseOnly prog $ pack $ concat args
技術的に
- Attoparsecというものを使ってパーサを書いてる
- 記法を簡単にするために、Applicativeというものを使っている
じゃあ、やってみよう
とりあえずコンパイルする
% ghc dentaku.hs [1 of 1] Compiling Main ( dentaku.hs, dentaku.o ) Linking dentaku ...
実行ファイル( dentaku )ができるので
これを使ってパースしてみる
% ./dentaku "(+ 1 1)" Right [Add (Nat 1) (Nat 1)]
できたー。
Addが自然数1を2つ持ってる。
後は、ロジックを実装すれば、立派な計算機として動きます。
時間あれば、+の部分を関数名にして、
ロジックで足し算とか分けていけたら、Lisp系の言語ができそう。
haskellの感想
- そもそもhaskellの文法を理解しないとだめだなー
- letとか、関数渡しとか、オブジェクト脳には、何がなんやら。
- 全体的に、なんか、動いた。。。ってことが多い(初心者すぐる)
- とはいえ、よく知ってる言語よりも動いたらうれしー。(よその猫が膝に乗ってきた感じ
次はちゃんと、haskellの書き方を理解しよう(゚д゚)!
インスピレーション受けたやつ
様々な、人とブログと勉強会から刺激を受けています。
スペシャルサンクス
- 発表をしていた@fujiyan18さん
https://gist.github.com/fujiyan/e1b58d3d447843509477
- その勉強会を企画した@kazuhito_mには特に感謝っす。
- プログラム中に僕を支えたハンモック
- 居心地がよく集中力を来れた。グランフロントのCafe.Lab.