2012-08-16 11 views
8

¿Es posible pasar patrones de casos como parámetros a otras funciones? Algo como esto:¿Los patrones de scala son de primera clase?

def foo(pattern: someMagicType) { 
    x match { 
    pattern => println("match") 
    } 
} 

def bar() { 
    foo(case List(a, b, c)) 
} 
+0

He jugado un poco con la Scala 2.10 'Try', antes de cambiar su pregunta. Quizás aún te parezca útil: http://stackoverflow.com/questions/11990017/threading-trys-through-for-comprehension –

Respuesta

3

creo que la primera respuesta de Kim Stebel está cerca de lo que desea. Una 'coincidencia de patrón como tal' no es una entidad aislada en Scala. Una coincidencia puede ser definida como a Function1 o PartialFunction.

def foo[A, B](x: A)(pattern: PartialFunction[A, B]): Unit = 
    if(pattern.isDefinedAt(x)) println("match") 

def bar(list: List[String]): Unit = 
    foo(list){ case List("a", "b", "c") => } 

prueba:

bar(Nil) 
bar(List("a", "b", "c")) 

Como alternativa, utilice composición:

def foo[A, B](x: A)(pattern: PartialFunction[A, B]): Unit = { 
    val y = pattern andThen { _ => println("match")} 
    if (y.isDefinedAt(x)) y(x) 
} 
4

¿Quiere pasar un bloque de coincidencia de patrón a otra función? Eso se puede hacer con PartialFunction s, como muestra el siguiente ejemplo:

def foo(f:PartialFunction[String, Int]) = { 
    f("") 
} 

foo { 
    case "" => 0 
    case s => s.toInt 
} 
0

Su tipo de magia se puede escribir como un tipo estructural que tiene un método de cancelar la aplicación. Dependiendo del tipo de extractor que necesite, necesitará diferentes tipos de unapply o unapplySeq. A continuación se muestra un ejemplo simple.

def foo(x:Int, Pattern: { def unapply(x:Int):Boolean }) { 
    x match { 
    case Pattern => println("match") 
    } 
} 

foo(1, new { def unapply(x:Int) = x > 0 }) 

y es así como se hace para las listas:

foo(List(1,2,3), new { def unapplySeq(x:List[Int]):Option[List[Int]] = if (x.size >= 3) Some(x) else None }) 

def foo(x:List[Int], Pattern: { def unapplySeq(x:List[Int]):Option[List[Int]] }) { 
    x match { 
    case Pattern(a,b,c) => println("match: " + a + b + c) 
    } 
} 
+0

El '' 'foo (1, ...' '' bit no funciona en el REPL (Yo uso 2.9.2). Me llevó a esta interesante discusión: http://www.scala-lang.org/node/10730 – opyate

+0

En realidad, ni funciona compilado. ¿Qué versión de Scala usaste, @ Kim? – opyate

Cuestiones relacionadas