Re: Currying
Dimitris Andreou <jim.andreou <at> gmail.com>
2009-01-01 20:15:11 GMT
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.andreou <at> gmail.com <mailto:jim.andreou <at> gmail.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
>
>