是否可以将 Proc 传递给函数?

Is it possible to pass a Proc into a function?

我正在尝试将 Ruby 的函数组合运算符 << 实现到 Crystal 的过程中。在 Ruby 中似乎很简单。

  def << block
    proc { |*args| self.call( block.to_proc.call(*args) ) }
  end
end

我试过做类似的事情。

struct Proc
  def <<(&block)
    Proc.new { |*args, blk| call(block.call(*args, blk)) }
  end
end

我已经尝试使用简单的加法器和子函数对其进行测试

def add(x : Int32)
  x + 1
end

def sub(x : Int32)
  x - 1
end

但是,我遇到了这个错误。 Error: wrong number of arguments for 'Proc(Int32, Int32)#<<' (given 1, expected 0)

我也尝试过更改 << 以接受一个过程,但这也会导致 expected block type to be a function type, not Proc(*T, R)

我是这门语言的新手,所以我不太确定我缺少什么知识来理解为什么这不起作用。

您收到此错误是因为 Proc 未指定。 Proc 类型是泛型类型,需要使用描述其参数类型和 return 类型的特定泛型参数进行实例化。

您可以通过一个最小示例看到相同的行为:

Proc.new { 1 } # Error: expected block type to be a function type, not Proc(*T, R)

当然,错误信息不是很清楚。


您尝试实现的工作示例可能如下所示:

struct Proc
  def <<(block : Proc(*U, V)) forall U, V
    Proc(*T, V).new { |arg| call(block.call(arg)) }
  end
end

def add(x : Int32)
  x + 1
end
 
def sub(x : Int32)
  x - 1
end

x = ->add(Int32) << ->sub(Int32)
p! x.call(10)