feat: add comprehensive example programs

Standard examples (examples/standard/):
- hello_world: Basic effect usage
- fizzbuzz: Classic programming exercise
- factorial: Recursive and tail-recursive versions
- primes: Prime number generation
- guessing_game: Interactive Random + Console effects
- stdlib_demo: Demonstrates List, String, Option, Math modules

Showcase examples (examples/showcase/):
- ask_pattern: Resumable effects for config/environment
- custom_logging: Custom effect with handler
- early_return: Fail effect for clean error handling
- effect_composition: Combining multiple effects
- higher_order: Closures and function composition
- pattern_matching: ADTs and exhaustive matching

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 17:25:04 -05:00
parent d8e01fd174
commit 0b5abece5f
12 changed files with 404 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
// Factorial - compute n!
// Recursive version
fn factorial(n: Int): Int =
if n <= 1 then 1
else n * factorial(n - 1)
// Tail-recursive version (optimized)
fn factorialTail(n: Int, acc: Int): Int =
if n <= 1 then acc
else factorialTail(n - 1, n * acc)
fn factorial2(n: Int): Int = factorialTail(n, 1)
fn main(): Unit with {Console} = {
Console.print("Factorial examples:")
Console.print("5! = " + toString(factorial(5)))
Console.print("10! = " + toString(factorial(10)))
Console.print("20! = " + toString(factorial2(20)))
}
let output = run main() with {}

View File

@@ -0,0 +1,22 @@
// FizzBuzz - print numbers 1-100, but:
// - multiples of 3: print "Fizz"
// - multiples of 5: print "Buzz"
// - multiples of both: print "FizzBuzz"
fn fizzbuzz(n: Int): String =
if n % 15 == 0 then "FizzBuzz"
else if n % 3 == 0 then "Fizz"
else if n % 5 == 0 then "Buzz"
else toString(n)
fn printFizzbuzz(i: Int, max: Int): Unit with {Console} =
if i > max then ()
else {
Console.print(fizzbuzz(i))
printFizzbuzz(i + 1, max)
}
fn main(): Unit with {Console} =
printFizzbuzz(1, 100)
let output = run main() with {}

View File

@@ -0,0 +1,25 @@
// Number guessing game - demonstrates Random and Console effects
fn gameLoop(secret: Int, attempts: Int): Unit with {Console} = {
Console.print("Guess the number (1-100), attempt " + toString(attempts) + ":")
let guess = Console.readInt()
if guess == secret then
Console.print("Correct! You got it in " + toString(attempts) + " attempts!")
else if guess < secret then {
Console.print("Too low!")
gameLoop(secret, attempts + 1)
}
else {
Console.print("Too high!")
gameLoop(secret, attempts + 1)
}
}
fn main(): Unit with {Console, Random} = {
Console.print("Welcome to the Guessing Game!")
Console.print("I'm thinking of a number between 1 and 100...")
let secret = Random.int(1, 100)
gameLoop(secret, 1)
}
let output = run main() with {}

View File

@@ -0,0 +1,7 @@
// The classic first program
// Expected output: Hello, World!
fn main(): Unit with {Console} =
Console.print("Hello, World!")
let output = run main() with {}

View File

@@ -0,0 +1,29 @@
// Prime number utilities
fn isPrime(n: Int): Bool =
if n < 2 then false
else isPrimeHelper(n, 2)
fn isPrimeHelper(n: Int, i: Int): Bool =
if i * i > n then true
else if n % i == 0 then false
else isPrimeHelper(n, i + 1)
// Find first n primes
fn findPrimes(count: Int): Unit with {Console} =
findPrimesHelper(2, count)
fn findPrimesHelper(current: Int, remaining: Int): Unit with {Console} =
if remaining <= 0 then ()
else if isPrime(current) then {
Console.print(toString(current))
findPrimesHelper(current + 1, remaining - 1)
}
else findPrimesHelper(current + 1, remaining)
fn main(): Unit with {Console} = {
Console.print("First 20 prime numbers:")
findPrimes(20)
}
let output = run main() with {}

View File

@@ -0,0 +1,43 @@
// Standard Library Demo
// Demonstrates the built-in modules: List, String, Option, Math
fn main(): Unit with {Console} = {
Console.print("=== List Operations ===")
let nums = [1, 2, 3, 4, 5]
Console.print("Original: " + toString(nums))
Console.print("Mapped (*2): " + toString(List.map(nums, fn(x: Int): Int => x * 2)))
Console.print("Filtered (even): " + toString(List.filter(nums, fn(x: Int): Bool => x % 2 == 0)))
Console.print("Sum (fold): " + toString(List.fold(nums, 0, fn(acc: Int, x: Int): Int => acc + x)))
Console.print("Length: " + toString(List.length(nums)))
Console.print("Reversed: " + toString(List.reverse(nums)))
Console.print("Range 1-5: " + toString(List.range(1, 6)))
Console.print("")
Console.print("=== String Operations ===")
let text = " Hello, World! "
Console.print("Original: \"" + text + "\"")
Console.print("Trimmed: \"" + String.trim(text) + "\"")
Console.print("Upper: " + String.toUpper(text))
Console.print("Lower: " + String.toLower(text))
Console.print("Contains 'World': " + toString(String.contains(text, "World")))
Console.print("Split by comma: " + toString(String.split("a,b,c", ",")))
Console.print("Join with dash: " + String.join(["x", "y", "z"], "-"))
Console.print("")
Console.print("=== Option Operations ===")
let some_val = Some(42)
let none_val: Option<Int> = None
Console.print("Some(42) mapped (*2): " + toString(Option.map(some_val, fn(x: Int): Int => x * 2)))
Console.print("None mapped: " + toString(Option.map(none_val, fn(x: Int): Int => x * 2)))
Console.print("Some(42) getOrElse(0): " + toString(Option.getOrElse(some_val, 0)))
Console.print("None getOrElse(0): " + toString(Option.getOrElse(none_val, 0)))
Console.print("")
Console.print("=== Math Operations ===")
Console.print("abs(-5): " + toString(Math.abs(-5)))
Console.print("min(3, 7): " + toString(Math.min(3, 7)))
Console.print("max(3, 7): " + toString(Math.max(3, 7)))
Console.print("pow(2, 10): " + toString(Math.pow(2, 10)))
}
let output = run main() with {}