ruby中的功能代码示例

时间:2010-09-30 17:53:07

标签: ruby functional-programming rubygems

我正在寻找ruby中的功能代码示例。也许你知道一些宝石,我可以在哪里找到这样的代码?

6 个答案:

答案 0 :(得分:7)

我一直在收集Ruby的函数式编程示例:

答案 1 :(得分:4)

你看过Enumerable吗?

(1..100).select { |i| i % 5 == 0 }.map { |i| i * 5 }.take(3) #=> [25, 50, 75]

答案 2 :(得分:4)

几个月前,我想知道是否有可能制作一个行为完全的mixin,如Enumerable,但基于折叠而不是枚举。或者更确切地说,我已经知道可以这样做,因为 fold 是一个通用的迭代操作,它具有与 foreach ,但我想知道它会是什么样子,它会有多难。

在我实现大多数方法之后,我感到无聊,直到字母 g ,所以它不完整。此外,我在这里展示的版本是简化的,因为它的行为完全Enumerable一样是Ruby中的PITA。 (例如,那里有重载方法,但Ruby不支持重载。对于大多数Ruby实现来说这不是问题,因为它们用Java或C#或做的其他语言实现Enumerable 支持重载,但在纯Ruby中执行它时非常痛苦,所以我决定将其删除。)

Enumerable充满了高阶程序,当然 fold (或者reduce / inject因为它在Ruby中被调用)是本身一个更高阶的程序,所以这段代码充满了它们。

module Enumerable
  def all?
    reduce(true) {|res, el| res && yield(el) }
  end

  def any?
    reduce(false) {|res, el| res || yield(el) }
  end

  def collect
    reduce([]) {|res, el| res + yield(el) }
  end
  alias_method :map, :collect

  def count
    reduce(0) {|res, el| res + 1 if yield el }
  end

  def detect
    reduce(nil) {|res, el| if yield el then el end unless res }
  end
  alias_method :find, :detect

  def drop(n=1)
    reduce([]) {|res, el| res.tap {|res| res + el unless n -= 1 >= 0 }}
  end

  def each
    reduce(nil) {|_, el| yield el }
  end

  def each_with_index
    reduce(-1) {|i, el| (i+1).tap {|i| yield el, i }}
  end

  def find_all
    reduce([]) {|res, el| res.tap {|res| res + el if yield el }}
  end
  alias_method :select, :find_all

  def grep(pattern)
    reduce([]) {|res, el| res.tap {|res| res + yield(el) if pattern === el }}
  end

  def group_by
    reduce(Hash.new {|hsh, key| hsh[key] = [] }) {|res, el| res.tap {|res|
        res[yield el] << el
    }}
  end

  def include?(obj)
    reduce(false) {|res, el| break true if res || el == obj }
  end

  def reject
    reduce([]) {|res, el| res.tap {|res| res + el unless yield el }}
  end
end

你会注意到我在某些地方使用副作用。我本可以在没有副作用的情况下编写它,但它本来会复杂得多。问题是我无法确保由mixin的客户端提供的reduce方法或核心库中的任何方法没有副作用。

另一个很好的例子是Ruby的Prelude库,它是Ruby中Haskell Prelude的一些部分(Haskell相当于Ruby的核心库)的实现。

答案 3 :(得分:2)

你可能会对Dean Wampler的“通过功能编程实现更好的Ruby”这个话题感兴趣,它展示了如何在Ruby中使用FP风格:

http://vimeo.com/6701329

汤姆斯图尔特还有“在Ruby中功能性思考”:

http://skillsmatter.com/podcast/ajax-ria/enumerators

答案 4 :(得分:1)

“Ruby编程语言”有半个章节,他们可以使用几个可枚举的附加内容来使ruby看起来像Haskell。

您可能还想浏览以前使用“Ruby”和“functional-programming”here标记的Stack Overflow问题。

答案 5 :(得分:0)

这不是漂亮或高效的代码。它解释了功能和非功能风格之间的区别。

在ruby中执行功能概念时需要考虑的一点是我们的vm不是为它构建的,因此如果没有透明的参考优化,你将会以功能样式进行更多的内存编写。

# non functional
class Post
  attr_accessor :title, :body
end

all_posts = []

# create a post
p = Post.new
p.title = "Hello world"
p.body  = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

# put post in the array
all_posts << p

# fix post title
all_posts[0].title = "Opps, fixed title"

#functional
class Post
  attr_reader :title, :body

  def initialize(attrs={})
    attrs.each {|k,v| instance_variable_set "@#{k.to_s}", v }
  end
end

all_posts = []

# create a post
p = Post.new({title: "Hello world", body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."})
# add to array via new array creation
all_posts = all_posts + [p] # be wary when all_posts is a very large collection!

old_post = p
p = Post.new({title: "Oops, fixed title", body: old_post.body})
all_posts = all_posts - [old_post] + [p]

我经常在我的博客上发表关于ruby的函数式编程:http://rubylove.io