Syntax Considerations - kvverti/rusty-lavender GitHub Wiki
Current syntax considerations for Lavender. Lavender syntax should be clear while at the same time staying true to previous versions.
Definitions define values/computations and functions. Lavender treats definitions with function type identically to definitions with non-function type. A definition is composed from a name, an optional type, an optional parameter list, and a function body, which may be a pattern match.
<Definition> ::= "def" <Id> [":" <TypeExpression> ";"] [<Pattern>*] <DefinitionBody>
<DefinitionBody> ::= "=>" <ValueExpression>
| (";" <Pattern>* "=>" <ValueExpression>)+
# Identity function
def id: 'a -> 'a
; x => x
# Also written as
def id2 x => x
# Pattern matching
def else: 'a -> Option 'a -> 'a
; d ; (Some a) => a
None => d
Let expressions declare and bind a name.
<LetExpression> ::= "let" <Pattern> "<-" <ValueExpression> [";" <Pattern> "<-" <ValueExpression>]* [";"] "in" <ValueExpression>
let x <- 3
in x + 4
let x <- complexComputation a b c;
y <- simpleComputation x;
in (x, y)
Case expressions pattern match on a single expression.
<CaseExpression> ::= "case" <ValueExpression> ";" <Pattern> "=>" <ValueExpression> [";" <Pattern> "=>" <ValueExpression>]*
case Some 3
; (Some a) => a
; None => 0
Data type definitions are declared with data
and define an algebraic data type. Data types may be generic. Each constructor of a data type is both a definition and a pattern.
<Data> ::= "data" <Identifier> [<Identifier>*] "=>" <Identifier> [<TypePrimary>*] ["|" <Identifier> [<TypePrimary>*]]*
# The List ADT
data List a => Nil | Cons a (List a)
Type class definitions define type classes, which associate a set of definitions one or more types/type constructors. Definitions in type classes may have default implementations.
<Class> ::= "class" <Identifier> <Identifier>+ [":" <ClassExpression> ["," <ClassExpression>]*] "{" <ClassDefinition>* "}"
# Type class for equality
class Eq a {
def eq: a -> a -> Bool
def ne: a -> a -> Bool
; a b => not $ eq a b
}
# Associative type class
class Associative a {
def append: a -> a -> a
}
Type class implementations define instances of type classes for some given types/type constructors.
<Impl> ::= "impl" ["for" <Identifier>* ["[" <ClassExpression>* "]"] "."] <Identifier> <TypePrimary>+ "{" <Definition>* "}"
impl for a. Associative (List a) {
def append => (++)
}
# state monad transformer implementation
impl for s m [Monad m]. Applicative (StateT s m) {
# elided...
}