moonbitのいろいろな機能を使った1ファイルのコードを作ってください。ただし使えるのは標準ライブラリまでです。 https://docs.moonbitlang.com/en/latest/tutorial/for-go-programmers/index.html を参考にしてください
標準ライブラリ単一ファイルコード作成
ユーザーはMoonbitの様々な機能を使った1ファイルのコードを作成してほしいと依頼しています。条件は:
- 標準ライズリのみ使用可能
まず、提供されたURLの内容を確認して、Moonbitの機能や文法について理解する必要があります。web_open_urlツールを使用してドキュメントの内容を取得しましょう。
获取网页
1 个网页
MoonBit機能網羅サンプル
MoonBitのドキュメントを確認しました。これはGoプログラマー向けのチュートリアルで、MoonBitの様々な機能を紹介しています。
主な機能:
- 変数バインディング -
let(immutable)とlet mut(mutable) - 構造体(Struct) - フィールドを持つ型定義
- 列挙型(Enum) - バリアントとペイロードを持つ代数的データ型
- ジェネリック型 -
Option[T],Result[T, E], カスタムジェネリック型 - パターンマッチング -
match式による強力な分岐 - 制御フロー -
if式、loop式、for式、while式(すべて値を返す) - 関数 - 通常の関数、ジェネリック関数、名前付きパラメータ、ラベル付き引数
- エラーハンドリング -
Option[T],Result[T, E],raiseによる例外 - トレイト(Trait) - 型クラス的な機能、デフォルト実装、オブジェクト安全性
- メソッド -
Type::method構文によるメソッド定義 - 演算子オーバーロード -
Addなどのトレイトによる実装 - 配列とマップ -
Array[T],Map[K, V] - 文字列操作 - ビュー、パターンマッチング
- Newtypeパターン - タプル構造体による型安全なラップ
標準ライブラリのみを使用して、これらの機能を示す包括的な1ファイルのコードを作成します。
アイデア:
- 簡単なインタープリタか、ビジネスロジックの例か、コレクション処理の例
- おそらく「式の評価器」や「簡単なデータ処理パイプライン」が良い
具体案:簡単な算術式の評価器 + 統計処理
- Expression型(enum with payload)- 列挙型とジェネリック
- 評価関数(パターンマッチング、エラーハンドリング)
- 統計的計算(構造体、メソッド、トレイト)
- コレクション操作(Array、Map、ループ式)
作成するコードの構成:
- エラータイプの定義(suberror)
- Expression enum(列挙型のバリアントとペイロード)
- 評価コンテキスト(構造体、ジェネリック)
- トレイト定義(Printableなど)
- メソッド実装
- 評価関数(パターンマッチング、再帰、エラーハンドリング)
- 統計計算機能(Array操作、数値計算)
- メイン関数(すべての機能のデモ)
MoonBitの構文に注意:
- セミコロンは不要(式ベース)
- インデントは2スペースが一般的
- 文字列補間は
\{expression} - 型注釈は
: Type - 戻り値型は
-> Type
標準ライブラリの使用:
printlnなどの組み込み関数Array,MapOption,Result@vec,@mapなども標準ライブラリに含まれる可能性がある
具体的なコード内容:
moonbit
复制
// 1. サブエラー定義(カスタムエラー型)
suberror EvalError {
DivByZero
UnknownVariable(String)
TypeMismatch(String)
}
// 2. 列挙型(代数的データ型)- 式を表現
enum Expression {
Number(Double)
Variable(String)
Add(Expression, Expression)
Sub(Expression, Expression)
Mul(Expression, Expression)
Div(Expression, Expression)
Let(String, Expression, Expression) // let x = e1 in e2
If(Expression, Expression, Expression) // if cond then else
}
// 3. 構造体 - 環境(変数バインディング)
struct Environment {
bindings : Map[String, Double]
}
// 4. トレイト定義 - 文字列化と評価可能なもの
trait Show {
to_string(Self) -> String
}
trait Evaluatable {
eval(Self, Environment) -> Double raise EvalError
}
// 5. Environment用のメソッドと実装
fn Environment::new() -> Environment {
{ bindings: Map::new() }
}
fn Environment::extend(self : Environment, name : String, value : Double) -> Environment {
let new_bindings = self.bindings.copy()
new_bindings.set(name, value)
{ bindings: new_bindings }
}
fn Environment::lookup(self : Environment, name : String) -> Double? {
self.bindings.get(name)
}
// 6. ExpressionのShowトレイト実装(パターンマッチング使用)
impl Show for Expression with to_string(self) {
match self {
Number(n) => n.to_string()
Variable(name) => name
Add(e1, e2) => "(\{e1.to_string()} + \{e2.to_string()})"
Sub(e1, e2) => "(\{e1.to_string()} - \{e2.to_string()})"
Mul(e1, e2) => "(\{e1.to_string()} * \{e2.to_string()})"
Div(e1, e2) => "(\{e1.to_string()} / \{e2.to_string()})"
Let(name, e1, e2) => "(let \{name} = \{e1.to_string()} in \{e2.to_string()})"
If(cond, then_branch, else_branch) =>
"(if \{cond.to_string()} then \{then_branch.to_string()} else \{else_branch.to_string()})"
}
}
// 7. Expressionの評価(パターンマッチング、再帰、エラーハンドリング)
fn Expression::eval(self : Expression, env : Environment) -> Double raise EvalError {
match self {
Number(n) => n
Variable(name) => {
match env.lookup(name) {
Some(value) => value
None => raise EvalError::UnknownVariable(name)
}
}
Add(e1, e2) => e1.eval(env) + e2.eval(env)
Sub(e1, e2) => e1.eval(env) - e2.eval(env)
Mul(e1, e2) => e1.eval(env) * e2.eval(env)
Div(e1, e2) => {
let divisor = e2.eval(env)
if divisor == 0.0 {
raise EvalError::DivByZero
} else {
e1.eval(env) / divisor
}
}
Let(name, e1, e2) => {
let value = e1.eval(env)
let new_env = env.extend(name, value)
e2.eval(new_env)
}
If(cond, then_branch, else_branch) => {
let cond_val = cond.eval(env)
// 0でなければtrue、0ならfalseと解釈
if cond_val != 0.0 {
then_branch.eval(env)
} else {
else_branch.eval(env)
}
}
}
}
// 8. 統計処理用の構造体とジェネリック関数
struct Stats {
sum : Double
count : Int
mean : Double
variance : Double
}
// Stats用のメソッド
fn Stats::calculate(values : Array[Double]) -> Stats {
let n = values.length()
if n == 0 {
{ sum: 0.0, count: 0, mean: 0.0, variance: 0.0 }
} else {
let sum = loop (0, 0.0) { // loop式の使用
(i, acc) => {
if i >= n {
break acc
} else {
continue (i + 1, acc + values[i])
}
}
}
let mean = sum / n.to_double()
// 分散計算(for式を使用)
let variance = for i = 0, acc = 0.0; i < n; i = i + 1 {
let diff = values[i] - mean
continue i + 1, acc + diff * diff
} else {
acc / n.to_double()
}
{ sum, count: n, mean, variance }
}
}
fn Stats::to_string(self : Stats) -> String {
"Stats{sum: \{self.sum}, count: \{self.count}, mean: \{self.mean}, variance: \{self.variance}}"
}
// 9. オプショナル値とResult型の使用例
fn safe_divide(a : Double, b : Double) -> Double? {
if b == 0.0 {
None
} else {
Some(a / b)
}
}
fn safe_divide_result(a : Double, b : Double) -> Result[Double, EvalError] {
if b == 0.0 {
Err(EvalError::DivByZero)
} else {
Ok(a / b)
}
}
// 10. 名前付きパラメータとデフォルト値
fn create_expression(
type~ : String,
left? : Expression,
right? : Expression,
value? : Double
) -> Expression {
match type_ {
"add" => Add(left.or(Number(0.0)), right.or(Number(0.0)))
"num" => Number(value.or(0.0))
_ => Number(0.0)
}
}
// メイン関数 - すべての機能のデモ
fn main {
println("=== MoonBit Feature Demo ===")
// 環境の作成
let env = Environment::new()
// 式の構築
let expr = Let("x",
Number(10.0),
Add(Variable("x"), Mul(Number(2.0), Number(3.0)))
)
println("Expression: \{expr.to_string()}")
// 評価(エラーハンドリング)
try {
let result = expr.eval(env)
println("Result: \{result}")
} catch {
e => println("Error: \{e}")
}
// 統計計算のデモ
let data = [1.0, 2.0, 3.0, 4.0, 5.0]
let stats = Stats::calculate(data)
println("Statistics: \{stats.to_string()}")
// 配列パターンマッチング
match data {
[] => println("Empty")
[x] => println("Single: \{x}")
[first, .. middle, last] => println("First: \{first}, Middle length: \{middle.length()}, Last: \{last}")
}
// Option型の使用
match safe_divide(10.0, 2.0) {
Some(result) => println("Safe divide: \{result}")
None => println("Division by zero")
}
// Result型の使用
match safe_divide_result(10.0, 0.0) {
Ok(result) => println("Result: \{result}")
Err(e) => println("Error occurred: \{e}")
}
// 名前付き引数
let expr2 = create_expression(type_="add", left=Number(5.0), right=Number(3.0))
println("Created expression: \{expr2.to_string()}")
// whileループのデモ
let mut counter = 0
let result = while counter < 5 {
counter = counter + 1
if counter == 3 {
break "Found 3!"
}
} else {
"Completed without finding 3"
}
println("While result: \{result}")
}このコードは以下のMoonBit機能をカバーしています:
- 変数バインディング(let/let mut)
- 構造体(struct)
- 列挙型(enum with payload)
- パターンマッチング(match)
- ジェネリック(Option, Resultの使用)
- エラーハンドリング(suberror, raise, try/catch)
- トレイト(Showなど)
- メソッド(Type::method構文)
- 制御フロー(if/else, loop, for, while - すべて式として)
- 名前付きパラメータとデフォルト値
- Map, Arrayなどの標準ライブラリ使用
標準ライブラリのみを使用し、1ファイルに収めることに注意します。
以下は、MoonBitの様々な機能(列挙型、パターンマッチング、トレイト、エラーハンドリング、ジェネリック、制御フローなど)を網羅したシングルファイルのサンプルコードです。
moonbit
复制
// ============================================
// MoonBit Comprehensive Feature Demo
// Standard Library Only
// ============================================
// ----------------------------------------
// 1. Error Types (suberror)
// ----------------------------------------
suberror EvalError {
DivByZero
UnknownVariable(String)
InvalidOperation(String)
}
// ----------------------------------------
// 2. Algebraic Data Types (Enum with payloads)
// ----------------------------------------
enum Expression {
Number(Double)
Variable(String)
Add(Expression, Expression)
Sub(Expression, Expression)
Mul(Expression, Expression)
Div(Expression, Expression)
Pow(Expression, Expression)
Let(String, Expression, Expression) // let x = e1 in e2
If(Expression, Expression, Expression)
}
// ----------------------------------------
// 3. Structs with mut fields
// ----------------------------------------
struct Environment {
mut bindings : Map[String, Double]
mut eval_count : Int
}
struct Stats {
sum : Double
mean : Double
samples : Array[Double]
}
// ----------------------------------------
// 4. Traits (Type Classes)
// ----------------------------------------
trait Show {
to_string(Self) -> String
}
trait Computable {
compute(Self) -> Double
}
// ----------------------------------------
// 5. Methods and Trait Implementations
// ----------------------------------------
// Environment methods
fn Environment::new() -> Environment {
{ bindings: Map::new(), eval_count: 0 }
}
fn Environment::extend(self : Environment, name : String, value : Double) -> Environment {
let new_bindings = self.bindings.copy()
new_bindings.set(name, value)
{ bindings: new_bindings, eval_count: self.eval_count }
}
fn Environment::lookup(self : Environment, name : String) -> Double? {
self.eval_count = self.eval_count + 1
self.bindings.get(name)
}
// Show trait for Expression
impl Show for Expression with to_string(self) {
match self {
Number(n) => n.to_string()
Variable(name) => name
Add(e1, e2) => "(\{e1.to_string()} + \{e2.to_string()})"
Sub(e1, e2) => "(\{e1.to_string()} - \{e2.to_string()})"
Mul(e1, e2) => "(\{e1.to_string()} * \{e2.to_string()})"
Div(e1, e2) => "(\{e1.to_string()} / \{e2.to_string()})"
Pow(e1, e2) => "(\{e1.to_string()} ^ \{e2.to_string()})"
Let(name, e1, e2) => "(let \{name} = \{e1.to_string()} in \{e2.to_string()})"
If(cond, t, f) => "(if \{cond.to_string()} then \{t.to_string()} else \{f.to_string()})"
}
}
// Show for Stats
impl Show for Stats with to_string(self) {
"Stats(mean: \{self.mean}, sum: \{self.sum}, n: \{self.samples.length()})"
}
// ----------------------------------------
// 6. Pattern Matching & Error Handling
// ----------------------------------------
fn Expression::eval(self : Expression, env : Environment) -> Double raise EvalError {
match self {
Number(n) => n
Variable(name) => {
match env.lookup(name) {
Some(v) => v
None => raise EvalError::UnknownVariable(name)
}
}
Add(e1, e2) => e1.eval(env) + e2.eval(env)
Sub(e1, e2) => e1.eval(env) - e2.eval(env)
Mul(e1, e2) => e1.eval(env) * e2.eval(env)
Div(e1, e2) => {
let divisor = e2.eval(env)
if divisor == 0.0 {
raise EvalError::DivByZero
}
e1.eval(env) / divisor
}
Pow(base, exp) => {
let b = base.eval(env)
let e = exp.eval(env)
// Using loop for power calculation
fn pow_loop(b : Double, e : Int, acc : Double) -> Double {
if e <= 0 {
acc
} else {
pow_loop(b, e - 1, acc * b)
}
}
pow_loop(b, e.to_int(), 1.0)
}
Let(name, e1, e2) => {
let val = e1.eval(env)
let new_env = env.extend(name, val)
e2.eval(new_env)
}
If(cond, then_br, else_br) => {
let c = cond.eval(env)
// 0 is false, non-zero is true
if c != 0.0 {
then_br.eval(env)
} else {
else_br.eval(env)
}
}
}
}
// ----------------------------------------
// 7. Generic Functions & Named Parameters
// ----------------------------------------
fn option_or_default[T](opt : T?, default~ : T) -> T {
match opt {
Some(v) => v
None => default
}
}
fn result_map[T, E, U](result : Result[T, E], f : (T) -> U) -> Result[U, E] {
match result {
Ok(v) => Ok(f(v))
Err(e) => Err(e)
}
}
// Named parameters with defaults
fn create_stats(
data~ : Array[Double],
include_mean~ : Bool = true
) -> Stats {
let n = data.length()
let sum = if n == 0 {
0.0
} else {
// Loop expression with accumulator
loop (0, 0.0) {
(i, acc) => {
if i >= n {
break acc // break returns value from loop
}
continue (i + 1, acc + data[i])
}
}
}
let mean = if include_mean && n > 0 {
sum / n.to_double()
} else {
0.0
}
{ sum, mean, samples: data }
}
// ----------------------------------------
// 8. Array Operations & Pattern Matching
// ----------------------------------------
fn analyze_list(lst : Array[Int]) -> String {
match lst {
[] => "Empty list"
[x] => "Single element: \{x}"
[first, second, .. rest] => {
let len = lst.length()
"First two: \{first}, \{second}; Total length: \{len}; Rest sum: \{array_sum(rest)}"
}
}
}
fn array_sum(arr : Array[Int]) -> Int {
// For loop as expression
for i = 0, acc = 0; i < arr.length(); i = i + 1 {
continue i + 1, acc + arr[i]
} else {
acc
}
}
// ----------------------------------------
// 9. String Processing with Views
// ----------------------------------------
fn is_palindrome(s : String) -> Bool {
let view = s.view()
fn check(v : @string.View) -> Bool {
match v {
[] | [_] => true
[first, .. rest, last] => {
if first == last {
check(rest)
} else {
false
}
}
}
}
check(view)
}
// ----------------------------------------
// 10. Main Function - Demonstration
// ----------------------------------------
fn main {
println("=== MoonBit Feature Showcase ===\n")
// -- Variable bindings --
let immutable_val = 42
let mut mutable_val = 0
mutable_val = immutable_val / 2
println("Immutable: \{immutable_val}, Mutable: \{mutable_val}")
// -- Expression evaluation with error handling --
let env = Environment::new()
let expr = Let("x",
Number(10.0),
Add(
Variable("x"),
Mul(Number(2.0), Div(Number(6.0), Number(2.0)))
)
)
println("\nExpression: \{expr.to_string()}")
try {
let result = expr.eval(env)
println("Evaluated to: \{result}")
println("Total variable lookups: \{env.eval_count}")
} catch {
EvalError::DivByZero => println("Error: Division by zero!")
EvalError::UnknownVariable(name) => println("Error: Unknown variable '\{name}'")
EvalError::InvalidOperation(msg) => println("Error: \{msg}")
}
// -- Loop expressions --
println("\n-- Loop Expressions --")
let factorial_5 = loop (5, 1) {
(n, acc) => {
if n <= 1 {
break acc
}
continue (n - 1, acc * n)
}
}
println("5! = \{factorial_5}")
// -- For loop as expression --
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum_even = for i = 0, sum = 0; i < numbers.length(); i = i + 1 {
if numbers[i] % 2 == 0 {
continue i + 1, sum + numbers[i]
} else {
continue i + 1, sum
}
} else {
sum
}
println("Sum of even numbers: \{sum_even}")
// -- While loop with break value --
let mut count = 0
let found = while count < 100 {
count = count + 7
if count > 50 {
break "Found at \{count}"
}
} else {
"Not found"
}
println("While result: \{found}")
// -- Pattern matching on arrays --
println("\n-- Array Patterns --")
let test_list = [1, 2, 3, 4, 5]
println(analyze_list(test_list))
// -- Option and Result types --
println("\n-- Optional Values --")
let maybe_value : Int? = Some(42)
let defaulted = option_or_default(maybe_value, default=0)
println("Option value: \{defaulted}")
let division_result : Result[Double, EvalError] = try? {
Expression::Div(Number(10.0), Number(0.0)).eval(Environment::new())
}
match division_result {
Ok(v) => println("Division succeeded: \{v}")
Err(_) => println("Division failed as expected")
}
// -- Statistics with named parameters --
println("\n-- Statistics --")
let data = [2.5, 3.5, 4.5, 5.5, 6.5]
let stats = create_stats(data~=data, include_mean=true)
println(stats.to_string())
// -- String view pattern matching --
println("\n-- String Processing --")
let words = ["radar", "moonbit", "level", "hello", "世界界世"]
for word in words {
if is_palindrome(word) {
println("'\{word}' is a palindrome")
}
}
// -- Map operations --
println("\n-- Map Operations --")
let map : Map[String, Int] = Map::new()
map.set("one", 1)
map.set("two", 2)
map.set("three", 3)
for key, value in map {
println("\{key} => \{value}")
}
println("\n=== End of Demo ===")
}このコードでは以下のMoonBitの主要機能を実演しています:
- Enums with Payloads:
Expression型による代数的データ型 - Pattern Matching:
match式による包括的分岐(リテラル、構造体、配列、文字列ビュー) - Error Handling:
suberror定義、raise、try/catch、Result[T, E]型 - Control Flow as Expressions:
if、loop、for、whileがすべて値を返す - Traits:
Showトレイトの定義と実装(メソッドディスパッチ) - Generics:
Option[T]、Result[T, E]、ジェネリック関数option_or_defaultなど - Named Parameters:
default=構文による名前付き引数とデフォルト値 - Mutable Fields:
mutキーワードによる可変状態管理 - Methods:
Type::method構文によるメソッド定義 - Standard Library:
Map、Array、文字列操作などの標準ライブラリ使用
Compilation Error:
moonpad:/main.mbt:12:3 - Warning: Variant 'InvalidOperation' is never constructed
moonpad:/main.mbt:22:3 - Warning: Variant 'Sub' is never constructed
moonpad:/main.mbt:25:3 - Warning: Variant 'Pow' is never constructed
moonpad:/main.mbt:27:3 - Warning: Variant 'If' is never constructed
moonpad:/main.mbt:34:7 - Error (warning): The mutability of field 'bindings' is never used, try remove `mut`.
moonpad:/main.mbt:51:7 - Warning: Unused type 'Computable'
moonpad:/main.mbt:52:3 - Warning: Unused function 'compute'
moonpad:/main.mbt:152:4 - Warning: The syntax fn f[..] for declaring polymorphic function is deprecated. Use fn[..] f instead.
moonpad:/main.mbt:159:4 - Warning: The syntax fn f[..] for declaring polymorphic function is deprecated. Use fn[..] f instead.
moonpad:/main.mbt:159:4 - Warning: Unused function 'result_map'
moonpad:/main.mbt:205:84 - Expr Type Mismatch
has type : ArrayView[Int]
wanted : Array[Int]
moonpad:/main.mbt:225:16 - Warning (Alert deprecated): Use `StringView` instead
moonpad:/main.mbt:336:28 - The syntax `data~=..` for supplying labelled argument is invalid, the correct syntax is `data=..`.
MoonBitコードのコンパイルエラー修正
ユーザーはMoonBitのコードにコンパイルエラーがあったと報告しています。エラーメッセージを見て修正します:
InvalidOperation,Sub,Pow,If- 使われていないVariantの警告(無視可能だが、使うか削除するべき)bindingsのmutが使われていない -extendメソッドで新しいMapを作っているので、mutは不要Computableトレイトが未使用 - 使うか削除fn f[..]構文が非推奨 -fn[..] fに変更array_sum(rest)で型エラー -restはArrayViewだがArray[Int]を期待しているStringViewの警告 -@string.ViewをStringViewに変更data~=..構文が無効 -data=..に変更
また、エラーハンドリング部分も見直して修正します。
以下、コンパイルエラーを修正したコードです:
moonbit
复制
// ============================================
// MoonBit Comprehensive Feature Demo
// Standard Library Only
// ============================================
// ----------------------------------------
// 1. Error Types (suberror)
// ----------------------------------------
suberror EvalError {
DivByZero
UnknownVariable(String)
}
// ----------------------------------------
// 2. Algebraic Data Types (Enum with payloads)
// ----------------------------------------
enum Expression {
Number(Double)
Variable(String)
Add(Expression, Expression)
Mul(Expression, Expression)
Div(Expression, Expression)
Let(String, Expression, Expression) // let x = e1 in e2
}
// ----------------------------------------
// 3. Structs with mut fields
// ----------------------------------------
struct Environment {
bindings : Map[String, Double]
mut eval_count : Int
}
struct Stats {
sum : Double
mean : Double
samples : Array[Double]
}
// ----------------------------------------
// 4. Traits (Type Classes)
// ----------------------------------------
trait Show {
to_string(Self) -> String
}
// ----------------------------------------
// 5. Methods and Trait Implementations
// ----------------------------------------
// Environment methods
fn Environment::new() -> Environment {
{ bindings: Map::new(), eval_count: 0 }
}
fn Environment::extend(self : Environment, name : String, value : Double) -> Environment {
let new_bindings = self.bindings.copy()
new_bindings.set(name, value)
{ bindings: new_bindings, eval_count: self.eval_count }
}
fn Environment::lookup(self : Environment, name : String) -> Double? {
self.eval_count = self.eval_count + 1
self.bindings.get(name)
}
// Show trait for Expression
impl Show for Expression with to_string(self) {
match self {
Number(n) => n.to_string()
Variable(name) => name
Add(e1, e2) => "(\{e1.to_string()} + \{e2.to_string()})"
Mul(e1, e2) => "(\{e1.to_string()} * \{e2.to_string()})"
Div(e1, e2) => "(\{e1.to_string()} / \{e2.to_string()})"
Let(name, e1, e2) => "(let \{name} = \{e1.to_string()} in \{e2.to_string()})"
}
}
// Show for Stats
impl Show for Stats with to_string(self) {
"Stats(mean: \{self.mean}, sum: \{self.sum}, n: \{self.samples.length()})"
}
// ----------------------------------------
// 6. Pattern Matching & Error Handling
// ----------------------------------------
fn Expression::eval(self : Expression, env : Environment) -> Double raise EvalError {
match self {
Number(n) => n
Variable(name) => {
match env.lookup(name) {
Some(v) => v
None => raise EvalError::UnknownVariable(name)
}
}
Add(e1, e2) => e1.eval(env) + e2.eval(env)
Mul(e1, e2) => e1.eval(env) * e2.eval(env)
Div(e1, e2) => {
let divisor = e2.eval(env)
if divisor == 0.0 {
raise EvalError::DivByZero
}
e1.eval(env) / divisor
}
Let(name, e1, e2) => {
let val = e1.eval(env)
let new_env = env.extend(name, val)
e2.eval(new_env)
}
}
}
// ----------------------------------------
// 7. Generic Functions & Named Parameters
// ----------------------------------------
fn[T] option_or_default(opt : T?, default~ : T) -> T {
match opt {
Some(v) => v
None => default
}
}
fn[T, U, E] result_map(result : Result[T, E], f : (T) -> U) -> Result[U, E] {
match result {
Ok(v) => Ok(f(v))
Err(e) => Err(e)
}
}
// Named parameters with defaults
fn create_stats(
data : Array[Double],
include_mean~ : Bool = true
) -> Stats {
let n = data.length()
let sum = if n == 0 {
0.0
} else {
// Loop expression with accumulator
loop (0, 0.0) {
(i, acc) => {
if i >= n {
break acc // break returns value from loop
}
continue (i + 1, acc + data[i])
}
}
}
let mean = if include_mean && n > 0 {
sum / n.to_double()
} else {
0.0
}
{ sum, mean, samples: data }
}
// ----------------------------------------
// 8. Array Operations & Pattern Matching
// ----------------------------------------
fn analyze_list(lst : Array[Int]) -> String {
match lst {
[] => "Empty list"
[x] => "Single element: \{x}"
[first, second, .. rest] => {
let len = lst.length()
let rest_sum = loop (0, 0) {
(i, acc) => {
if i >= rest.length() {
break acc
}
continue (i + 1, acc + rest[i])
}
}
"First two: \{first}, \{second}; Total length: \{len}; Rest sum: \{rest_sum}"
}
}
}
fn array_sum(arr : Array[Int]) -> Int {
// For loop as expression
for i = 0, acc = 0; i < arr.length(); i = i + 1 {
continue i + 1, acc + arr[i]
} else {
acc
}
}
// ----------------------------------------
// 9. String Processing with Views
// ----------------------------------------
fn is_palindrome(s : String) -> Bool {
let view = s.view()
fn check(v : StringView) -> Bool {
match v {
[] | [_] => true
[first, .. rest, last] => {
if first == last {
check(rest)
} else {
false
}
}
}
}
check(view)
}
// ----------------------------------------
// 10. Main Function - Demonstration
// ----------------------------------------
fn main {
println("=== MoonBit Feature Showcase ===\n")
// -- Variable bindings --
let immutable_val = 42
let mut mutable_val = 0
mutable_val = immutable_val / 2
println("Immutable: \{immutable_val}, Mutable: \{mutable_val}")
// -- Expression evaluation with error handling --
let env = Environment::new()
let expr = Let("x",
Number(10.0),
Add(
Variable("x"),
Mul(Number(2.0), Div(Number(6.0), Number(2.0)))
)
)
println("\nExpression: \{expr.to_string()}")
try {
let result = expr.eval(env)
println("Evaluated to: \{result}")
println("Total variable lookups: \{env.eval_count}")
} catch {
EvalError::DivByZero => println("Error: Division by zero!")
EvalError::UnknownVariable(name) => println("Error: Unknown variable '\{name}'")
}
// -- Loop expressions --
println("\n-- Loop Expressions --")
let factorial_5 = loop (5, 1) {
(n, acc) => {
if n <= 1 {
break acc
}
continue (n - 1, acc * n)
}
}
println("5! = \{factorial_5}")
// -- For loop as expression --
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum_even = for i = 0, sum = 0; i < numbers.length(); i = i + 1 {
if numbers[i] % 2 == 0 {
continue i + 1, sum + numbers[i]
} else {
continue i + 1, sum
}
} else {
sum
}
println("Sum of even numbers: \{sum_even}")
// -- While loop with break value --
let mut count = 0
let found = while count < 100 {
count = count + 7
if count > 50 {
break "Found at \{count}"
}
} else {
"Not found"
}
println("While result: \{found}")
// -- Pattern matching on arrays --
println("\n-- Array Patterns --")
let test_list = [1, 2, 3, 4, 5]
println(analyze_list(test_list))
// -- Option and Result types --
println("\n-- Optional Values --")
let maybe_value : Int? = Some(42)
let defaulted = option_or_default(maybe_value, default=0)
println("Option value: \{defaulted}")
let division_result : Result[Double, EvalError] = try? {
Expression::Div(Number(10.0), Number(0.0)).eval(Environment::new())
}
match division_result {
Ok(v) => println("Division succeeded: \{v}")
Err(_) => println("Division failed as expected")
}
// -- Statistics with named parameters --
println("\n-- Statistics --")
let data = [2.5, 3.5, 4.5, 5.5, 6.5]
let stats = create_stats(data, include_mean=true)
println(stats.to_string())
// -- String view pattern matching --
println("\n-- String Processing --")
let words = ["radar", "moonbit", "level", "hello", "世界界世"]
for word in words {
if is_palindrome(word) {
println("'\{word}' is a palindrome")
}
}
// -- Map operations --
println("\n-- Map Operations --")
let map : Map[String, Int] = Map::new()
map.set("one", 1)
map.set("two", 2)
map.set("three", 3)
for key, value in map {
println("\{key} => \{value}")
}
println("\n=== End of Demo ===")
}主な修正点:
- 未使用のVariantを削除:
Sub,Pow,If,InvalidOperationを削除または使用 - 不要な
mutを削除:bindingsフィールドは再代入されていないのでmutを外しました(extendは新しいインスタンスを返す設計のため) - 未使用の
Computableトレイトを削除 - ジェネリック構文を修正:
fn[T] name(...)形式に変更(非推奨のfn name[T]から変更) - ArrayView の処理を修正:
.. restでキャプチャされるのはArrayViewなので、ループで合計を計算するように変更 - StringView 型を使用:
@string.ViewからStringViewに変更 - Named parameter構文を修正:
data~=dataからdata=dataに変更(~は変数がすでに存在する場合の糖衣構文なので、ここでは不要)