はじめに

このガイドは、空の MoonBit モジュールから、arithmetic の各層を一度ずつ使うコードまでを案内する。続きは core チュートリアル で完全な作業を扱う。

インストールとインポート

パッケージを moon.mod に追加する:

moon add Luna-Flow/arithmetic@0.5.0

それを使うすべてのパッケージの moon.pkg で、Luna Flow のコードが使う別名を付けてインポートする:

import {
  "Luna-Flow/arithmetic" @lf_arith,
}

Ring や Field のような代数トレイトも必要なら、Luna-Flow/luna-generic を別名 @lf_alg で追加する。

型ではなく能力を求める

使うトレイトに対して関数を書く。Add と Mul は MoonBit の演算子トレイトであり、Sqrt はこのパッケージから来る:

fn[T : Add + Mul + @lf_arith.Sqrt] norm2(x : T, y : T) -> T {
  @lf_arith.Sqrt::sqrt(x * x + y * y)
}

test "norm" {
  inspect(norm2(3.0, 4.0), content="5")
}

norm2 は Float、Double、そして三つのトレイトを実装した独自の任意の型を受け付ける。

失敗を明示する

検査付きトレイトは Result を返す。ArithmeticContext を渡すこと。ネイティブのインスタンスはそれを読まないが、十進バックエンドなら読む:

test "checked division" {
  let ctx = @lf_arith.ArithmeticContext::decimal64()
  inspect(@lf_arith.DivChecked::div_checked(1.0, 8.0, ctx).unwrap(), content="0.125")
  match @lf_arith.DivChecked::div_checked(1.0, 0.0, ctx) {
    Ok(_) => fail("unexpected quotient")
    Err(e) => inspect(e.message, content="division by zero")
  }
}

診断を読む

コンテキスト付きトレイトは診断も返す。224+12^{24} + 1 を Float に変換すると最後のビットが失われ、結果がそれを伝える:

test "contextual conversion" {
  let ctx = @lf_arith.ArithmeticContext::new(24)
  let out : @lf_arith.ArithmeticOutcome[Float] = @lf_arith.IntegralContextual::from_int_contextual(
    16_777_217, ctx,
  ).unwrap()
  inspect(out.value, content="16777216")
  inspect(out.diagnostics.inexact, content="true")
}

Float と Double のコンテキスト付き演算の多くは丸めを検出しない。どれが検出するかは API ページ に書いてある。

次に読むもの