3

GUIを書いているとします

ここに画像の説明を入力

class Kitteh (val age: Int) {
  require (age < 5)
  def saveMeow(file: File) = { /* implementation */ }
  def savePurr(file: File) = { /* implementation */ }
}

フレームには現在の Kitteh のフィールドがあります。これは、Optionまだ定義されていないか、ユーザーが無効なものを作成しようとした可能性があるためです。

var currentKitteh: Option[Kitteh] = None

Kittehユーザーが Create を押したときに安全に作成したい

val a = ... // parse age from text box
currentKitteh = try { Some(new Kitteh(a)) } catch { case _ => None }

私の GUI には、同様のことを行う 2 つのボタンがあります。疑似コードでは、両方を行う必要があります

if (currentKitteh.isDefined) {
  if (file on the disk already exists) {
    bring up a dialog box asking for confirmation
    if (user confirms)
       << execute method on currentKitteh >>
  }
}
else bring up warning dialog

詳細は気にしないでください。ポイントは、コードの重複があるため、両方のボタンから呼び出すことができる共通のメソッドを作成したいということです。唯一の違いは、実行する必要がある Kitteh のメソッドです。

currentKittehではない場合Option、共通メソッドは次のような署名を持つことができます

def save(filename: String, f:(File => Unit)) {

たとえば、これで呼び出すことができます

save("meow.txt", currentKitteh.saveMeow _)

しかし、実際にはオプションなので、どうすればこれを実装できますか?

currentKitteh が定義されているかどうかを確認し、各ボタン.getのメソッドを呼び出す前にa を実行することもできますが、このチェックをメソッドに残す別の方法はありますか? つまり、 が与えられた場合、(存在しない可能性がある)オブジェクトのメソッドから部分関数を指定することは可能ですか?savesaveOption[A]A

(この質問が理にかなっていることを願っていますが、複雑な例にもかかわらず)

編集: おまけの質問: の代わりにOption[Kitteh]を使用した場合はEither[Throwable, Kitteh]?

update : 警告ダイアログを表示するために疑似コードに追加された追加の行: 理想的には、save保存する有効な Kitteh がない場合にユーザーに警告されるように、メソッドを常に呼び出す必要があります。

4

3 に答える 3

4

これは私にとって最良の選択肢のように見えます:

currentKitteh foreach { c => save("meow.txt", c.saveMeow _) }

これを繰り返している場合は、抽象化できます。

def currentSaveMeow(file: String) = currentKitteh foreach { c =>
  save(file, c.saveMeow _)
}
currentSaveMeow("meow.txt")

元の質問に答えると思いますが、ロジックを関数の引数にプッシュすることもできます。

save("meow.txt", file => currentKitten.foreach(_.saveMeow(file)))

このバージョンではセマンティクスが少し異なります。

更新しますk: Option[Kitteh]が に置き換えられた場合k: Either[Throwable, Kitteh]、 はどうk.right foreach { c => ... }でしょうか? k.right map ...エラー情報を保存したい場合にも使用できます。


変更された質問への回答として、別の抽象化の可能性があります。

def save(filename: String, f: (Kitteh, File) => Unit)

saveは開梱の責任がありcurrentKittehます。saveこのように呼び出し、

save("meow.txt", (k, f) => k.saveMeow(f))

またはこのように、

save("meow.txt", _ saveMeow _)
于 2011-09-08T22:02:27.727 に答える
0

関数をそれにマップして、失敗関数を getOrElse することができます。

def save = 
  o map {s => () => "saved a kitteh! " + s} getOrElse {() => "oh noes, no kittehs!"}

次に、あなただけ:

save()
于 2011-09-09T19:51:46.033 に答える
0

クラス BadKitteh を定義して、エラー メッセージを生成させることができます。次に、必要に応じて currentKitty.getOrElse(badKitty) を使用します。

于 2011-09-10T09:45:47.667 に答える