[scala] Using existential types to get rid of extraneous type parameters

View: New views
3 Messages — Rating Filter:   Alert me  

[scala] Using existential types to get rid of extraneous type parameters

by Paul Chiusano-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, I am experimenting with using existential types to get rid of some extraneous type parameters, however, I'm not totally sure what I'm doing and was hoping someone would enlighten me.

Take the following function:

  def integerDivide[K](denominator: Int, vs: Map[K,Int]): Map[K,Int] =
    vs.transform((k,v) => v/denominator)

It seems silly to have K appear as a type parameter to this function since it is not "touched" by the body of the function. So I tried this:

  def integerDivide(denominator: Int)(vs: Map[_,Int]): Map[_,Int] =
    vs.transform((k,v) => v/denominator)

That doesn't work either, though - the following doesn't type check:

   val divided: Map[String,Int] = integerDivide(3)(Map(("a", 1), ("b", 2)))

I get an error like:

type mismatch;
 found   : Map[_$5,Int] where type _$5
 required: Map[String,Int]

Is there any way I can get the type to carry through without having to make the key a type parameter? Or is what I am trying to do just crazy, not-well defined, or not possible?

Paul

Re: [scala] Using existential types to get rid of extraneous type parameters

by Alex Boisvert-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 17, 2008 at 11:36 AM, Paul Chiusano <paul.chiusano@...> wrote:
Take the following function:

  def integerDivide[K](denominator: Int, vs: Map[K,Int]): Map[K,Int] =
    vs.transform((k,v) => v/denominator)

It seems silly to have K appear as a type parameter to this function since it is not "touched" by the body of the function.

I don't think it's silly because it specifies that the return type is the same as the type passed in.  Otherwise, you're looking at an undefined return type....

alex


Re: [scala] Using existential types to get rid of extraneous type parameters

by Florian Hars-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Paul Chiusano schrieb:
>   def integerDivide[K](denominator: Int, vs: Map[K,Int]): Map[K,Int] =
>     vs.transform((k,v) => v/denominator)

The type you specified is

  exists K . (Int, Map[K, Int]) => Map[K, Int]

but the type you are after is

  forall K . (Int, Map[K, Int]) => Map[K, Int]

That is universal, not existential. And universal types are the prototypical
hypothetical improvement to scala
(see http://lampsvn.epfl.ch/svn-repos/scala/sip/trunk/sips/sip-00000.xhtml).

This may be related, too:
http://existentialtype.net/2008/05/26/revisiting-higher-rank-impredicative-polymorphism-in-scala/
but it looks too scary for me right now.
IIRC i've read somewhere else that you can get the effect you want by
CPS-transforming your program, but I am not sure that this would be an
improvement in the scariness department.

- Florian
LightInTheBox - Buy quality products at wholesale price