Elm に手を出しました。
mousemove のイベントハンドラを使うのに MouseEvent の JSON をパースする必要があって四苦八苦したので、明日の自分のために JSON のパースの仕方をメモっておきます。
後日イベントハンドラについても書く予定。
パーサを書く
SomethingJson という雑なモジュールを作成しました。
module SomethingJson exposing
( Something
, Somethings
, somethingDecoder
, parseSomething
, parseSomethings
, FooBarBaz
, parseFooBarBaz
)
import Json.Decode exposing
( Decoder
, Error
, decodeString
, at
, string
, int
, map
, map3
, list
)
-- "something" という文字列の要素を持つレコード型
type alias Something =
{ something : String
}
-- Something のリスト型
type alias Somethings =
List Something
-- "something" という要素を含む JSON のデコーダ
somethingDecoder : Decoder String
somethingDecoder =
at ["something"] string
-- JSON 文字列をパースして Something 型の値を返す関数
parseSomething : String -> Result Error Something
parseSomething =
decodeString (map Something somethingDecoder)
-- JSON 文字列をパースして Somethings 型の値を返す関数
parseSomethings : String -> Result Error Somethings
parseSomethings =
decodeString (list (map Something somethingDecoder))
-- 三つの要素を持つレコード型
type alias FooBarBaz =
{ foo : String
, bar : Int
, baz : List Int
}
-- "foo", "bar", "baz" という要素を含む JSON のデコーダ
fooBarBazDecoder : Decoder FooBarBaz
fooBarBazDecoder =
map3 FooBarBaz
(at ["foo"] string)
(at ["bar"] int)
(at ["baz"] (list int))
-- JSON 文字列をパースして FooBarBaz 型の値を返す関数
parseFooBarBaz : String -> Result Error FooBarBaz
parseFooBarBaz =
decodeString fooBarBazDecoder
elm init した時に作成される src/ というディレクトリに SomethingJson.elm という名前で保存します。
パーサを使う
REPL で動作を確認します。
$ elm repl ---- Elm 0.19.0 ---------------------------------------------------------------- Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc. -------------------------------------------------------------------------------- >
インポートします。
> import SomethingJson
Something 型を表す JSON をパースします。
> SomethingJson.parseSomething "{\"something\":\"何か\"}"
Ok { something = "何か" }
: Result Json.Decode.Error SomethingJson.Something
Somethings 型(Something のリスト型)を表す JSON をパースします。
> SomethingJson.parseSomethings "[{\"something\":\"何か\"},{\"something\":\"どれか\"}]"
Ok [{ something = "何か" },{ something = "どれか" }]
: Result Json.Decode.Error SomethingJson.Somethings
三種類の型の値を持つ FooBarBaz 型を表す JSON をパースします。
> SomethingJson.parseFooBarBaz "{\"foo\":\"ふー\",\"bar\":123,\"baz\":[1,2,3]}"
Ok { bar = 123, baz = [1,2,3], foo = "ふー" }
: Result Json.Decode.Error SomethingJson.FooBarBaz
もっと要素の多い JSON のパーサをかく
Json.Decode には map8 まで用意されていて 8 要素まではパーサを書くことができます。それ以上の場合はドキュメントにも記載されているように他のパッケージなどを利用します。
Note: If you run out of map functions, take a look at elm-json-decode-pipeline which makes it easier to handle large objects, but produces lower quality type errors.
リンクされている elm-json-decode-pipeline を使ってみます。
インストールします。
$ elm install NoRedInk/elm-json-decode-pipeline
HTML の MouseEvent の内容を解釈するパーサを書いてみます。
module MouseEvents exposing (EventData, mouseEventDecoder, parseMouseEvent)
import Json.Decode exposing (Decoder, Error, decodeString, int, bool, succeed)
import Json.Decode.Pipeline exposing (required)
type alias EventData =
{ altKey : Bool
, ctrlKey : Bool
, shiftKey : Bool
, metaKey : Bool
, button : Int
, clientX : Int
, clientY : Int
, movementX : Int
, movementY : Int
, screenX : Int
, screenY : Int
}
mouseEventDecoder : Decoder EventData
mouseEventDecoder =
succeed EventData
|> required "altKey" bool
|> required "ctrlKey" bool
|> required "shiftKey" bool
|> required "metaKey" bool
|> required "button" int
|> required "clientX" int
|> required "clientY" int
|> required "movementX" int
|> required "movementY" int
|> required "screenX" int
|> required "screenY" int
parseMouseEvent : String -> Result Error EventData
parseMouseEvent =
decodeString mouseEventDecoder
MouseEvents.elm というファイル名で src/ に保存します。
REPL で確認します。
$ elm repl
---- Elm 0.19.0 ----------------------------------------------------------------
Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
--------------------------------------------------------------------------------
> import MouseEvents
> MouseEvents.parseMouseEvent "{\"screenX\":1,\"screenY\":1,\"movementX\":1,\"movementY\":1,\"clientX\":1,\"clientY\":1,\"button\":0,\"metaKey\":true,\"shiftKey\":true,\"ctrlKey\":true,\"altKey\":true}"
Ok { altKey = True, button = 0, clientX = 1, clientY = 1, ctrlKey = True, metaKey = True, movementX = 1, movementY = 1, screenX = 1, screenY = 1, shiftKey = True }
: Result Json.Decode.Error MouseEvents.EventData
これで MouseEvent を扱う準備ができました。つづく。
いつか読むはずっと読まない:はじまりの艦隊
The Lost Fleet (彷徨える艦隊)の最新刊、The Genesis Fleet: Vanguard 、の邦訳、ようやく読了。って刊行から一年近く経ってしまっていた。
来月には原著のシリーズ最新刊 The Genesis Fleet: Triumphant がもう刊行される模様。

- 作者: ジャック・キャンベル,寺田克也,月岡小穂
- 出版社/メーカー: 早川書房
- 発売日: 2018/05/02
- メディア: 文庫
- この商品を含むブログ (1件) を見る