JoL
JoL

Reputation: 1137

Is there valid Ruby syntax for as-patterns in parameters like `[[1, 2]].map {|xy@(x, y)| [xy, x + y]}`?

Given that the following currently works in Ruby like a very limited version of Haskell's constructor pattern matching:

[[1,[2,3]]].map {|(x, (y, z))| x + y * z} #=> [7]

I wonder if it also supports a syntax for "as-patterns" (what Haskell calls them), which is basically putting multiple bindings on the same arguments, like so:

[[1,[2,3]]].map {|(x, yz@(y, z))| [x + y * z, yz]} #=> [7, [2,3]]

I tried @ and other symbols, but they all resulted in syntax errors.

Upvotes: 3

Views: 77

Answers (2)

Salil
Salil

Reputation: 47522

Not sure about the as-patterns but in ruby you can implement similar thing using lambda & proc

For 1st Pattern

2.3.1 :030 > pattern = Proc.new {|x, y, z| x + (y * z) }
 => #<Proc:0x007fa6fd5a2188@(irb):30> 
2.3.1 :031 > func = lambda { |arr| arr.map {|ar| pattern.call(*ar)} }
 => #<Proc:0x007fa6fddc1328@(irb):31 (lambda)> 
2.3.1 :032 > func.call([[1,2,3], [4,5,6]])
 => [7, 34] 

For 2nd Pattern

2.3.1 :033 > pattern = Proc.new {|x, y, z| [x + (y * z), [y, z]] }
 => #<Proc:0x007fa6ffba5150@(irb):33> 
2.3.1 :034 > func = lambda { |arr| arr.map {|ar| pattern.call(*ar)} }
 => #<Proc:0x007fa6fdd60aa0@(irb):34 (lambda)> 
2.3.1 :035 > func.call([[1,2,3], [4,5,6]])
 => [[7, [2, 3]], [34, [5, 6]]] 

Upvotes: 0

Jared Beck
Jared Beck

Reputation: 17538

As far as I know, ruby does not currently (2018-06-04) have that feature.

There isn't a formal spec of the ruby language to refer to, but there is The Ruby Spec Suite. Check out language/block_spec.rb for some weird and unusual examples of block params.

Block arguments are surprisingly powerful, and support optional args, splats, post-args, destructuring, nested destructuring, keyword arguments, block-level variables. It's pretty impressive.

If you can read C (I can't) and you really want to dig into this further, you can find the definition of block arguments in the interpreter grammar at parse.y:2980.

Upvotes: 2

Related Questions