bricks-0.0.0.2: Bricks is a lazy functional language based on Nix.

Safe HaskellNone
LanguageHaskell2010

Bricks.Expression

Contents

Synopsis

Expressions

data Expression Source #

Constructors

Expr'Var Str'Unquoted

A variable, such as x.

Expr'Str Str'Dynamic

A string may be quoted either in the traditional form using a single double-quote ("..."):

"one\ntwo"

or in the "indented string" form using two single-quotes (''...''):

''
  one
  two
''

Both of these examples reduce to the same value, because leading whitespace is stripped from indented strings.

Either may contain "antiquotation" (also known as "string interpolation") to conveniently concatenate string-valued variables into the string.

"Hello, my name is ${name}!"

Normal strings may contain the following escape sequences:

  • \\\
  • \""
  • \${${
  • \n → newline
  • \r → carriage return
  • \t → tab

The indented string form does not interpret any escape sequences.

Expr'List List

A list is an ordered collection of expressions.

The empty list:

[ ]

A list containing three variables:

[ a b c ]

Lambdas, function applications, let-in expressions, and with expressions must be parenthesized when in a list.

[
  (x: f x y)
  (g y)
  (let a = y; in f a a)
  (with d; f x a)
]
Expr'Dict Dict

A dict is an unordered extensional mapping from strings.

The empty dict (with no bindings):

{ }

A dict with two bindings:

{
  a = "one";
  b = "one two";
}

By default, dict bindings cannot refer to each other. For that, you need the rec keyword to create a recursive dict.

rec {
  a = "one";
  b = "${a} two";
}

In either case, the order of the bindings does not matter.

The left-hand side of a dict binding may be a quoted string (in the traditional "..." style, not the indented-string '' style), which make it possible for them to be strings that otherwise couldn't be expressed unquoted, such as strings containing spaces:

{ "a b" = "c"; }

The left-hand side of a dict may even be an arbitrary expression, using the ${ ... } form:

let x = "a b"; in { ${x} = "c"; }

Dicts also support the inherit keyword:

{ inherit a; inherit (x) c d; }

The previous expression is equivalent to:

{ a = a; c = x.c; d = x.d; }
Expr'Dot Dot

A dot expression (named after the . character it contains) looks up the value in a dict.

The examples in this section all reduce to Z.

{ a = "Z"; }.a
let x = { a = "Z"; }; in x.a
{ x = { a = "Z"; }; }.x.a

The right-hand side of a dot may be a quoted string (in the traditional "..." style, not the indented-string '' style):

{ a = "Z"; }."a"

The right-hand side of a dot may even be an arbitrary expression, using the ${ ... } form:

{ a = "Z"; }.${ let b = "a"; in b }
Expr'Lambda Lambda

A lambda expression x: y where x is the parameter.

This is a function that turns a name into a greeting:

name: "Hello, ${name}!"

The function parameter can also be a dict pattern, which looks like this:

{ a, b, c ? "another" }: "Hello, ${a}, ${b}, and ${c}!"

That function accepts a dict and looks up the keys a, b, and c from it, applying the default value "another" to c if it is not present in the dict. Dict patterns therefore give us something that resembles functions with named parameters and default arguments.

By default, a lambda defined with a dict pattern fails to evaluate if the dict argument contains keys that are not listed in the pattern. To prevent it from failing, you can end the pattern with ...:

({ a, ... }: x) { a = "1"; b = "2"; }

Every function has a single parameter. If you need multiple parameters, you have to curry:

a: b: [ a b ]
Expr'Apply Apply

Function application:

f x

If a function has multiple (curried) parameters, you can chain them together like so:

f x y z
Expr'Let Let

A let-in expression:

let
  greet = x: "Hello, ${x}!";
  name = "Chris";
in
  greet name

Let bindings, like dict bindings, may also use the inherit keyword.

let
  d = { greet = x: "Hello, ${x}!"; name = "Chris"; }
  inherit (d) greet name;
in
  greet name

The previous example also demonstrates how the bindings in a let expression may refer to each other (much like a dict with the rec keyword). As with dicts, the order of the bindings does not matter.

Expr'With With

A with expression is similar to a let-in expression, but the bindings come from a dict.

with {
  greet = x: "Hello, ${x}!";
  name = "Chris";
};
  greet name

Instances

Show Expression Source #

This instance is designed for doctests and REPL experimentation. The format is designed to strike a balance in verbosity between the derived Show implementations (which are unwieldily long) and the Bricks language itself (which is quite terse but unsuitable for demonstrating the parser, as outputting a Bricks rendering of parse result wouldn't illumunate anyone's understanding of the AST that the Show instances are here to depict).

Binding Expression DictBinding Source # 

Strings

type Str'Static = Text Source #

A fixed string value. We use the description "static" to mean the string may not contain antiquotation, in contrast with Str'Dynamic which can.

newtype Str'Dynamic Source #

A quoted string expression, which may be a simple string like "hello" or a more complex string containing antiquotation like "Hello, my name is ${name}!". See Expr'Str.

We use the description "dynamic" to mean the string may contain antiquotation, in contrast with Str'Static which cannot.

Constructors

Str'Dynamic 

String conversions

Lists

newtype List Source #

A list literal expression, starting with [ and ending with ]. See Expr'List.

Constructors

List (Seq Expression) 

Instances

Dicts

data Dict Source #

A dict literal expression, starting with { or rec { and ending with }. See Expr'Dict.

Constructors

Dict 

Fields

Instances

Dict lookup

data Dot Source #

An expression of the form person.name that looks up a key from a dict. See Expr'Dot.

Constructors

Dot 

Instances

Show Dot Source # 

Methods

showsPrec :: Int -> Dot -> ShowS #

show :: Dot -> String #

showList :: [Dot] -> ShowS #

expression'applyDots Source #

Arguments

:: Expression

Dict

-> [Expression]

Lookups

-> Expression

Dot expression

Lambdas

data Lambda Source #

A function expression. See Expr'Lambda.

Constructors

Lambda 

Fields

Instances

Function parameters

data Param Source #

A parameter to a Lambda. All functions have a single parameter, but it's more complicated than that because it may also include dict destructuring.

Constructors

Param'Name Str'Unquoted

A simple single-parameter function

Param'DictPattern DictPattern

Dict destructuring, which gives you something resembling multiple named parameters with default values

Param'Both Str'Unquoted DictPattern

Both a param name and a dict pattern, separated by the @ keyword

Instances

data DictPattern Source #

A type of function parameter (Param) that does dict destructuring.

Constructors

DictPattern 

Fields

data DictPattern'1 Source #

One item within a DictPattern.

Constructors

DictPattern'1 

Fields

Function application

data Apply Source #

A function application expression. See Expr'Apply.

Constructors

Apply 

Fields

Instances

expression'applyArgs Source #

Arguments

:: Expression

Function

-> [Expression]

Args

-> Expression

Function application

let

data Let Source #

A let-in expression. See Expr'Let.

Constructors

Let 

Fields

Instances

Show Let Source # 

Methods

showsPrec :: Int -> Let -> ShowS #

show :: Let -> String #

showList :: [Let] -> ShowS #

data LetBinding Source #

A semicolon-terminated binding within the binding list of a Let expression.

Constructors

LetBinding'Eq Str'Static Expression

A binding with an equals sign, of the form x = y;

LetBinding'Inherit Inherit

A binding using the inherit keyword, of the form inherit a b; or inherit (x) a b;

with

data With Source #

A with expression. See Expr'With.

Constructors

With 

Instances

inherit