読者です 読者をやめる 読者になる 読者になる

アヤチノオト

覚書のこと

D言語でMaybeモナドのようなもの

インターフェイスを使ってMonadを作りたかったんだけどそれはやり方がよく分からなかった。

import std.conv;
import std.stdio;

void main()
{
  auto a0 = Maybe!(int).just(8);       // Maybe Int
  writeln(a0);                         // Just 8
  auto a1 = a0.bind(&plus);            // Maybe Int
  writeln(a1);                         // Just 9
  writeln(a1.bind(&plus).bind(&plus)); // Nothing
}

// 整数iを受け取って10より小さいならJust (i+1)を返す、
// 10以上ならNothingを返す関数plus
Maybe!(int) plus(int i) {
  if (i < 10) {
    return Maybe!(int).just(i + 1);
  } else {
    return Maybe!(int).nothing();
  }
};

// 何か値を一つ持ってるかもしれないし持ってないかもしれない物のクラス
class Maybe(T)
{
  private T value;
  private bool has_value = false;

  // 何か値があるとき用コンストラクタ
  private this(T a)
  {
    value = a;
    has_value = true;
  }

  // なにも値がないとき用コンストラクタ
  private this()
  {
    has_value = false;
  }

  static Maybe!(T) just(T a)
  {
    return new Maybe!(T)(a);
  }

  static Maybe!(T) nothing()
  {
    return new Maybe!(T)();
  }

  override public string toString()
  {
    if (has_value) {
      return "Just " ~ to!(string)(value);
    } else {
      return "Nothing";
    }
      
  }

  // bind :: Maybe!(T) m => (a -> m a) -> m a
  public Maybe!(T) bind(Maybe!(T) function(T) f)
  {
    if (this.has_value) {
      return f(value);
    } else {
      return this; // Nothing なら何もしない
    }
  }
}