Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Dhallによるリッチな設定ファイル体験
Search
syocy
June 29, 2018
Programming
0
6.3k
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.8k
Dhall: Haskellの新たなキラーアプリ
syocy
4
4.4k
Other Decks in Programming
See All in Programming
Combinatorial Interview Problems with Backtracking Solutions - From Imperative Procedural Programming to Declarative Functional Programming - Part 1
philipschwarz
PRO
0
120
データファイルをAWSのDWHサービスに格納する / 20251115jawsug-tochigi
kasacchiful
2
100
【CA.ai #3】ワークフローから見直すAIエージェント — 必要な場面と“選ばない”判断
satoaoaka
0
100
大体よく分かるscala.collection.immutable.HashMap ~ Compressed Hash-Array Mapped Prefix-tree (CHAMP) ~
matsu_chara
1
200
2025 컴포즈 마법사
jisungbin
1
170
【CA.ai #3】Google ADKを活用したAI Agent開発と運用知見
harappa80
0
140
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
2
5k
Integrating WordPress and Symfony
alexandresalome
0
110
sbt 2
xuwei_k
0
150
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
290
jakarta-security-jjug-ccc-2025-fall
tnagao7
0
110
AIエージェントを活かすPM術 AI駆動開発の現場から
gyuta
0
190
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.8k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.3k
RailsConf 2023
tenderlove
30
1.3k
GraphQLとの向き合い方2022年版
quramy
49
14k
Writing Fast Ruby
sferik
630
62k
Six Lessons from altMBA
skipperchong
29
4.1k
The Cost Of JavaScript in 2023
addyosmani
55
9.3k
Visualization
eitanlees
150
16k
Done Done
chrislema
186
16k
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