Alex Craft
Alex Craft

Reputation: 15356

How to pass method to block in Crystal

How to pass plus into calculate method?

def calculate(&block : (Float64, Float64) -> Float64)
  block.call(1.1, 2.2)
end

def plus(a, b)
  a + b
end

calculate{|a, b| plus a, b}

This won't work

calculate ->plus
calculate &plus

P.S.

Another question, how to make it to work for all numbers? Not just Float64. This code won't compile and complain about requiring more specific type than Number

def calculate(&block : (Number, Number) -> Number)
  block.call(1, 2)
end

Ideally it would be nice to make it generalised so that typeof(block.call(1, 2)) => Int32 and typeof(block.call(1.1, 2.2)) => Float64

Upvotes: 3

Views: 491

Answers (2)

Johannes Müller
Johannes Müller

Reputation: 5661

A generalized solution could work with free variables, but there's a catch because free variables can't be derived from block arguments:

def calculate(&block : (T, T) -> T) forall T # Error: undefined constant T

This is because block arguments can't be overloaded since they can simply be captured blocks without type restrictions.

There are two options to make this work:

  1. You can pass the type for T explicitly as an argument. This is a bit more verbose but works with a captured block argument.
def plus(a, b)
  a + b
end

def calculate(t : T.class, &block : (T, T) -> T) forall T
  block.call(1.1, 2.2)
end

calculate(Float64, &->plus(Float64, Float64))
  1. You can change the captured block argument to a normal argument receiving a Proc:
def plus(a, b)
  a + b
end

def calculate(block : (T, T) -> T) forall T
  block.call(1.1, 2.2)
end

calculate(->plus(Float64, Float64))

Upvotes: 2

erasing
erasing

Reputation: 526

How to pass plus into calculate method?

You're looking for

calculate(&->plus(Float64, Float64))

Where ->plus(Float64, Float64) returns a Proc. Mind that you have to specify the type of the arguments - see the section From methods in the reference manual.

how to make it to work for all numbers?

I'd look into forall - see the section on Free variables in the reference manual.

Upvotes: 6

Related Questions