3

JavaまたはC++でプログラミングするときに、カスタム制御構造によってコード内の定型文を減らすことができる単純なパターンに遭遇することが何度もあります。それは次のようになります:

 if( Predicate ){
     Action

     return Value
 }

つまり、「returnif」タイプのステートメントです。のような署名付きの関数を作成しようとしましfoo[A,B]( pred:((A,A)=>Boolean), value:Option[B] )たが、SomeまたはNoneを返したかどうかを確認することになります。私はそのreturn声明につまずいた。

関数型言語、より具体的にはScalaでそのような制御構造を作成する継承方法はありますか?

編集:

私は私の説明がはっきりしていなかったし、私を助けようとしている人々を混乱させている。私が機能しない主な理由fooは、含まれている関数の評価を短絡できないことです。あれは

def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
    return_if( withinBounds( geometry, projection ), logToString( logger, "Geometry outside " + projection.toString ), EmptyGeometry() )
    return_if( topologicallyCorrect( geometry ), intersect( correct( geometry ), reference )
    //rest of the function
}

内で末尾再帰を許可しますreturn_if

4

4 に答える 4

7

部分関数を使用します:

def whatevs[A, B](options : PartialFunction[(A,A), B]) : Option[B] = {
  val myInput = generateInput
  if(options.isDefined(myInput)) {
    Some(options(myInput))
  } else None
}

その場合、使用法は次のようになります。

whateves {
   case (x,y) if x > y =>   "Biggerz"
   case (x,y) if y > x =>   "Tiny!"
}

通常、returnステートメントは必要ありません。If-expressionは、各ブロックで使用される最後の式に評価されます。コンパイラがif式の型結果を理解するのを助ける必要があるかもしれませんが、返される必要はありません。

Partial Functions are a mechanism to perform an action if some condition holds true. In the above, the two conditions are x > y or y > x from the tuple.

If the whatevs function is not quite what you're talking about I'd recommend using raw pattern matching.

于 2010-08-26T14:30:11.650 に答える
2

これをコードの制御フローからの条件付きエスケープとして使用しているようです。

それが本当に問題の最も洗練された解決策である場合は、Scalaでもこれを行うことができます(返す型でメソッドに注釈を付けるだけです)。コードが多段階フィルターのように機能する必要がある場合があり、このパターンはそのためにうまく機能します。

もちろん、いつでもifステートメントをネストできますが、それは厄介です。

ただし、Scalaでは他にも考慮すべきことがいくつかあります。1つができます

methodReturningOption.getOrElse(
  // All the code for the None case goes in here
)

これは通常、適切なデフォルトがある場合にさまざまなブランチを統合するのに非常にうまく機能します(または、ない場合は例外をスローすることになります)。

または、これにパターンマッチングを悪用することもできます。

None match {  // Could use a real variable instead of None if it helped
  case _ if (Predicate1) => Action1; Value1
  case _ if (Predicate2) => Action2; Value2
  . . .
  case _ => ErrorHandlingPerhaps
}

ただし、これらの種類の述語の有用性が低くなるように、問題について別の方法で考えることもできる場合があります。(詳細を知らなければ、私は何かを提案することはできません。)

于 2010-08-26T14:22:02.627 に答える
2

Hmm, as far as I understand it you want the return in the control structure to exit the function it is embedded in.

So in your example it should exit the method intersect?

I am not sure if thats possible. Because a return inside the return_if will always exit return_if and I don't think there is a way to tell scala, that the return should exit the function return_if is embedded in.

I hope I understood what you wanted to do :)

于 2010-08-26T19:43:58.250 に答える
1

I am at a loss to understand why you would want this. Here's the code you want to write:

def intersect( geometry:Geometry, reference:Geometry ):Geometry = {

  return_if( withinBounds( geometry, projection ), 
    logToString( logger, "Geometry outside " + projection.toString ), 
    EmptyGeometry() )

  return_if( topologicallyCorrect( geometry ), 
    intersect( correct( geometry )), 
    reference )

    // rest of the function
}

「通常の」Scalaでは次のようになります。

def intersect( geometry:Geometry, reference:Geometry ):Geometry = {

  if (withinBounds( geometry, projection )) {
    logToString( logger, "Geometry outside " + projection.toString )
    return EmptyGeometry() }

  if( topologicallyCorrect( geometry )) {
    intersect( correct( geometry ))
    return reference }

  //rest of the function
}

私には、「通常の」バージョンの方がはるかに明確に見えます。一つには、何が返されるのかが非常に明確になります。それはさらに冗長ではありません。もっと複雑なユースケースがあると思います。あなたがそれを私たちに見せれば、多分私たちはあなたをより適切なパターンに導くことができるでしょう。

于 2010-08-26T23:14:56.270 に答える