---
Every Cure file should define a module:
module ModuleName do
export [function_name/1, TypeName]
# Module contents
end
Export declarations specify what's public:
export [
function_name/1, # Function with arity
TypeName, # Type constructor
constructor_name # Data constructor
]
Import from other modules (including standard library):
import Std.Core [Result, Option, ok/1, error/1]
import Std.List [map/2, filter/2, fold/3]
import Std.Io [print/1, println/1]
---
Single-line comments only:
# This is a comment
---
type Result(T, E) = Ok(T) | Error(E)
type Option(T) = Some(T) | None
type Ordering = Lt | Eq | Gt
Records define structured data with named fields:
record RecordName do
field1: Type1
field2: Type2
field3: Type3
end
record Point(T) do
x: T
y: T
end
# Create a record instance
let point = Point{x: 3.0, y: 4.0}
let payload = TrafficPayload{cycles_completed: 0, timer_events: 0, emergency_stops: 0}
# Match and extract fields
match point do
Point{x: x, y: y} when x == 0.0 and y == 0.0 ->
"Origin"
Point{x: x, y: y} when x > 0.0 and y > 0.0 ->
"First quadrant"
Point{x: _, y: y} when y == 0.0 ->
"On X-axis"
end
# Partial field matching (other fields ignored)
match person do
Person{age: age, score: score} when age < 18 and score >= 90 ->
"Outstanding young achiever"
end
---
def function_name(param1: Type1, param2: Type2): ReturnType =
expression
def length(list: List(T)): Nat =
match list do
[] -> Zero
[_ | t] -> Succ(length(t))
end
def filter(list: List(T), predicate: T -> Bool): List(T) =
match list do
[] -> []
[h | t] ->
let filtered_tail = filter(t, predicate)
match predicate(h) do
true -> [h | filtered_tail]
false -> filtered_tail
end
end
Lambda syntax: fn(params) -> expression end
# Simple lambda
let double = fn(x) -> x * 2 end
# Lambda with multiple params
let add = fn(x, y) -> x + y end
# Curried function application
let partial_func = func(h)
partial_func(fold(t, init, func))
---
match value do
pattern1 -> result1
pattern2 -> result2
_ -> default_result
end
Guards allow additional conditions on patterns using when:
match value do
x when x < 0 -> "Negative"
x when x == 0 -> "Zero"
x when x > 0 -> "Positive"
end
# Multiple conditions with logical operators
match n do
x when x >= 10 and x <= 20 -> "In range"
x when x < 10 or x > 20 -> "Out of range"
end
# Guards with record patterns
match point do
Point{x: x, y: y} when x > 0.0 and y > 0.0 ->
"First quadrant"
Point{x: x, y: _} when x == 0.0 ->
"On Y-axis"
end
match list do
[] -> # empty list
[h | t] -> # head and tail
[a, b, c] -> # exact length (if supported)
end
match result do
Ok(value) -> # success case
Error(err) -> # error case
end
match option do
Some(value) -> # present
None -> # absent
end
match list do
[] -> []
[h | t] ->
match predicate(h) do
true -> [h | filtered_tail]
false -> filtered_tail
end
end
---
Arrow notation for function types:
# Function taking T, returning U
T -> U
# Function taking two params
T -> U -> V
# Can be curried
def func(x: T): U -> V =
fn(y) -> result end
Generic type parameters:
def identity(x: T): T = x
def map(list: List(T), f: T -> U): List(U) = ...
---
42 # Int
3.14 # Float
"hello" # String
true # Bool
false # Bool
:atom_name # Atom
[] # Empty list
[1, 2, 3] # List of integers
[h | t] # Cons pattern/constructor
Check actual implementation before using tuples extensively.
---
x + y # Addition
x - y # Subtraction
x * y # Multiplication
x / y # Division (may be integer division)
x == y # Equality
x != y # Inequality
x < y # Less than
x > y # Greater than
x <= y # Less than or equal
x >= y # Greater than or equal
[element | list] # Cons (prepend)
str1 <> str2 # Diamond operator for string concatenation
---
Simple let syntax:
let variable = expression
let result = function_call()
Note: Use in for scoped let expressions (check if implemented):
let x = 5 in x + 10
---
Declare Erlang FFI functions:
curify function_name(param: Type): ReturnType = {module, function, arity}
Example:
curify print_raw(format: String, args: List(String)): Unit = {io, format, 2}
Natural numbers use Peano encoding:
Zero # Zero
Succ(n) # Successor of n
Example:
def length(list: List(T)): Nat =
match list do
[] -> Zero
[_ | t] -> Succ(length(t))
end
---
FSMs are defined with an initial payload record and transition arrows:
# Define a payload record for FSM state tracking
record PayloadName do
field1: Type1
field2: Type2
end
# FSM definition with initial payload values
fsm PayloadName{field1: value1, field2: value2} do
State1 --> |event1| State2
State1 --> |event2| State1
State2 --> |event3| State1
end
record TurnstilePayload do
coins_inserted: Int
people_passed: Int
denied_attempts: Int
end
fsm TurnstilePayload{coins_inserted: 0, people_passed: 0, denied_attempts: 0} do
Locked --> |coin| Unlocked
Locked --> |push| Locked
Unlocked --> |coin| Unlocked
Unlocked --> |push| Locked
end
import Std.Fsm [fsm_spawn/2, fsm_cast/2, fsm_advertise/2, fsm_state/1]
import Std.Pair [pair/2]
# Spawn an FSM instance
let fsm_pid = fsm_spawn(:PayloadName, initial_data)
# Give it a name
let adv_result = fsm_advertise(fsm_pid, :fsm_name)
# Send an event (with empty data list)
let empty_list = []
let event = pair(:event_name, empty_list)
let cast_result = fsm_cast(:fsm_name, event)
# Get current state
let current_state = fsm_state(:fsm_name)
Key Points:
:event_name)--> and |event| syntax---
match result do
Ok(value) -> # handle success
Error(err) -> # handle error
end
match option do
Some(value) -> # handle present value
None -> # handle absence
end
def map(list: List(T), f: T -> U): List(U) =
match list do
[] -> []
[h | t] -> [f(h) | map(t, f)]
end
def reverse(list: List(T), acc: List(T)): List(T) =
match list do
[] -> acc
[h | t] -> reverse(t, [h | acc])
end
# Function returns another function
def flip(f: A -> B -> C): B -> A -> C =
fn(b, a) ->
let g = f(a) in
g(b)
end
---
module ModuleName do ... endmatch ... do ... end blocksfn(params) -> body end syntaxlet name = value without semicolonsfunc(arg1, arg2) syntax# single-line commentsdo ... end blocks)---
Based on actual standard library, these features may not be implemented:
process name(...) do ... end - verify syntaxVector(T, n: Nat) - may not fully work yet"text #{expr}" - use <> for concatenation instead---
When creating examples:
---
module ExampleModule do
export [
main/0,
helper_function/1
]
# Import standard library functions
import Std.Core [Result, ok/1, error/1]
import Std.List [map/2, filter/2]
import Std.Io [print/1]
# Type definition
type MyType(T) = Constructor1(T) | Constructor2(String)
# Main function
def main(): Unit =
let result = helper_function(42)
print("Done")
# Helper with pattern matching
def helper_function(value: Int): Result(String, String) =
match value > 0 do
true -> ok("positive")
false -> error("non-positive")
end
end
---
This guide is based on actual working code in the Cure standard library. When in doubt, refer tolib/std/ directory for real examples.