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

Abstract Types and Polymorphism

4 replies
Santiago Hirschfeld
Joined: 2008-12-31,
User offline. Last seen 42 years 45 weeks ago.

Hello,

This is my first message to the list and with a very simple question.
I'm in the process of learning Scala and currently I'm stuck with this
issue of using polymorphism and abstract types to do something like
the following (this is a simplification of the problem) :

abstract case class SomeType {
type T;
val value: T
}

case class IntType( value: Int ) extends SomeType {
type T = Int
}

val st: SomeType = IntType( 42 )

val i: Int = st.value

And as expected I get this:

:10: error: type mismatch;
found : st.T
required: Int
val i: Int = st.value

The question is this: Is there any way to get the value as Int from
the IntType object when st is declared as SomeType?

Thanks and happy New Year to everyone!

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Currying

Hi,
I'm new to this list and to Scala too. I'm reading through the currying
chapter of Programming in Scala, and I've a pretty basic question.

Perhaps I misunderstood the term, but I thought 'currying' described the
ability to bind some parameters to an existing function and derive
another one, with fewer parameters. I thought it would be possible to
take *any* function, treating it as a black-box, bind some parameters to
it and derive another. But it seems that this can't be applied to a
function in an after-the-fact fashion - the author must built this
ability inside a particular function. Also, this doesn't give the
ability to bind an arbitrary parameter of the function, but the first
one(s). I.e., if I have a function with four parameters:

f(a, b, c, d)

I could implement it in scala in a way that I could derive functions:

f(b, c, d)
f(c, d)
f(d)
f()

Is there a way I could also derive functions like f(a, b, c), f(a, b, d)
etc.? But again, I would like to be able to do this opaquely on top of
any function, not a specially crafted one, or else it doesn't sound too
useful to me. Can someone try to illuminate me on the subject? If I got
something entirely wrong, please correct me!

Thanks
Dimitris Andreou

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: Currying
Currying is taking a function of type (A,B) => C and creating a function of type A => B => C.   In Scala, currying can be done both syntactically (def foo(x:A)(y:B) : C = ...) and using an appropriate function.  For instance, here's a curry function for arity 2

scala> def curry[A,B,C](f : (A,B) => C) = {x : A => y : B => f(x,y)}
curry: [A,B,C]((A, B) => C)(A) => (B) => C

And here's using it

scala> def add(x : Int, y : Int) = x + y
add: (Int,Int)Int

scala> val curriedAdd = curry(add)
curriedAdd: (Int) => (Int) => Int = <function>

scala> val plusOne = curriedAdd(1)
plusOne: (Int) => Int = <function>

scala> plusOne(4)
res0: Int = 5


What you're describing is partial application, which is of course related.  You can use a curry function like above to do partial application by just applying an argument on the same line as where you curry

scala> val plusOne2 = curry(add)(1)
plusOne2: (Int) => Int = <function>

scala> plusOne2(5)
res1: Int = 6

But you don't need all that, because you can partially apply anything in Scala using _ notation

scala> val plusOne3 = add(1, _:Int)
plusOne3: (Int) => Int = <function>

scala> plusOne3(6)
res2: Int = 7

On Thu, Jan 1, 2009 at 9:06 AM, Dimitris Andreou <jim [dot] andreou [at] gmail [dot] com> wrote:
Hi,
I'm new to this list and to Scala too. I'm reading through the currying chapter of Programming in Scala, and I've a pretty basic question.

Perhaps I misunderstood the term, but I thought 'currying' described the ability to bind some parameters to an existing function and derive another one, with fewer parameters. I thought it would be possible to take *any* function, treating it as a black-box, bind some parameters to it and derive another. But it seems that this can't be applied to a function in an after-the-fact fashion - the author must built this ability inside a particular function. Also, this doesn't give the ability to bind an arbitrary parameter of the function, but the first one(s). I.e., if I have a function with four parameters:

f(a, b, c, d)

I could implement it in scala in a way that I could derive functions:

f(b, c, d)
f(c, d)
f(d)
f()

Is there a way I could also derive functions like f(a, b, c), f(a, b, d) etc.? But again, I would like to be able to do this opaquely on top of any function, not a specially crafted one, or else it doesn't sound too useful to me. Can someone try to illuminate me on the subject? If I got something entirely wrong, please correct me!

Thanks
Dimitris Andreou

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: Currying

Thanks a lot James! That's a very nice summary, hopefully I'll be able
to feel at home with all the various forms.

Syntax apart, am I right in thinking that partial appication is a
superset of currying? Here's my attempt:

scala> def curry[A, B, C](f: (A, B) => C) = (x:A) => f(x, _:B)
curry: [A,B,C]((A, B) => C)(A) => (B) => C

Which seems functionally (no pun) equivalent to the one you gave. I
understand though that syntactically currying would be better if the
function has lots of parameters and I wanted to partially apply each
parameter in the order of appearance (but I can't imagine another
use-case where the difference of them would be highlighted).

(A side note: the syntax still seems a bit tricky to me. Removing from
the above the paren's around 'x:A' results in error)

Happy new year! :)
Dimitris

