- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers

# Abstract Types and Polymorphism

Wed, 2008-12-31, 21:48

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!

Thu, 2009-01-01, 18:37

#2
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:

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

Thu, 2009-01-01, 21:27

#3
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

>

>

Thu, 2009-01-01, 22:17

#4
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:

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

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