微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – Ruby中的第一类函数

我正在通过这篇关于函数式编程的文章(https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming)并试图用Ruby做练习.

一个练习定义了两个函数,零和一个. Zero接受一个字符串参数并返回字符串索引1 – 如果第一个字符为0则结束,One执行相同的操作但仅当第一个字符为1时.

以下是ruby实现:

def zero(s)
  if s[0] == "0"
    return s[1..(s.length)]
  end
end

def one(s)
  if s[0] == "1"
    return s[1..(s.length)]
  end
end

问题要求你编写一个名为rule_sequence的方法,给定一个字符串和一个函数数组,返回结果,以便一次调用一个函数 – 第一个函数在整个字符串中被调用,第二个函数调用关于该字符串的返回值等.如果在任何时候,其中一个函数返回nil,则返回nil.

Python实现是:

def rule_sequence(s, rules):
    if s == None or not rules:
        return s
    else:
        return rule_sequence(rules[0](s), rules[1:])

但是,由于Ruby似乎不支持高阶函数,我能想出的最优雅的解决方案如下:

def rule_sequence(string, rules)
  if rules.length == 0 or string.nil?
    return string
  else
    return rule_sequence(rules[0].call(string), rules[1..rules.length])
  end
end

puts rule_sequence('0101', [lambda { |s| zero(s) }, lambda { |s| one(s) }, lambda { |s| zero(s) } ])

任何人都可以提出比传递或调用lambdas更简洁的东西吗?

解决方法:

我将以此练习为契机,展示Ruby如何支持更高阶的函数.

让我们退后一步,重写零 – 一个功能.
你可以注意到他们有很多共同之处.
让我们尝试通过编写一个可以生成两者的lambda来利用它

tail_on_prefix = lambda {|prefix|
  lambda {|str| str[1..-1] if str[0] == prefix}
}

我们现在可以轻松定义零和一

zero = tail_on_prefix.("0")
one = tail_on_prefix.("1")

到rule_sequence吧!

rule_sequence = lambda {|str, rules|
  if (str.nil? or rules.empty?)
    str
  else
    rule_sequence.(rules[0].(str), rules[1..-1])
  end
}

现在调用rule_sequence看起来好一点,不是吗

rule_sequence.("100101", [one, zero, zero]) # => "101"

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