This page is no longer maintained — Please continue to the home page at www.scala-lang.org

A concise way to express this match?

12 replies
Pedro Lopes
Joined: 2010-08-06,
User offline. Last seen 42 years 45 weeks ago.

Hi, a quick style question:

I have a tree structure of heterogeneous nodes (as case classes).
In the unit tests for this structure I ended up with dozens of
find/filter/exists calls that look like something like this:

root.find {
_ match {
case Schema("HR") => true
case _ => false
}
}

This works well, but is terribly verbose. This sort of "boolean
match":

_ match {
case Schema("HR") => true
case _ => false
}

feels like it should be expressible in more compact form. Is there
a better way?

Thanks,
Pedro

Rodrigo Cano
Joined: 2009-03-22,
User offline. Last seen 42 years 45 weeks ago.
Re: A concise way to express this match?
I would write it as:

root.find {case Schema("HR") => true; case _ => false}

On Fri, Aug 6, 2010 at 4:26 PM, Pedro Lopes <paol [at] draic [dot] org> wrote:
Hi, a quick style question:

I have a tree structure of heterogeneous nodes (as case classes).
In the unit tests for this structure I ended up with dozens of
find/filter/exists calls that look like something like this:

root.find {
 _ match {
   case Schema("HR") => true
   case _ => false
 }
}

This works well, but is terribly verbose. This sort of "boolean
match":

_ match {
 case Schema("HR") => true
 case _ => false
}

feels like it should be expressible in more compact form. Is there
a better way?

Thanks,
Pedro


Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: A concise way to express this match?
It looks like you're trying to find the first Schema("HR") value in some collection `root`
So why not:
root.find{ _ == Schema("HR") }

case class already have equality properly defined for you :)


On 6 August 2010 20:26, Pedro Lopes <paol [at] draic [dot] org> wrote:
Hi, a quick style question:

I have a tree structure of heterogeneous nodes (as case classes).
In the unit tests for this structure I ended up with dozens of
find/filter/exists calls that look like something like this:

root.find {
 _ match {
   case Schema("HR") => true
   case _ => false
 }
}

This works well, but is terribly verbose. This sort of "boolean
match":

_ match {
 case Schema("HR") => true
 case _ => false
}

feels like it should be expressible in more compact form. Is there
a better way?

Thanks,
Pedro




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Pedro Lopes
Joined: 2010-08-06,
User offline. Last seen 42 years 45 weeks ago.
Re: A concise way to express this match?

On 08/06/2010 09:03 PM, Rodrigo Cano wrote:
> I would write it as:
>
> root.find {case Schema("HR") => true; case _ => false}
>

Thanks! I wasn't aware the match could be omitted.

Maybe still not as concise as I would like, but at least it's
short enough to be condensed into a single line, which makes a
huge difference.

Pedro

Pedro Lopes
Joined: 2010-08-06,
User offline. Last seen 42 years 45 weeks ago.
Re: A concise way to express this match?

On 08/06/2010 09:12 PM, Kevin Wright wrote:
> It looks like you're trying to find the first Schema("HR") value in some collection `root`
>
> So why not:
>
> root.find{ _ == Schema("HR") }
>
> case class already have equality properly defined for you :)

Sorry, I omitted the fact that the classes I want to match
(Schema in this example) are abstract, so I can't do that.

Pedro

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Re: A concise way to express this match?
root collect { case x : Schema("HR") => x }

collect is a bit like map, but instead accepts a PartialFunction and filters on the input domain.



On 7 August 2010 12:16, Pedro Lopes <paol [at] draic [dot] org> wrote:
On 08/06/2010 09:12 PM, Kevin Wright wrote:
It looks like you're trying to find the first Schema("HR") value in some collection `root`

So why not:

   root.find{ _ == Schema("HR") }

case class already have equality properly defined for you :)

Sorry, I omitted the fact that the classes I want to match
(Schema in this example) are abstract, so I can't do that.

Pedro




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: A concise way to express this match?

Hi,

how about this:

root.view.collect { case x @ Schema("HR") => x } headOption

- Andreas

Am 06.08.2010 um 21:26 schrieb Pedro Lopes:

> Hi, a quick style question:
>
> I have a tree structure of heterogeneous nodes (as case classes).
> In the unit tests for this structure I ended up with dozens of
> find/filter/exists calls that look like something like this:
>
> root.find {
> _ match {
> case Schema("HR") => true
> case _ => false
> }
> }
>
> This works well, but is terribly verbose. This sort of "boolean
> match":
>
> _ match {
> case Schema("HR") => true
> case _ => false
> }
>
> feels like it should be expressible in more compact form. Is there
> a better way?
>
> Thanks,
> Pedro
>
>

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: A concise way to express this match?
of course...  @ not :
Schoolboy error on my part!

