こんにちは こんばんは
kenjiです。
今回はDhall言語について書きたいと思います。(AWSについてばっかだったので)
Dhallってなに??
そもそもDhallってなんぞやと思う方がけっこういらっしゃると思います。
読み方すら自分は怪しかったです。(ダール?)
実際は「ドール」と読むそうです。
ちょーざっくりDhallを説明すると、
設定ファイル(yamlとかjsonとか)をプログラマブルに書く
為の物です。
公式には以下のような記述がされております。
Dhall is a programmable configuration language that is not Turing-complete
設定ファイルを書くための言語であり、これはチューリング完全ではない
と説明されています。
チューリング完全
とは・・・・
Dhallは設定ファイルを書くためだけの、言語なので再帰や無限ループを書けない
。
別のプログラミング言語の様に汎用性がない。と考えていただければ問題ないと思います。
もう一度いいます、これは設定ファイルを書く為だけの言語
です
もう少し詳しく知りたい方はこちら
では実際にDhallを触っていきましょう。
Dhall を導入する
Nixで導入が可能です。(Nixを入れていない方は、こちら)
$ nix-shell -p dhall dhall-json
$ dhall version
導入がめんどくさい方/お試し実施したい方
$ docker pull nixos/nix
$ docker run -it nixos/nix
[id]:/# nix-shell -p dhall dhall-json
[id]:/# dhall version
今回はdhall-jsonを利用してJSONを作成するので、Macの方は以下でもOK
$ brew install dhall-json
Dhallに触れてみる
以下のコマンドでREPL(対話型評価環境)を起動することができる。
※以下はdhall-json
を入れただけでは動作しません
nix-shellにてdhallコマンド導入をお願いします。不要の方は読み流してください。
$ dhall repl
⊢ 1 + 1
2
値の型を確認したい場合は以下のように:t
が利用できる
⊢ :t 1
Natural
⊢ :t "dhall"
Text
⊢ :t True
Bool
⊢ :t [1,2,3]
List Natural
他にも利用できる型はあるが、ここでは割愛する。
更に詳しい詳細はこちら
もちろん以下のような関数を定義することもできる。
:t λ(n : Natural) -> n * 2
∀(n : Natural) → Natural
引数の型注釈は必須となっています。
#Dhallを使って簡単なJSONを生成する
早速以下のようにDhallを使ってJSONを生成してみましょう。
$ dhall-to-json <<< '{foo = [1,2,3], bar = True}'
{"foo":[1,2,3],"bar":true}
以下の方法でも同一の結果を得ることができる。
$ echo '{foo = [1,2,3],bar = True}' | dhall-to-json
{"foo":[1,2,3],"bar":true}
###キレイな形でJSONを出力する
以下のように--pretty
オプションをつけることによって、整形されたJSONが出力できる。
$ echo '{foo = [1,2,3],bar = True}' | dhall-to-json --pretty
{
"bar": true,
"foo": [
1,
2,
3
]
}
どうでしょう? 簡単に生成できましたね。
このぐらい短いコードなら上記のようにコマンドラインで実装できると思いますが、
コードが長くなった場合コマンドライン上で実装するのは難しくなってきます。
ではどうするか
以下のコードをファイルに保存しましょう。
{ foo = True, bar = [1, 2, 3, 4, 5], baz = "ABC"}
{ foo = True
, bar = [1, 2, 3, 4, 5]
, baz = "ABC"
}
以下のコマンドを実施してみましょう。
dhall-to-json --pretty <<< '[ ./example.dhall, ./example.dhall ]'
[
{
"bar": [
1,
2,
3,
4,
5
],
"baz": "ABC",
"foo": true
},
{
"bar": [
1,
2,
3,
4,
5
],
"baz": "ABC",
"foo": true
}
]
簡単に長いコードを一つのJSONとして扱えるようになりました。
この様にして、大きなJSONファイルも分割して管理することができます。(すご便利)
一つ注意として以下の書き方になると、エラーとなります。
$ dhall-to-json <<< '[1,True]'
Error: List elements should all have the same type
- Natural
+ Bool
True
(stdin):1:4
これはリスト要素の中の型が不一致の為エラーとなってしまいます。
リスト要素の中はすべて同じ型である必要があります。
細かいエラー内容を必要とする場合は--explain
オプションを入れください。
$ dhall-to-json --explain <<< '[1,"True"]'
ここまでが、単純なJSONの作り方となります。
続いてDhallを利用して型チェックできるようにしましょう。
#型チェックをする
型チェック検証をやってみましょう。
$ dhall-to-json <<< '{foo = 1,bar = "True"}:{foo:Natural,bar:Text}'
式がスキーマ(型アノテーション)と一致しない場合、検証に失敗します(つまり、型エラーが発生する)
例えば以下のような形です。
$ dhall-to-json <<< '{foo = 1,bar = True}:{foo:Natural,bar:Text}'
Error: Expression doesn't match annotation
{ bar : - Text
+ Bool
, …
}
型注釈を含むファイルをインポートすることもできます。
$ echo '{foo:Natural,bar:Bool}' > schema.dhall
$ dhall-to-json <<< '{foo = 1,bar = True}:./schema.dhall'
#let式
let式を利用し、複数回参照できる変数を定義することができます。
$ dhall-to-json <<< 'let x = [1, 2, 3] in [x, x, x]'
[[1,2,3],[1,2,3],[1,2,3]]
このlet式
を利用して以下の様にJSONを生成することができます。
let job = { department = "Data Platform", title = "Software Engineer" }
in let john = { age = 23, name = "John Doe", position = job }
in let alice = { age = 24, name = "Alice Smith", position = job }
in [ john, alice ]
$ dhall-to-json --pretty <<< './emp.dhall'
[
{
"age": 23,
"name": "John Doe",
"position": {
"department": "Data Platform",
"title": "Software Engineer"
}
},
{
"age": 24,
"name": "Alice Smith",
"position": {
"department": "Data Platform",
"title": "Software Engineer"
}
}
]
如何でしょう。
この様にして、大きなJSONファイルを分割して管理したり、型チェックをしたり等
今まで設定ファイルでは叶えることができなかった部分をプログラマブルに書くことができないだろうか。
今回はJSONを紹介したが、もちろんyaml
shell
もサポートされている。
次回はこれでdocker-compose.yml
を生成していきたい。
##参考にさせていただいたサイト
https://ryota-ka.hatenablog.com/entry/2018/08/27/110000
https://github.com/dhall-lang/dhall-lang/wiki/Getting-started%3A-Generate-JSON-or-YAML