Member methods as function arguments

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Member methods as function arguments

fero
Hi,
I would like to write a SQL like DSL in Scala. One of my methods is

def groupBy[A,B](xs: List[A],f: A=>B) = (unique(xs,f)) map (x=>(x, xs filter (y=>f (y) == x)))

or

case class Group[A, B](name: A, list: B)
def groupBy2[A,B](xs: List[A],f: A=>B) = (unique(xs,f)) map (x=>Group(x, xs filter (y=>f (y) == x)))

groupBy or groupBy2 are essentially the same. I use this method as follows:
case class Item(name: String, price: Int)
val items: List[Item] = List(Item("a", 2),Item("b", 2),Item("c", 2),Item("a", 2),Item("b", 2))

groupBy(items, ((x:Item)=>x.name))

which groups items by name. But I don't like the function ((x:Item)=>x.name). It is very confusing in long queries. I would like to write "(_.name)" or "Item.name" instead. Is it possible?
I can write
items map (_.name)
but this but in this case map is member function of List so it works. Is there any way how to rewrite groupBy to make queries more clear?

Thanks for help

Fero

PS fuctions used to bulis groupBy:

def removeDuplicates[A](xs: List[A]): List[A] =
    if (xs.isEmpty) xs
    else xs.head :: removeDuplicates(xs.tail filter (x => x != xs.head))

def unique[A,B](xs: List[A], f: A=>B) = removeDuplicates(xs map f)
Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

Jon Pretty
Hi Fero,

fero wrote:
> I would like to write a SQL like DSL in Scala.

There's a number of ways you can do this, and it's probably good experience to give it a go
(but implementing all of SQL will quickly get tedious).

Nonetheless, Gilles Dubochet at EPFL has been working on something similar (not released
yet), and he's written a teaser page on the Scala Wiki:

   http://scala.sygneca.com/libs/dbc

Cheers,
Jon


--
Jon Pretty | Sygneca Ltd

Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

fero
Thanks John

John wrote:
>Nonetheless, Gilles Dubochet at EPFL has been working on something similar (not released
>yet), and he's written a teaser page on the Scala Wiki:
>
>   http://scala.sygneca.com/libs/dbc

This project looks very interesting. I will definitely try it out. Mainly for inspiration. But I don't want to write SQL for database, I would like to write query language for objects and list of objects. So it can go deeper in obect tree, or sort the result...

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

Aaron Harnly-2-2
In reply to this post by fero

On Jun 25, 2008, at 4:03 PM, fero wrote:
> def groupBy[A,B](xs: List[A],f: A=>B) = (unique(xs,f)) map (x=>(x,  
> xs filter(y=>f (y) == x)))
> case class Item(name: String, price: Int)
> val items: List[Item] = List(Item("a", 2),Item("b", 2),Item("c",
> 2),Item("a", 2),Item("b", 2))
> groupBy(items, ((x:Item)=>x.name))
>
>  I would like to write "(_.name)" or "Item.name" instead. Is it  
> possible?


As Jon said, sounds like a great project!
With regard to your question: Welcome to the limitations of Scala's  
type inference.
A hint to the compiler can give you what you want, at some cost:

groupBy[Item,String](items, _.name)

It's rather annoying to have to specify the first parameterized type,  
and very annoying to have to specify the second. (Still pining for yet  
another overload for `_' to mean "figure out this type parameter yo'  
own damn self...")

As for a better way to write it, I'd have to think...
cheers,
Aaron


Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

Chris Hansen-7
In reply to this post by fero
Sounds a lot like LINQ. At the Scala Lift Off, it was briefly
mentioned that someone had a Scala/LINQ library well under way
(someone suggested the name SLINQY ). Does anyone know if it is
publicly available, and where?

-Chris

On Thu, Jun 26, 2008 at 1:21 AM, fero <[hidden email]> wrote:
>>
>>   http://scala.sygneca.com/libs/dbc
>
> This project looks very interesting. I will definitely try it out. Mainly
> for inspiration. But I don't want to write SQL for database, I would like to
> write query language for objects and list of objects. So it can go deeper in
> obect tree, or sort the result...
>
Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

fero
Thanks Chris, I found SLINQY on google bu t it doesn't seem to be  out yet. Hopefully it will make the path do daylight. I am learning Scala two weeks so I don't think I can do as good as LINQ.

Btw. I have found the way how ot do it more readable. But you need to use Curried form of function. I tis weird for me why in Curried form type inference works and in Uncurried it doesn't.

Here is the code

def groupBy3[A,B](xs: List[A])(f: A=>B) = (unique(xs,f)) map (x=>Group(x, xs filter (y=>f (y) == x)))

groupBy3(items) (_.name)

Thanks to everyone

Fero
Reply | Threaded
Open this post in threaded view
|

Re: Member methods as function arguments

Chris Hansen-7
If you're referring to the project of the same name on google code,
that one appears to be an open-source rewrite of LINQ for .NET. If I
remember right, it was someone at the EPFL who had written the Scala
one.

-Chris

On Fri, Jun 27, 2008 at 1:44 AM, fero <[hidden email]> wrote:
>
> Thanks Chris, I found SLINQY on google bu t it doesn't seem to be  out yet.
> Hopefully it will make the path do daylight. I am learning Scala two weeks
> so I don't think I can do as good as LINQ.
>