2011-06-23 22 views
6

红宝石(和Per​​l)具有触发器的概念:在Perl或Ruby中是否存在与触发器运算符等效的函数式编程概念?

file = File.open("ordinal") 
while file.gets 
    print if ($_ =~ /third/) .. ($_ =~ /fifth/) 
end 

其中给予序的列表,如

first 
second 
third 
fourth 
fifth 
sixth 

,当它达到了“第三”将开始打印和停止时它达到“十五”:

third 
fourth 
fifth 

是否有功能的编程概念类似于此,或将这种通常在takewhile条款来描述?我不是在问一个特定的语言,只是用什么词来描述它。

+0

?有很多不同的方法,有些可能会满足您的需求。另外,在这个例子中,你只是输入第三 - 第五行?你可能想更详细地解释你希望发生的事情。 –

+0

@詹姆斯布莱克:问题的新版本如何? –

回答

7

在诸如haskell的函数式语言中,您可以传入翻转和翻转条件作为谓词,并根据它筛选输入列表。例如,下面是Haskell中的flipflop定义(不要担心,如果执行不知道哈斯克尔 - 的关键部分是如何使用它):

flipflop flip flop = 
    uncurry (++) . second (take 1) . break flop . dropWhile (not . flip) 

这是它如何被使用:

> flipflop (== 3) (== 5) [1..10] 
[3,4,5] 

这是一个仅仅通过使用更高阶函数来生成有效的新语言结构的例子。

我不知道函数式语言中是否存在该构造的特殊名称。

4

取决于功能语言。这个怎么样?

ff_gen = 
    lambda{ |first, *conditions| 
    flipflop = false 
    condition = first 
    lambda{ |v| 
     if condition && condition[v] 
     condition = conditions.shift 
     flipflop = !flipflop 
     true 
     else 
     flipflop 
     end 
    } 
    } 

ff = ff_gen[lambda{|v| v == 3}, lambda{|v| v == 5}, lambda{|v| v == 7}, lambda{|v| v == 11}] 

puts (0..20).select{ |i| ff[i] }.inspect # => [3, 4, 5, 7, 8, 9, 10, 11] 

补充:当然,Ruby是不是一个纯粹的功能性语言,所以我决定把它改写二郎:

#!/usr/bin/env escript 

flipflop(E, {[H|T] = Conditions, FlipFlop}) -> 
    case H(E) of 
    true -> 
     {true, {T, not FlipFlop}}; 
    false -> 
     {FlipFlop, {Conditions, FlipFlop}} 
    end; 

flipflop(_, {[], FlipFlop}) -> 
    {FlipFlop, {[], FlipFlop}}. 

flipflop_init(Conditions) -> 
    {[], {Conditions, false}}. 

main([]) -> 
    {L, _} = 
    lists:foldl(
     fun(E, {L2, FFState}) -> 
     case flipflop(E, FFState) of 
      {true, FFState2} -> 
      {[E|L2], FFState2}; 
      {false, FFState2} -> 
      {L2, FFState2} 
     end 
     end, 
     flipflop_init([ 
     fun(E) -> E == 3 end, 
     fun(E) -> E == 5 end, 
     fun(E) -> E == 7 end, 
     fun(E) -> E == 11 end 
     ]), 
     lists:seq(0,20) 
    ), 
    io:format("~p~n", [lists:reverse(L)]), 
    ok. 

注:事实上,经典的触发器应工作就像dropwhile(!first) - > takewhile(!second),所以Ruby的触发器是特设的(与电子产品中的触发器相比)。

+0

你知道是否有描述这个概念的术语? –

0

同@ nanothief的解决方案,但在斯卡拉:

def flipFlop[A](flip: A => Boolean, flop: A => Boolean, seq: Seq[A]): Seq[A] = { 
    val (p, q) = seq.dropWhile(!flip(_)).span(!flop(_)) 
    p ++ q.take(1) 
} 

样品试验:

> flipFlop[Int](_ == 3, _ == 5, Nil) 
List() 

> flipFlop[Int](_ == 3, _ == 5, 1 to 19) 
Vector(3, 4, 5) 
语言,你考虑哪些FP
相关问题