コラッツ予想がとけたらいいな2

自分の考察を書いていきます。

Crystal をやってみた その2(メソッドチェーン)

関連


メソッドチェーンでプログラムを書くことを考えている。
BoolInt にメソッドを追加して、ひとまず今の形になった。


階乗のプログラム

# crystal test4.cr

# 遅延評価
class Delay
  def initialize(&block : String -> Int32)
    @func = block
    @flag = false
    #@value = nil
    @value = 0
  end
  def force
    unless @flag
      ret = @func.call ""
      @value = ret.nil? ? raise("@func.call is nil. #{@func}") : ret
      @flag = true
    end
    @value
  end
end

# Bool 構造体にメソッドを追加
struct Bool
  def if(t, e)
    if_base t, e
  end

  def if_base(t, e)
    return t.responds_to?(:force) ? t.force : t if self
    e.responds_to?(:force) ? e.force : e
  end
end
# puts true.if "then", "else"

struct Int
  # 階乗
  def fact
    self.<=(0).if 1, Delay.new{self.-(1).fact.*(self)}
  end
end

# 実行
puts 10.fact # => 3628800


ここまでで分かった事

ブロック引数には型をつけなくてはいけない

現状、結果の型が Int32 に固定されている

マクロはインスタンスメソッド扱いでなく、クラスメソッド扱い

true.macro_if... じゃなくて Bool.macro_if... になってしまう
これでは目的に合わない

引数は先行評価される

if で選ばれない方は評価したくないので、本方式となった


続くかな?