سؤال

في سكالا، PartialFunction[A, B] فئة مشتقة من النوع Function[A, B] (انظر مرجع scala، 12.3.3). ومع ذلك، يبدو هذا مضادا لي، منذ Function (الذي يحتاج إلى تعريف للجميع A) لديه متطلبات أكثر صرامة من PartialFunction, ، والتي يمكن أن تكون غير محددة في بعض الأماكن.

المشكلة التي أحضرت accross كان ذلك عندما يكون لدي وظيفة جزئية، لا أستطيع استخدام Function لتمديد الوظيفة الجزئية. على سبيل المثال لا أستطيع أن أفعل:

(pf orElse (_)=>"default")(x)

(نأمل أن يكون بناء الجملة على صواب على الأقل)

لماذا يتم ذلك الفرعي الفرعي عكسها؟ هل هناك أي أسباب تجاهلت، مثل حقيقة أن Function أنواع مدمجة؟

راجع للشغل، سيكون لطيفا أيضا إذا Function1 :> Function0 لذلك لا أحتاج إلى حجة وهمية في المثال أعلاه :-)

تحرير لتوضيح المشكلة الفرعية

يمكن التأكيد على الفرق بين النهجين من خلال النظر إلى مثالين. أي منهم صحيح؟

واحد:

val zeroOne : PartialFunction[Float, Float] = { case 0 => 1 }
val sinc = zeroOne orElse ((x) => sin(x)/x) // should this be a breach of promise?

اثنين:

def foo(f : (Int)=>Int) {
  print(f(1))
}
val bar = new PartialFunction[Int, Int] {
  def apply(x : Int) = x/2
  def isDefinedAt(x : Int) = x%2 == 0
}
foo(bar) // should this be a breach of promise?

لا يوجد حل صحيح

نصائح أخرى

لأنه في Scala (كما هو الحال في أي لغة تورينج كاملة) لا يوجد أي ضمان أن وظيفة كاملة.

val f = {x : Int => 1 / x}

لا يتم تعريف هذه الوظيفة عند 0. تعد جزءا من الجزئي مجرد وظيفة تعد بإخبارك أين لم يتم تعريفها. لا يزال، scala يجعل من السهل بما يكفي للقيام بما تريد

def func2Partial[A,R](f : A => R) : PartialFunction[A,R] = {case x => f(x)}

val pf : PartialFunction[Int, String] = {case 1 => "one"} 

val g = pf orElse func2Partial{_ : Int => "default"}

scala> g(1)
res0: String = one

scala> g(2)
res1: String = default

إذا كنت تفضل ذلك، فيمكنك إجراء ضمني function2partial.

PartialFunction لديه طرق التي Function1 لا، لذلك هو النوع الفرعي. تلك الطرق isDefinedAt و orElse.

مشكلتك الحقيقية هي ذلك PartialFunctionلا يستنتج S في بعض الأحيان عندما تحبهم حقا. أنا آمل أن يتم تناولها في تاريخ بعض المستقبل. على سبيل المثال، هذا لا يعمل:

scala> val pf: PartialFunction[String, String] = { case "a" => "foo" }
pf: PartialFunction[String,String] = <function>

scala> pf orElse { case x => "default" }
<console>:6: error: missing parameter type for expanded function 
((x0$1) => x0$1 match { case (x @ _) => "default" })

ولكن هذا يفعل:

scala> pf orElse ({ case x => "default" } : PartialFunction[String,String])
res5: PartialFunction[String,String] = <function>

بالطبع يمكنك دائما القيام بذلك:

scala> implicit def f2pf[T,R](f: Function1[T,R]): PartialFunction[T,R] = 
  new PartialFunction[T,R] { 
    def apply(x: T) = f(x)
    def isDefinedAt(x: T) = true 
  }
f2pf: [T,R](f: (T) => R)PartialFunction[T,R]

والآن أكثر وكأنك تريد:

scala> pf orElse ((x: String) => "default")
res7: PartialFunction[String,String] = <function>

scala> println(res7("a") + " " + res7("quux"))
foo default
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top