Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Dhallによるリッチな設定ファイル体験
Search
syocy
June 29, 2018
Programming
0
6.2k
Dhallによるリッチな設定ファイル体験
LT in Japanese about dhall-lang
syocy
June 29, 2018
Tweet
Share
More Decks by syocy
See All by syocy
並列並行言語Haskell
syocy
4
3.7k
Dhall: Haskellの新たなキラーアプリ
syocy
4
4.3k
Other Decks in Programming
See All in Programming
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
1
330
関数型まつり2025登壇資料「関数プログラミングと再帰」
taisontsukada
2
850
つよそうにふるまい、つよい成果を出すのなら、つよいのかもしれない
irof
1
300
すべてのコンテキストを、 ユーザー価値に変える
applism118
2
750
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
230
Go1.25からのGOMAXPROCS
kuro_kurorrr
1
800
Create a website using Spatial Web
akkeylab
0
300
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
170
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
46
30k
F#で自在につくる静的ブログサイト - 関数型まつり2025
pizzacat83
1
310
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
390
なんとなくわかった気になるブロックテーマ入門/contents.nagoya 2025 6.28
chiilog
1
190
Featured
See All Featured
Statistics for Hackers
jakevdp
799
220k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Done Done
chrislema
184
16k
Balancing Empowerment & Direction
lara
1
360
A Modern Web Designer's Workflow
chriscoyier
694
190k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
48
5.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.3k
The Pragmatic Product Professional
lauravandoore
35
6.7k
How STYLIGHT went responsive
nonsquared
100
5.6k
Transcript
Dhallによるリッチな設定ファイル体験 @syocy 2018-06-29
設定ファイル書いてますか? 最初は小さく単純な JSON/YAML から始まるが…… ソフトウェアの成長に伴って役割が増えていく 気づくと数百行の JSON ができていたり 後段の機能に渡すために JSON
の文字列として JSON が入り込む 2 / 18
マクロの誘惑 設定ファイルにさらなる表現力を持たせたくなって くる しかし既存の設定ファイルを大きく変えたくない 独自マクロだ! → JSON 文法が破壊され構文ハイライト等が効かなく なる →実行時でないとどういう設定になるか分からなくなる
→表現力を上げすぎると無限ループのおそれもある 3 / 18
Dhall
Dhall? You can think of Dhall as: JSON + functions
+ types + imports – GitHub - dhall-lang/dhall-lang Dhall とは データ表現に、 プログラマブルさと、 静的検査と、 外部ファイルのインポートを加えたもの 5 / 18
Dhallはチューリング完全ではない 具体的にはループがない どうやっても無限ループしないので安心 (個人的には) 設定記述にはループがない方が読みやす い気がする ユニットテストにはあまりループを書くべきでないと いうのと近い 6 /
18
例: Kubernetes(オリジナルYAML) 1 kind: Service 2 apiVersion: v1 3 metadata:
4 name: my-service 5 spec: 6 selector: 7 app: MyApp 8 ports: 9 - protocol: TCP 10 port: 80 11 targetPort: 9376 (https://kubernetes.io/docs/concepts/ services-networking/service/) 7 / 18
例: Kubernetes(型注釈なしDhall) 1 { kind = 2 "Service" 3 ,
apiVersion = 4 "v1" 5 , metadata = 6 { name = "my-service" } 7 , spec = 8 { selector = 9 { app = "MyApp" } 10 , ports = 11 [ { protocol = "TCP", port = 80, targetPort = 9376 } ] 12 } 13 } 8 / 18
DhallをYAMLに変換 > cat service.dhall | dhall-to-yaml apiVersion: v1 kind: Service
spec: selector: app: MyApp ports: - targetPort: 9376 protocol: TCP port: 80 metadata: name: my-service できたけど、これだけだと嬉しさが少ない “Service” などを typo してもエラーにならない 9 / 18
Dhallの機能を活用する Dhall の機能によって静的検査を導入してみる つまり、Dhall で Kubernetes のスキーマを記述する スキーマは k8s_types.dhall という名前で別ファ
イルに切り出す 以下の便利な標準関数を使う constructors: Union 型のコンストラクタを生成する merge: Union 型の値を任意の型に変換する 10 / 18
例: Kubernetes(Dhall色々定義1/2) 1 let Kind_ = < Service : {}
| Pod : {} | Deployment : {} > 2 3 in let kindHandlers = 4 { Service = 5 λ(_ : {}) → "Service" 6 , Pod = 7 λ(_ : {}) → "Pod" 8 , Deployment = 9 λ(_ : {}) → "Deployment" 10 } 11 12 in let ApiVersion = < v1 : {} > 13 14 in let apiVersionHandlers = { v1 = λ(_ : {}) → "v1" } 15 16 in let Metadata : Type = { name : Text } 17 18 in let Selector : Type = { app : Text } 19 20 in let Protocol = < TCP : {} | UDP : {} > 21 22 in let protocolHandlers = { TCP = λ(_ : {}) → "TCP", UDP = λ(_ : { (次のページに続く) 11 / 18
例: Kubernetes(Dhall色々定義2/2) 24 in let Port : Type = {
protocol : Text, port : Integer, targetPort : 25 26 in let Spec : Type = { selector : Selector, ports : List Port } 27 28 in let Yaml 29 : Type 30 = { kind : Text, apiVersion : Text, metadata : Metadata, spec 31 32 in { Kinds = 33 constructors Kind_ 34 , kind = 35 λ(k : Kind_) → merge kindHandlers k 36 , ApiVersions = 37 constructors ApiVersion 38 , apiVersion = 39 λ(v : ApiVersion) → merge apiVersionHandlers v 40 , Protocols = 41 constructors Protocol 42 , protocol = 43 λ(p : Protocol) → merge protocolHandlers p 44 , Yaml = 45 Yaml 46 } 12 / 18
例: Kubernetes(Dhall版Ver.2) 1 let types = ./k8s_types.dhall 2 3 in
( { kind = 4 types.kind (types.Kinds.Service {=}) 5 , apiVersion = 6 types.apiVersion (types.ApiVersions.v1 {=}) 7 , metadata = 8 { name = "my-service" } 9 , spec = 10 { selector = 11 { app = "MyApp" } 12 , ports = 13 [ { protocol = 14 types.protocol (types.Protocols.TCP {=}) 15 , port = 16 80 17 , targetPort = 18 9376 19 } 20 ] 21 } 22 } 23 : types.Yaml 24 ) 13 / 18
DhallをYAMLに変換(Ver.2) > cat service_typed.dhall | dhall-to-yaml apiVersion: v1 kind: Service
spec: selector: app: MyApp ports: - targetPort: 9376 protocol: TCP port: 80 metadata: name: my-service 結果を変えずに静的検査・関数・インポートが追加で きた! 14 / 18
Dhallのツールチェイン dhall コマンド Dhall のインタプリタ。ターミナル上で Dhall ファイル のチェックをするならこれ dhall-format コマンド
Dhall の公式フォーマッタ。保存時に自動で走るように しておくと良い (Emacs の dhall-mode は勝手にそうして くれる) 15 / 18
Dhallのアプリケーション dhall-json dhall-to-json, dhall-to-yaml コマンドを提供 Dhall ファイルを JSON/YAML に変換する すでに
JSON/YAML を使うアプリがあるなら、これを 使って静的検査と関数とインポートのある Dhall から JSON/YAML を生成しよう dhall-to-cabal Dhall ファイルを cabal ファイルに変換する Dhall を本格利用するならノウハウの宝庫なので、cabal に興味がない場合でも参考にするとよい 16 / 18
バインディング プログラミング言語から Dhall を読む場合は各言語のバ インディングを利用する すでに提供されている: Haskell, Nix1 開発中: Scala,
Rust 1正確にはプログラミング言語ではない 17 / 18
事例紹介 18 / 18