2011-01-18 10 views
3

私は時々、私は基本的にPartialFunction[SomeType,AnotherType]を持っている、とFunction[SomeType,Option[AnotherType]としてそれを扱いたい、例えば次のパターン、渡って来る:ScalaでPartialFunctionを持ち上げる方法がありますか?

def f(s:SomeType):Option[AnotherType] = s match { 
    case s1:SubType1 => Some(AnotherType(s1.whatever)) 
    case s2:SubType2 => Some(AnotherType(s2.whatever)) 
    case _ => None 
} 

は避けるように、上記の関数を記述する方法はあります既定の場合、結果はSomeにラップされます。私が今までに思いつきました最高はこれです:

def f(s:SomeType):Option[AnotherType] = pf.lift(s) 
def pf:PartialFunction[SomeType,AnotherType] = { 
    case s1:SubType1 => AnotherType(s1.whatever) 
    case s2:SubType2 => AnotherType(s2.whatever) 
} 

中間機能を定義することなくそれを行う方法はありますか?私はすでに、次の線に沿っていろいろなことを試してみたが、まだコンパイルには何も持っていない:

def f:Function[SomeType,Option[AnotherType]] = { 
    case s1:SubType1 => AnotherType(s1.whatever) 
    case s2:SubType2 => AnotherType(s2.whatever) 
}.lift 
+0

あなたは中間の機能を意味しますか? – Raphael

+0

@Raphael関数のリテラルは、そうでないことを示す型ヒントがない限り、部分的な関数リテラルではありません。 –

+0

ああ、「持っている」とは「私がコードしている」という意味で、「タイプの価値がある」という意味ではありません。誤解、申し訳ありません。 – Raphael

答えて

6

condOptオブジェクトscala.PartialFunctionに。 scaladocから:

def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x } 
+0

しかし、 'condOpt(x)(pf)'は 'pf.lift(x)'と同じです。何か不足していますか?または、ここで明示的な型の注釈なしで関数リテラルを使用できる点は何ですか? –

+0

@oxbow_lakes、私はクリスチャンのために話すことができず、私は質問または私の答えについてあまり考えていなかった、 'condOpt'はちょうど彼が求めていたものに関連していたようだ。 – huynhjl

+0

実際、私はcondOptが型を推論するのが好きです。 –

4

それほど答え、huynhjlの答えが正解である理由の説明として...あなたの混乱の

パートはあなたがdefに部分的な機能をしようとしているということです。このすべてがないあなたにも直接のものを作成することができたときに、PartialFunctionオブジェクトを返すメソッドを作成することです:

val pf: PartialFunction[SomeType,AnotherType] = { 
    case s1:SubType1 => AnotherType(s1.whatever) 
    case s2:SubType2 => AnotherType(s2.whatever) 
} 

私は個人的にタイプの帰属を使用することを好むものの:

val pf = { 
    case s1:SubType1 => AnotherType(s1.whatever) 
    case s2:SubType2 => AnotherType(s2.whatever) 
} : PartialFunction[SomeType,AnotherType] 

いずれかの方法で、入力の種類を指定する必要がありますので、PartialFunctionの正確な署名をする必要があります。私はそれがこのことを推測することが可能であるべきであると感じていることを知っているが、悲しいかな、それは悲しいことではない!帰さバージョンを使用して

、あなたは、すべて同じ場所に定義して持ち上げることができます:それは残して、inferencerがあなたのために、この作業のほとんどを行うことができますよう

val pf = ({ 
    case s1:SubType1 => AnotherType(s1.whatever) 
    case s2:SubType2 => AnotherType(s2.whatever) 
} : PartialFunction[SomeType,AnotherType]).lift 

PartialFunction.condOptは、しかし、より良いソリューションですはるかにクリーンなコード:)

+0

これはまさに私が同じ振る舞いが必要なときにも私がやっていることです。「condOpt」はあまりにもひどいメソッド名です。私はそれを代わりに使用したいと思います。なぜ彼らはそれを 'applyLifted'と呼んでいないのですかわからない! –

+0

世界で最も直感的な名前ではありませんか? –

+0

ありがとうKevin、私はまたvalを試みたと思ったが、間違った呪文だったに違いない。あなたの答えは確かに私がダウンしていたパスのラインに沿っていますが、それは私が何を探していた(関数名にもかかわらず!) –

関連する問題