Dhallは、JSONやYAMLのようなシンプルな構成ファイルに、関数型プログラミングと静的型システムの利点を融合させた設定言語です。これにより、複雑なインフラやアプリケーションの設定を安全かつ再利用可能に記述できます。
なぜDhallが選ばれるのか?
従来のYAML/JSON設定は柔軟ですが、以下のような課題があります:
- 型チェックがなく、デプロイ時に初めてエラーが発覚
- 繰り返しの多い記述が避けられず、変更時のメンテナンスコストが高い
- 大規模プロジェクトでのモジュール分割が困難
Dhallはこれらを解決するために設計されており、以下の特徴を持ちます:
- コンパイル時(評価時)に型エラーを検出
- 関数・変数によるDRYな記述
- 他のDhallファイルや標準ライブラリのインポート機能
- 最終的にJSON/YAMLへ変換可能で既存ツールとの互換性を確保
基本的な使用例
まず、Dhall式をJSONに変換してみましょう:
{ application = "web-api", port = 8080, debug = True }
この内容をdhall-to-jsonに渡すと、次のようなJSONが出力されます:
{
"application": "web-api",
"port": 8080,
"debug": true
}
再利用可能な設定の作成
共通パターンを関数として定義し、環境ごとにカスタマイズできます:
let mkService = \(name : Text) ->
{ name = name
, replicas = 3
, image = "company/${name}:v1.2"
}
in [ mkService "auth"
, mkService "payment"
]
このように記述することで、サービス定義のテンプレートを一元管理できます。
モジュールと標準ライブラリ
DhallはPreludeと呼ばれる標準ライブラリを提供しており、リスト操作や文字列処理など多くのユーティリティが含まれています。例えば、リストの各要素に1を加えるには:
let Prelude = https://prelude.dhall-lang.org/package.dhall
in Prelude.List.map Natural (\(x : Natural) -> x + 1) [2, 4, 6]
高度な機能
レコードのマージ
//演算子(原文の/\は誤記)を使い、ベース設定と環境固有設定を結合できます:
let base = { timeout = 10, retries = 2 }
let prod = { env = "production", tls = True }
in base // prod
オプショナルフィールド
Optional型を使うと、JSON出力時にNoneのフィールドを自動的に除外できます:
[ { user = "admin", email = Some "admin@example.com" }
, { user = "guest", email = None Text }
]
変換結果では、guestのemailフィールドは含まれません。
動的キーを持つオブジェクト
連想配列スタイルの記述により、動的なキー名を持つオブジェクトを生成可能です:
toMap
{ alice = { role = "engineer" }
, bob = { role = "designer" }
}
これはdhall-to-jsonによって適切なJSONオブジェクトに変換されます。
実用シナリオ
- Kubernetesマニフェスト生成:型安全なPod/Service定義
- Terraform設定:環境ごとの差分を関数で抽象化
- CIパイプライン定義:ジョブテンプレートの再利用
- マイクロサービスの設定共通化:開発・本番間の一貫性確保
始め方
Dhallツールチェーンは各OSで簡単にインストールできます:
- macOS:
brew install dhall-json - Linux: 公式バイナリまたはNix経由
- Windows: GitHub Releasesからバイナリを取得
インストール後、dhall-to-jsonやdhall-to-yamlコマンドを使ってすぐに試せます。
詳細な学習は公式チュートリアル(Language Tour)やPreludeのソースコードを参照すると良いでしょう。Dhallの設計思想は「設定もコードと同じく信頼性と保守性が求められる」という点にあります。型安全性と関数的抽象化により、設定ファイルの品質を飛躍的に向上させることができます。