Skip to content

Instantly share code, notes, and snippets.

@dra1n
Last active August 20, 2024 08:52
Show Gist options
  • Save dra1n/338c15d3426efd9361f029b2e5679892 to your computer and use it in GitHub Desktop.
Save dra1n/338c15d3426efd9361f029b2e5679892 to your computer and use it in GitHub Desktop.
Dhall talk

What is dhall?

Functions

  • Built-in
  • User defined
let makeUser = \(user : Text) ->
      let home       = "/home/${user}"
      let privateKey = "${home}/.ssh/id_ed25519"
      let publicKey  = "${privateKey}.pub"
      in  { home, privateKey, publicKey }
in  [ makeUser "bill"
    , makeUser "jane"
    ]

Types

Imports

Problems we've encountered so far

  • Really hard to write recursive types
  • No support for record fields autocompletion
  • Dhall formatter removes any comment that is not in the beggining of the file
  • Only can compare booleans, so it's impossible to write something like Map.lookup for example

What's cool

  • Simple, functional, strongly typed
  • Embrace limitations

Popular libraries

-- type alias
let Map = List { mapKey : Text, mapValue : Text }
-- union type example
let View = < span | div >
-- special syntax for record type definition that allows us to use record completion operator `::`
let TypographyProps =
{ Type =
{ asElement : Text
, weight : Optional Text
, underscore : Bool
, style : Optional Map
}
, default =
{ asElement = "p"
, weight = None Text
, underscore = False
, style = None Map
}
}
let InputProps =
{ Type = { label : Text, name : Text, value : Optional Text, type : Text }
, default = { type = "text", value = None Text }
}
let ViewProps = { Type = { asElement : View }, default.asElement = View.div }
-- union types with multiple value constructors
let ComponentProps =
< Typography : TypographyProps.Type
| Input : InputProps.Type
| View : ViewProps.Type
>
let Component1
: Type
= { name : Text, props : ComponentProps, children : Optional Text }
-- we want this type to be recursive, because of `children`, but in practice it's easier to get rid of the recursion
let Component
: Type
= { name : Text, props : ComponentProps, children : List Component1 }
let jsx
: Component
= { name = "SiteWrapper"
, props = ComponentProps.View ViewProps::{=}
, children =
[ { name = "SiteHeader"
, props =
ComponentProps.Typography
TypographyProps::{
, asElement = "h1"
, weight = Some "bold"
, underscore = True
, style = Some (toMap { marginBottom = "24px" })
}
, children = Some "Welcome to my site"
}
, { name = "NameForm"
, props =
ComponentProps.Input
InputProps::{ name = "name", label = "Please enter your name" }
, children = None Text
}
]
}
in jsx
{
"name": "SiteWrapper",
"props": {
"asElement": "div"
},
"children": [
{
"name": "SiteHeader",
"children": "Welcome to my site",
"props": {
"asElement": "h1",
"underscore": true,
"weight": "bold",
"style": {
"marginBottom": "24px"
}
}
},
{
"name": "NameForm",
"props": {
"label": "Please enter your name",
"name": "name",
"type": "text",
},
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment