7

Ruby(およびPerl)には、フリップフロップの概念があります。

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

次のような序数のリストを与えました

first
second
third
fourth
fifth
sixth

「3番目」に達したときに印刷を開始し、「5番目」に達したときに停止します。

third
fourth
fifth

これに類似した関数型プログラミングの概念はありますか、それともこれは通常takewhilesの観点から説明されますか?私は特定の言語について尋ねているのではなく、それを説明するためにどのような用語を使用するのかを尋ねています。

4

3 に答える 3

8

haskellのような機能的な言語では、述語としてフリップとフロップの条件を渡し、それに基づいて入力リストをフィルタリングします。たとえば、以下はflipflopin haskellの定義です(haskellがわからなくても、実装について心配する必要はありません。重要なのは、その使用方法です)。

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

使用方法は次のとおりです。

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

これは、高次の関数を使用するだけで、効果的に新しい言語構造を作成する例です。

関数型言語でその構成に特別な名前があるかどうかはわかりません。

于 2011-06-24T04:46:16.663 に答える
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は純粋な機能言語ではないので、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.

注:実際、従来のフリップフロップはdropwhile(!first)-> takewhile(!second)のように機能するはずなので、Rubyのフリップフロップはアドホックなものです(電子機器のフリップフロップと比較してください)。

于 2011-06-24T00:46:32.387 に答える
0

@nanothiefのソリューションと同じですが、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)
}

サンプル実行:

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

> flipFlop[Int](_ == 3, _ == 5, 1 to 19)
Vector(3, 4, 5)
于 2011-06-24T07:04:15.420 に答える