我正在寻找ruby中的功能代码示例。也许你知道一些宝石,我可以在哪里找到这样的代码?
答案 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风格:
汤姆斯图尔特还有“在Ruby中功能性思考”:
答案 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