どんな型でも遅延評価できるようにした。
Delay.new
には型とその適当な値も渡すようにした。
# $ crystal test5.cr # 遅延評価 class Delay(T) def initialize(init_v : T, &block : -> T) @func = block @flag = false @value = init_v 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) 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(Int32).new(0){self.pred.fact.*(self)} end # フィボナッチ def fib self.<=(1).if (self.==(0).if 0, 1), Delay(Int32).new(0){self.pred.fib.+(self.pred.pred.fib)} end # コラッツ (0 は無限ループ) def collatz self.==(1).if [1], Delay(Array(Int32)).new([0]){self.odd?.if Delay(Array(Int32)).new([0]){self.*(3).succ.collatz.unshift(self)}, Delay(Array(Int32)).new([0]){self.tdiv(2).collatz.unshift(self)} } end def hoge2 self.<=(0).if "1", Delay(String).new(""){"yaahhhh"} end end # 実行 puts 10.fact # => 3628800 puts (0..10).to_a.map &.fib # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] puts 3.collatz # => [3, 10, 5, 16, 8, 4, 2, 1] puts 3.hoge2