Elmメモ - 文字列をIPアドレスに変換(2) Parserを用いる方法

準備 前回のsrc/IPAddr.elmを全て消し、内容を以下の通りにする。 1 2 3 4 5 module IPAddr exposing (..) import Parser type IPAddr = IPAddr Int Int Int Int $ elm repl > import Parser exposing (..) > import IPAddr exposing (..) Parserの基本 以下の2つのステップに分かれる。 Parserを作る Parserを実行する - Parser.runを用いる ライブラリでは、標準で用意されているParserと、それらを組み合わせて新たなParserを作るための関数が用意されている。 > run int "123" Ok 123 : Result (List Parser.DeadEnd) Int > run int "123abc" Ok 123 : Result (List Parser.DeadEnd) Int > run int "abc123abc" Err [{ col = 1, problem = ExpectingInt, row = 1 }] : Result (List Parser.DeadEnd) Int succeed 何もパースせず、決まった結果だけを返すパーサー。 > run (succeed "Hello") "123abcde" Ok "Hello" : Result (List Parser.DeadEnd) String パーサーを組み合わせるときの基本になる。 ...

2020-01-05 · (updated 2020-01-05) · 3 min · 549 words

Elmメモ - 文字列をIPアドレスに変換(1) splitを用いる方法

IPv4アドレスの文字列"192.168.1.1"をパースする方法を考える。IPAddrの内部表現は次のようにする。 1 type IPAddr = IPAddr Int Int Int Int 思いつくのは次の2通り。 ピリオドでsplitして、整数値に変換する。 パーサを利用する。 いずれにしても結構面倒。この記事では前者だけやる。 準備 適当なディレクトリで次のコマンドを実行。 $ elm init $ elm install elm/parser src/IPAddr.elmを作り、内容を以下の通りにする。 1 2 3 module IPAddr exposing (..) type IPAddr = IPAddr Int Int Int Int $ elm repl > import IPAddr exposing (..) 方針 次の処理を行う関数をfromStringとして定義する。 文字列を.でsplitする。 Listの要素数が4でなければ失敗。 Listの各要素にString.toIntを適用し、どれか一つでも失敗すれば全体としても失敗。 Listを[a,b,c,d]としたとき、IPAddr a b c dを返す。 traverseの実装 3の処理は、次の関数として抽象化できる: リストの各要素にfを適用し、その結果すべてがJustを返したときだけ、全体の結果を返す。 1 traverse : (a -> Maybe b) -> List a -> Maybe List b 原始的な実装 なるべくfoldrとかを使わずに書こうとするとこんな感じになる。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 traverse : (a -> Maybe b) -> List a -> Maybe (List b) traverse f list = case list of [] -> Just [] x::xs -> case traverse f xs of Nothing -> Nothing Just ys -> case f x of Nothing -> Nothing Just y -> Just (y::ys) case文を使ってネストが深くなってくると、Haskellみたいなパターンマッチが欲しくなってくる。 ...

2020-01-05 · (updated 2020-01-05) · 3 min · 437 words