On 7 August 2010 15:09, Andreas Flierl <andreas [at] flierl [dot] eu> wrote:
Hi,

how about this:

root.view.collect { case x @ Schema("HR") => x } headOption

- Andreas

Am 06.08.2010 um 21:26 schrieb Pedro Lopes:

> Hi, a quick style question:
>
> I have a tree structure of heterogeneous nodes (as case classes).
> In the unit tests for this structure I ended up with dozens of
> find/filter/exists calls that look like something like this:
>
> root.find {
>  _ match {
>    case Schema("HR") => true
>    case _ => false
>  }
> }
>
> This works well, but is terribly verbose. This sort of "boolean
> match":
>
> _ match {
>  case Schema("HR") => true
>  case _ => false
> }
>
> feels like it should be expressible in more compact form. Is there
> a better way?
>
> Thanks,
> Pedro
>
>




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Pedro Lopes
Joined: 2010-08-06,
User offline. Last seen 42 years 45 weeks ago.
Re: A concise way to express this match?

On 08/07/2010 03:09 PM, Andreas Flierl wrote:
> Hi,
>
> how about this:
>
> root.view.collect { case x @ Schema("HR") => x } headOption
>

Interesting, why does the above pattern not require the _ case?
I would have expected that code to throw MatchError, but it doesn't.

Pedro

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: Re: A concise way to express this match?

It's because collect is exactly for that. Collect takes a partial function pf and only considers the values in the underlying collection for which pf is defined, applies pf to them and builds a new collection containing only them.

scala> List(None, Some(1), Some(2), None, Some(42), None, None).collect { case Some(n) => n }
res0: List[Int] = List(1, 2, 42)

- Andreas

Am 07.08.2010 um 20:17 schrieb Pedro Lopes:

> On 08/07/2010 03:09 PM, Andreas Flierl wrote:
>> Hi,
>>
>> how about this:
>>
>> root.view.collect { case x @ Schema("HR") => x } headOption
>>
>
> Interesting, why does the above pattern not require the _ case?
> I would have expected that code to throw MatchError, but it doesn't.
>
> Pedro
>
>

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Re: A concise way to express this match?
an incomplete match expression becomes a PartialFunction`collect` eats *those* for breakfast...

On 7 August 2010 19:17, Pedro Lopes <paol [at] draic [dot] org> wrote:
On 08/07/2010 03:09 PM, Andreas Flierl wrote:
Hi,

how about this:

root.view.collect { case x @ Schema("HR") =>  x } headOption


Interesting, why does the above pattern not require the _ case?
I would have expected that code to throw MatchError, but it doesn't.

Pedro




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: A concise way to express this match?
To add another detail, if I'm not mistaken, basically when you write a PartialFunction, scalac compiles your pattern match twice: once doing essentially what you wrote, as the body of the apply method; and it also compiles a boolean version for the body of the isDefinedAt method. So code that consumes a PartialFunction can call isDefinedAt in order to know whether apply will throw a MatchError.

On Sat, Aug 7, 2010 at 2:31 PM, Andreas Flierl <andreas [at] flierl [dot] eu> wrote:
It's because collect is exactly for that. Collect takes a partial function pf and only considers the values in the underlying collection for which pf is defined, applies pf to them and builds a new collection containing only them.

scala> List(None, Some(1), Some(2), None, Some(42), None, None).collect { case Some(n) => n }
res0: List[Int] = List(1, 2, 42)

- Andreas

Am 07.08.2010 um 20:17 schrieb Pedro Lopes:

> On 08/07/2010 03:09 PM, Andreas Flierl wrote:
>> Hi,
>>
>> how about this:
>>
>> root.view.collect { case x @ Schema("HR") =>  x } headOption
>>
>
> Interesting, why does the above pattern not require the _ case?
> I would have expected that code to throw MatchError, but it doesn't.
>
> Pedro
>
>


dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: A concise way to express this match?
Depending on your code, you could do something like this:
def isA[A](pf: PartialFunction[A, Unit]) = pf.lift(_: A) != Noneval testHR = isA[SuperClass] { case Schema("HR") => }
then you can do root.find(testHR(_))

On Fri, Aug 6, 2010 at 4:26 PM, Pedro Lopes <paol [at] draic [dot] org> wrote:
Hi, a quick style question:

I have a tree structure of heterogeneous nodes (as case classes).
In the unit tests for this structure I ended up with dozens of
find/filter/exists calls that look like something like this:

root.find {
 _ match {
   case Schema("HR") => true
   case _ => false
 }
}

This works well, but is terribly verbose. This sort of "boolean
match":

_ match {
 case Schema("HR") => true
 case _ => false
}

feels like it should be expressible in more compact form. Is there
a better way?

Thanks,
Pedro




--
Daniel C. Sobral

I travel to the future all the time.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland