2

我在 F# 中有一个例子:

let a n = Convert.ToString(n:int32)

我可以说:

3 |> a

评估为"3"。Ruby 中有类似的构造吗?

这是 F#(和其他 FP 语言)的方法链接,它不是函数组合,也不是 Ruby 中的方法链接,即返回 self 的对象,以便可以调用对象上的其他方法,如a.b.c.d.

4

3 回答 3

5

这在 Ruby 中很容易实现。直接取自 F# 参考文档:

let function1 x = x + 1
let function2 x = x * 2

let result = 100 |> function1 |> function2
//> val result : int = 202

这可以用 Ruby 编写如下:

function1 = -> x { x + 1 }
function2 = -> x { x * 2 }

result = 100.pipe(function1).pipe(function2)
# => 202

通过以下实现Object#pipe

class Object
  def pipe(callable)
    callable.(self)
  end
end

或者用你的例子:

a = -> n { String(n) }

3.pipe(a)
# => '3'

let f x y = x * y

3 |> f(2)
// > 6

变成

f = -> (x, y) { x * y }

3.pipe(f.curry.(2))
# => 6
于 2013-10-13T04:33:36.197 回答
2

Ruby 不支持这种 F#/Ocaml/Haskel 表示法。虽然我相信你可以做点什么。但关键是你不应该。

如果你想以函数式的方式实现事物(这很棒),你可以使用Enumerableruby​​ 提供的功能 - injectmapselect等。

它将产生一个干净可读的 ruby​​ 代码,没有任何黑客攻击。

PS:这个问题+1。当我第一次开始使用 ruby​​ 时,我自己也问过这个问题。

于 2013-10-12T23:07:12.823 回答
1

没有这样的表示法,但您可以添加一个Object传递self给给定方法的方法。就像是:

class Object
  def pass_to(m)
    m.call(self)
  end
end

这将允许这样的调用:

def convert_to_string(n)
  n.to_s
end

def reverse_string(s)
  s.reverse
end

123
  .pass_to(method(:convert_to_string))
  .pass_to(method(:reverse_string))
#=> "321"

或使用 lamdas:

convert_to_string = -> n { n.to_s }
reverse_string = -> s { s.reverse }

123
  .pass_to(convert_to_string)
  .pass_to(reverse_string)
#=> "321"

这相当于将to_s消息发送到123(返回"123"),然后将reverse消息发送到"123"

123
  .to_s
  .reverse
#=> "321"
于 2013-10-13T00:10:39.340 回答