Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@saurabhnanda
Last active June 6, 2022 21:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saurabhnanda/a6f4db1d15a0b114e5b4fd73f555e094 to your computer and use it in GitHub Desktop.
Save saurabhnanda/a6f4db1d15a0b114e5b4fd73f555e094 to your computer and use it in GitHub Desktop.
Comparitive code samples between Dhall and Haskell. Complete blog post at https://www.saurabhnanda.in/2022/03/24/dhall-a-gateway-drug-to-haskell/
-- Union/sum type to decide the logging configuration
let LoggingCfg = < LogFile : Text | Syslog >
-- Configuration that is common across applications. One can also define
-- AppOneCfg and AppTwoCfg for config params that are specific to each app.
let CommonCfg =
{ logging : LoggingCfg
-- ^ the logging configuration that should be same across both applications
, topic : Text
-- ^ the pub/sub topic that should be same across both applications
}
-- Config values for development environment
let devCfg : CommonCfg =
{ logging = LoggingCfg.LogFile "log/dev.log"
, topic = "devTopic"
}
-- Config values for production environment. This is not really being used in this code
-- sinppet, and is just an example to show how duplication across environments can be managed.
let prodCfg : CommonCfg =
{ logging = LoggingCfg.Syslog
, topic = "prodTopic"
}
-- Function to generate Application One's configuration, which is a properties file.
-- The return type of this function is a Text (string literal) which can be dumped to a file directly.
let appOneCfg = \(cfg : CommonCfg) ->
let loggingCfgHandler =
{ LogFile = \(f : Text) ->
''
logdriver = file
logfile = ${f}
''
-- ^ handler to convert the `LogFile` part of the sum-type
, Syslog = "logdriver = syslog"
-- ^ hadler to convert the `Syslog` part of the sum-type
}
in ''
topic = ${cfg.topic}
${merge loggingCfgHandler cfg.logging}
''
-- Function to generate Application Two's configuration, which is a JSON file.
-- The return type of this function is a native Dhall record, which can be easily converted
-- to a JSON via the dhall-to-json utility.
let appTwoCfg = \(common : CommonCfg) ->
let loggingCfgHandler =
{ LogFile = \(f : Text) ->
{ driver = "file"
, file = Some f
, Syslog =
{ driver = "syslog"
, file = None Text
-- ^ forced to use explicit nulls, else Dhall won't type-check this expression
}
}
in { topic = common.topic
, logging = merge loggingCfgHandler common.logging
}
in { appOneProps = appOneCfg devCfg
-- ^ can be written to filesystem via the `dhall-to-text` utility
, appTwoJson = appTwoCfg devCfg
-- ^ can be written to filesystem via the `dhall-to-json` utility
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment