Is there a functional programming concept equivalent to flip flop operator in Perl or Ruby?

Ruby (and Perl) has a trigger concept:

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

which specified a list of ordinals such as

 first second third fourth fifth sixth 

will start to print when it reaches the β€œthird” and stop when it reaches the β€œfifth”:

 third fourth fifth 

Is there a functional programming concept similar to this, or is it usually described in terms of takewhile s? I am not asking about a particular language, just what term would you use to describe it.

+6
source share
3 answers

In a functional language such as haskell, you must pass the flip flop conditions as predicates and filter the input list based on this. For example, the following flipflop definition in haskell (don't worry about implementation if you don't know haskell - the key part is how it is used):

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

Here's how to use it:

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

This is an example of creating an effective new language construct by simply using a higher ordered function.

I do not know if there is a special name for this construct in functional languages.

+7
source

Depends on the functional language. How about this?

 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] 

Added: Of course, Ruby is not a pure functional language, so I decided to rewrite it in Erlang:

 #!/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. 

Note: In fact, a classic flip flop should work like dropwhile (! First) β†’ takewhile (! Second), so the ruby ​​trigger is an ad hoc one (compare with the trigger in electronics).

+4
source

Same as @nanothief's solution, but in Scala:

 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) } 

Run Examples:

 > flipFlop[Int](_ == 3, _ == 5, Nil) List() > flipFlop[Int](_ == 3, _ == 5, 1 to 19) Vector(3, 4, 5) 
0
source

Source: https://habr.com/ru/post/891254/


All Articles