昨日の続き。
昨日書いたコードに対して、showをいじってみる。
instance Show Atom where show s = "Hoge"
などとすると、Atom型は常に"Hoge"と表示される。このとき、元々の定義、newtype Atom = Atom String deriving Show
の deriving ... は消しておく。Atomの場合はdataじゃなくてnewtypeで良い。
デストラクタとかデコンストラクタと呼ばれるやつを定義する。こんな感じで。
unAtom :: Atom -> String unAtom (Atom s) = s unMole :: Mole -> [(Int, Atom)] unMole (Mole s) = s
これは、Stringしか受け取らない関数に対してAtom String の形で受け取れるようにするのを避けるため、一旦unAtomしてAtomすればよいみたいな感じでつかう(と思う)。一度読んだはずだが完全に忘れている。
さて、MoleのShowを自分で定義する。最終的にこんな感じになった。最初、show Mole s = ... としていたが、sに対して unAtom $ snd $ head $ unMole s みたいなことをしていたのだが、右辺で分離して受け取るようにすればよかった。何気に再帰であるが、終わりになるやつの書き方で苦労した。型注釈が必要かと思って書いたら怒られて、最終的にはMole []で問題ないことが分かった。unAtomは入れておかないと、Atom He みたいに表示されるので入れている。空文字は"\NUL"で入れるらしい。""だと""が表示されるのでダメだった。
instance Show Mole where show (Mole ((a, b):c)) = (unAtom $ b) ++ show a ++ show (Mole c) show (Mole []) = "\NUL"
あと、isAtomは型がAtom指定しているので、Atom以外を与えるとエラーになる。a -> Bool とかにした方が良いのかと思ったが、本体でAtomって書いてあるのでそれはだめっぽい(Atomだろって怒られる)まぁ、isUpperとかもCharじゃないと怒られるので良いことにした。dataを使うかnewtypeを使うか、whereを使うかletを使うかとか、ちゃんと条件を網羅出来ているのか、再帰で書いたときの終止条件が書けているのか、など課題が多い。しばらくは続けていく。