Reputation: 1813
I wrote a section code for testing:
class A extends JavaTokenParsers {
def str: Parser[Any] = stringLiteral ~ ":" ~ stringLiteral ^^
{ case x ~ ":" ~ y => (x, y) } //how to use case keyword like this?
}
object B extends A with App{
val s = """
"name": "John"
"""
println(parseAll(str, s))
}
I read "Chapter 15: Case Classes and Pattern Matching" of Programming in Scala Second Edition , but I never saw case used like this:
... ^^ { case x ~ ":" ~ y => (x, y) }
It's not match keyword, but ^^ looks like match. I know partial functions and I can use case by this way:
object C extends App {
def a(f: Int => Int) = {
f(3)
}
a(x => x + 1)
a { case x => x + 1 }
}
But they are all different:
How to write custom function like ^^? Can you write a concrete example? Thanks a lot!
Upvotes: 10
Views: 6075
Reputation: 732
As you mentioned, you can use a block with the case keyword to create a partial function.
val doubleIntGtThree: PartialFunction[Int, Int] = {
case x: Int if x > 3 => x * 2
}
doubleIntGtThree(4) // return 8
doubleIntGtThree(2) //throws a matchError
Upvotes: 4
Reputation: 108169
It's just syntactic sugar. In scala, you can use any method that takes a single parameter as a binary operator.
Example:
class Foo(x: String) {
def ^^(pf: PartialFunction[String, Int]): Option[Int] =
if (pf.isDefinedAt(x)) Some(pf(x)) else None
}
val foo = new Foo("bar")
foo ^^ {
case "baz" => 41
case "bar" => 42
}
// result: Some(42)
Upvotes: 10