正規表現を抽象化したコードを書きたくて、以下のようなものができました。
Haskell
1data Regex 2 = Literal String -- 完全一致 3 | AnyChar -- 何かしら1文字 「.」 4 | Not Regex -- 否定 「^」 5 | And {a::Regex, b::Regex} -- aの次にb 6 | Or {a::Regex, b::Regex} -- aまたはb 「|」 7 | Repeat {range::[Int], element::Regex} -- elementがrangeのいずかの個数 8 9superPosition :: Regex -> Regex -- 0回か1回 「?」 10superPosition regex = Repeat [0,1] regex 11 12some :: Regix -> Regix -- 1回以上繰り返し 「+」 13some regex = Repeat [1..] regex 14 15oneOrMore :: Regex -> Regex -- 0回以上繰り返し 「*」 16oneOrMode regex = Repeat [0..] regex 17 18match :: Regex -> String -> Bool 19match (Literal literal) string = literal == string 20match (AnyChar) string = length string == 1 21match (Not regix) string = not $ match regix string 22-- TODO -- match (And a b) string = 23match (Or a b) string = match a || match b 24-- TODO -- match (Repeat range element) string =
解決したい問題点
-
TODOの部分の実装は今の自分の力でも無理やり実装しようと思えばできるけど、効率の良いhaskellらしいコードにするにはどんなやり方があるか。
-
some
とかの関数とOr
とかのコンストラクタが利用側では同じように使えるべきだが、キャメルケースとパスカルケースで違う見た目になっている。 -
superPosition
とかoneOrMore
という名前付けが他のものと一貫性が取れてない。もっと良い名前がないか? -
some
とかor
とかの名前付けだと利用側で名前衝突が起こる可能性があるかも?ないかも?初心者だからこの名前付けが良いのか悪いのかも分からない。 -
range
に負の整数を指定できてしまう
他にも私には分からない問題点があると思うので、そちらにもリファクタリングやマサカリをお願いします。
「regexは他にあるから車輪の再発明だ」っていうマサカリだけは無しでお願いします。
勉強のために車輪の再発明をしています。
そもそもRegexはString -> Bool
の型シノニムとした方がいいんですかね?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/24 09:31
2018/11/24 13:11