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.4k
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
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
2k
ゲームの物理 剛体編
fadis
0
400
Graviton と Nitro と私
maroon1st
0
160
從冷知識到漏洞,你不懂的 Web,駭客懂 - Huli @ WebConf Taiwan 2025
aszx87410
2
3.3k
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
190
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
130
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
令和最新版Android Studioで化石デバイス向けアプリを作る
arkw
0
470
CSC307 Lecture 02
javiergs
PRO
1
760
クラウドに依存しないS3を使った開発術
simesaba80
0
220
Giselleで作るAI QAアシスタント 〜 Pull Requestレビューに継続的QAを
codenote
0
340
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
2
710
Featured
See All Featured
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
39
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
Speed Design
sergeychernyshev
33
1.5k
Skip the Path - Find Your Career Trail
mkilby
0
42
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
41
The untapped power of vector embeddings
frankvandijk
1
1.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
エンジニアに許された特別な時間の終わり
watany
106
220k
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