O/H James Iry έγραψε:
> Currying is taking a function of type (A,B) => C and creating a
> function of type A => B => C. In Scala, currying can be done both
> syntactically (def foo(x:A)(y:B) : C = ...) and using an appropriate
> function. For instance, here's a curry function for arity 2
>
> scala> def curry[A,B,C](f : (A,B) => C) = {x : A => y : B => f(x,y)}
> curry: [A,B,C]((A, B) => C)(A) => (B) => C
>
> And here's using it
>
> scala> def add(x : Int, y : Int) = x + y
> add: (Int,Int)Int
>
> scala> val curriedAdd = curry(add)
> curriedAdd: (Int) => (Int) => Int =
>
> scala> val plusOne = curriedAdd(1)
> plusOne: (Int) => Int =
>
> scala> plusOne(4)
> res0: Int = 5
>
>
> What you're describing is partial application, which is of course
> related. You can use a curry function like above to do partial
> application by just applying an argument on the same line as where you
> curry
>
> scala> val plusOne2 = curry(add)(1)
> plusOne2: (Int) => Int =
>
> scala> plusOne2(5)
> res1: Int = 6
>
> But you don't need all that, because you can partially apply anything
> in Scala using _ notation
>
> scala> val plusOne3 = add(1, _:Int)
> plusOne3: (Int) => Int =
>
> scala> plusOne3(6)
> res2: Int = 7
>
> On Thu, Jan 1, 2009 at 9:06 AM, Dimitris Andreou
> > wrote:
>
> Hi,
> I'm new to this list and to Scala too. I'm reading through the
> currying chapter of Programming in Scala, and I've a pretty basic
> question.
>
> Perhaps I misunderstood the term, but I thought 'currying'
> described the ability to bind some parameters to an existing
> function and derive another one, with fewer parameters. I thought
> it would be possible to take *any* function, treating it as a
> black-box, bind some parameters to it and derive another. But it
> seems that this can't be applied to a function in an
> after-the-fact fashion - the author must built this ability inside
> a particular function. Also, this doesn't give the ability to bind
> an arbitrary parameter of the function, but the first one(s).
> I.e., if I have a function with four parameters:
>
> f(a, b, c, d)
>
> I could implement it in scala in a way that I could derive functions:
>
> f(b, c, d)
> f(c, d)
> f(d)
> f()
>
> Is there a way I could also derive functions like f(a, b, c), f(a,
> b, d) etc.? But again, I would like to be able to do this opaquely
> on top of any function, not a specially crafted one, or else it
> doesn't sound too useful to me. Can someone try to illuminate me
> on the subject? If I got something entirely wrong, please correct me!
>
> Thanks
> Dimitris Andreou
>
>

Paul Chiusano
Joined: 2009-01-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Currying
Also, fyi, all the Function types have a curry method defined, so given f: (A,B) => C, you can just say f.curry(a), which has the type B => C.

On Thu, Jan 1, 2009 at 3:15 PM, Dimitris Andreou <jim [dot] andreou [at] gmail [dot] com> wrote:
Thanks a lot James! That's a very nice summary, hopefully I'll be able to feel at home with all the various forms.

Syntax apart, am I right in thinking that partial appication is a superset of currying? Here's my attempt:

scala> def curry[A, B, C](f: (A, B) => C) = (x:A) => f(x, _:B)
curry: [A,B,C]((A, B) => C)(A) => (B) => C

Which seems functionally (no pun) equivalent to the one you gave. I understand though that syntactically currying would be better if the function has lots of parameters and I wanted to partially apply each parameter in the order of appearance (but I can't imagine another use-case where the difference of them would be highlighted).

(A side note: the syntax still seems a bit tricky to me. Removing from the above the paren's around 'x:A' results in error)

Happy new year! :)
Dimitris

O/H James Iry έγραψε:
Currying is taking a function of type (A,B) => C and creating a function of type A => B => C.   In Scala, currying can be done both syntactically (def foo(x:A)(y:B) : C = ...) and using an appropriate function.  For instance, here's a curry function for arity 2

scala> def curry[A,B,C](f : (A,B) => C) = {x : A => y : B => f(x,y)}
curry: [A,B,C]((A, B) => C)(A) => (B) => C

And here's using it

scala> def add(x : Int, y : Int) = x + y
add: (Int,Int)Int

scala> val curriedAdd = curry(add)
curriedAdd: (Int) => (Int) => Int = <function>

scala> val plusOne = curriedAdd(1)
plusOne: (Int) => Int = <function>

scala> plusOne(4)
res0: Int = 5


What you're describing is partial application, which is of course related.  You can use a curry function like above to do partial application by just applying an argument on the same line as where you curry

scala> val plusOne2 = curry(add)(1)
plusOne2: (Int) => Int = <function>

scala> plusOne2(5)
res1: Int = 6

But you don't need all that, because you can partially apply anything in Scala using _ notation

scala> val plusOne3 = add(1, _:Int)
plusOne3: (Int) => Int = <function>

scala> plusOne3(6)
res2: Int = 7

On Thu, Jan 1, 2009 at 9:06 AM, Dimitris Andreou <jim [dot] andreou [at] gmail [dot] com <mailto:jim [dot] andreou [at] gmail [dot] com>> wrote:

   Hi,
   I'm new to this list and to Scala too. I'm reading through the
   currying chapter of Programming in Scala, and I've a pretty basic
   question.

   Perhaps I misunderstood the term, but I thought 'currying'
   described the ability to bind some parameters to an existing
   function and derive another one, with fewer parameters. I thought
   it would be possible to take *any* function, treating it as a
   black-box, bind some parameters to it and derive another. But it
   seems that this can't be applied to a function in an
   after-the-fact fashion - the author must built this ability inside
   a particular function. Also, this doesn't give the ability to bind
   an arbitrary parameter of the function, but the first one(s).
   I.e., if I have a function with four parameters:

   f(a, b, c, d)

   I could implement it in scala in a way that I could derive functions:

   f(b, c, d)
   f(c, d)
   f(d)
   f()

   Is there a way I could also derive functions like f(a, b, c), f(a,
   b, d) etc.? But again, I would like to be able to do this opaquely
   on top of any function, not a specially crafted one, or else it
   doesn't sound too useful to me. Can someone try to illuminate me
   on the subject? If I got something entirely wrong, please correct me!

   Thanks
   Dimitris Andreou




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