🕌

Dfinity Examples を動かしてみる (その3 factorial編)

2021/10/01に公開

1. Dfinity Examples とは

Dfinityの gitに examples という motokoのサンプルプログラムがある。これを動かして触ってみることで motokoの基本を身につけさせようということだね。

今回はfactorial というシンプルなプログラムを動かしてみる。ちなみにfactorialというのは階乗という意味らしい。

factorial

このプログラムは、入力値以下のすべての正の整数の積を計算する再帰的なプログラムのようだ。たとえば、3を入力した場合、3 x 2 x 1 で 6を返す、みたいなものだろう。

わざわざIC上で動かすほどのものでもないので、ローカルで動かしてみたい。

2. 事前準備

事前準備は「その1 calc編」で完了しているので省略。

3. ローカルネットワークでの動作確認

dfx.json

factorial も calcと同じように Main.mo だけのシンプルなプログラムで、dfx.jsonも超シンプル。

$ cat dfx.json 
{
  "canisters": {
    "factorial": {
      "main": "src/Main.mo"
    }
  },
  "dfx": "0.7.2"
}

dfx の起動とキャニスターのインストール

$ cd examples/motoko/factorial
$ dfx start

ローカルネットワークを起動し、別ターミナルで、キャニスターを作成。

$ dfx canister create --all
Creating a wallet canister on the local network.
The wallet canister on the "local" network for user "default" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
Creating canister "factorial"...
"factorial" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"

Walletキャニスターは defaultアカウント用のもので、前回と同じものだった。
そして、factorialキャニスターも前回と同じIDだった。設定等で特に指定はされていないので、ローカルで立ち上げる場合はこのIDになるのかもしれない。

つづいて、ビルドとインストール。いつもの手順だ。

$ dfx build
$ dfx canister install --all
Creating UI canister on the local network.
The UI canister on the "local" network is "ryjl3-tyaaa-aaaaa-aaaba-cai"
Installing code for canister factorial, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai

うーん、やはり前回とまったく同じキャニスターIDが割り当てられる。

factorialを動かしてみる

3を入れてみる

$ dfx canister call factorial fac '(3)'
(6)

やはり6になった。

10を入れてみる

$ dfx canister call factorial fac '(10)'
(3_628_800)

おー、こんなに大きくなるのか。。。。以上!

4. ソースを読む

ソースはMain.moだけでしかも短い。

$ cat src/Main.mo 
actor Factorial {

  // Calculate the product of all positive integers less than or equal to `n`.
  public query func fac(n : Nat) : async Nat {

    // We implement the recustion in a helper function that does not return
    // asynchronously.
    func go(m : Nat) : Nat {
      if (m == 0) {
	return 1;
      } else {
	return m * go(m - 1);
      };
    };

    // Return.
    return go(n);
  };
};

facという関数の中に goという関数があって、入力した数字(m)と go(m - 1)を掛けている?

ん、なんか意外と難しい。return go(n)のnはどこから出てきたんだ?

。。。。まあ、よしとしよう。

Discussion