自由モノイドプログラミング言語の作成(MonIter バージョン1.2 仕様(17))
変数とその値の対応を記憶するためのクラス
変数とその値の対応を記憶する線形リストを保持するクラス(Env<T>)
Env<T> は線形リスト(LinearList<EnvItem<T>>)を保持します。
Env<T> は IEnumerable<EnvItem<T>> を実装するクラスとします。
/// <summary> /// 変数と変数の値の対応を表す「環境」のクラス /// </summary> /// <typeparam name="T">変数の型</typeparam> internal class Env<T> : IEnumerable<EnvItem<T>> { /// <summary> /// 変数と変数の値の対応を保存する線形リスト /// </summary> private LinearList<EnvItem<T>> list; /// <summary> /// 変数と変数の値の対応を初期化 /// </summary> public Env() { list = new LinearList<EnvItem<T>>(); } /// <summary> /// IEnumerable 実装のために必要なイテレーターを取得するメソッド /// </summary> /// <returns>IEnumerable のイテレーター</returns> public IEnumerator<EnvItem<T>> GetEnumerator() { return list.GetEnumerator(); } /// <summary> /// IEnumerable 実装のために必要なイテレーターを取得するメソッド /// </summary> /// <returns>IEnumerable のイテレーター</returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// <summary> /// 変数とその値の対応を追加する /// </summary> /// <param name="key">変数名</param> /// <param name="value">値</param> /// <returns>変数とその値の対応を追加した「環境」</returns> public Env<T> Define(string key, T value) { Env<T> env = new Env<T>(); env.list = list.Define(new EnvItem<T>(key, value)); return env; } /// <summary> /// 複数の変数とその値の対応を追加する /// </summary> /// <param name="keys">変数のリスト</param> /// <param name="values">値のリスト</param> /// <returns>変数とその値の対応を追加した「環境」</returns> public Env<T> DefineList(IEnumerable<string> keys, IEnumerable<T> values) { Env<T> env = this; foreach ((string key, T value) in keys.Zip(values)) { env = env.Define(key, value); } return env; } /// <summary> /// 変数の値を取得する /// </summary> /// <param name="key">変数</param> /// <returns>変数の値</returns> public T? Value(string key) { foreach (EnvItem<T> node in this) { if (node.Key == key) { return node.Value; } } return default; } }
変数と変数の値の組のクラス(EnvItem<T>)
/// <summary> /// 変数と変数の値の対応を保存する線形リストの項目のクラス /// </summary> /// <typeparam name="T">変数の型</typeparam> internal class EnvItem<T> { /// <summary> /// 変数名 /// </summary> private readonly string key; /// <summary> /// 変数の値 /// </summary> private readonly T value; public EnvItem(string key, T value) { this.key = key; this.value = value; } /// <summary> /// 変数名 /// </summary> public string Key => key; /// <summary> /// 変数の値 /// </summary> public T Value => value; }
数値の自由モノイドの元または数値を表すクラス(FreeMonoidUnion)
「数値を生成元とする自由モノイドの元」または「数値」のどちらかを保持するクラス(C# では「どちらか」を表す良い方法がないのでこのクラスがあります)なのですが、現状ではユーザーが定義できる関数はパラメーターの型が数値のものだけなので数値の方しか使われていません。
/// <summary> /// 数値の自由モノイドの元または数値を表すクラス /// </summary> internal class FreeMonoidUnion { /// <summary> /// 数値のときの値 /// </summary> private readonly Number? domain_value; /// <summary> /// 数値の自由モノイドの元 /// </summary> private readonly FreeMonoid<int>? monoid_value; /// <summary> /// 数値の自由モノイドかどうか /// </summary> private readonly bool ismonoid; /// <summary> /// 数値のオブジェクトを作成 /// </summary> /// <param name="domain_value">数値</param> public FreeMonoidUnion(Number domain_value) { this.domain_value = domain_value; ismonoid = false; } /// <summary> /// 自由モノイドの元のオブジェクトを作成 /// </summary> /// <param name="monoid_value">自由モノイドの元</param> public FreeMonoidUnion(FreeMonoid<int> monoid_value) { this.monoid_value = monoid_value; ismonoid = true; } /// <summary> /// 数値の値 /// </summary> internal Number DomainValue => domain_value; }





