Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

When I first started with Scala, I fell into a trap that almost every functional programmer hits: I thought currying was just a fancy way of writing multiple parameter lists to make the code look "more academic." I figured it was just a syntactic preference, like choosing between a for loop and a while loop. I was wrong.

"It's just a different way to write parentheses"

The misconception is that def add(x: Int)(y: Int) is functionally identical to def add(x: Int, y: Int). On the surface, when you call add(1)(2), you get the same result as add(1, 2). But this ignores the fundamental shift in what the function is.

// Standard function: Takes two Ints, returns one Int
def multiply(x: Int, y: Int): Int = x * y

// Curried function: Takes one Int, returns A NEW FUNCTION that takes one Int
def curriedMultiply(x: Int)(y: Int): Int = x * y

In the first example, you have a single jump from input to output. In the second, you've created a factory. If I call curriedMultiply(10), the program doesn't throw an error for missing an argument; instead, it returns a function that "remembers" the number 10 and is just waiting for the second number to finish the job. That's the core of currying: transforming a function that takes $n$ arguments into a chain of $n$ functions that each take a single argument.

Turning a general tool into a specialized one

Now, why would you actually do this in a production codebase? The real power comes when you combine currying with partial application. I often use this when I have a set of configuration parameters that stay the same for a while, followed by the actual data that changes constantly.

Imagine we're building a system to calculate shipping costs based on a carrier's base rate and a package weight. Instead of passing the base rate every single time, we curry the function:

def calculateShipping(baseRate: Double)(weight: Double): Double = {
  baseRate * weight
}

// I can now "lock in" the rate for FedEx
val fedExShipping = calculateShipping(15.50) 
val upsShipping = calculateShipping(12.00)

// Now I have specialized functions for specific carriers
val cost1 = fedExShipping(2.5) // Only need to provide the weight now
val cost2 = upsShipping(2.5)

I've essentially used currying to create a "template" for shipping. This keeps the business logic (the multiplication) separate from the configuration (the rates), and it makes your call sites much cleaner.

The secret weapon: Type Inference

If the "specialization" argument doesn't convince you, the type system will. This is where currying becomes non-negotiable in Scala. Scala's type inference works from left to right. In a standard function, the compiler tries to infer the types of all parameters at once.

But with curried functions, the compiler can infer the type of the first block of parameters and use those types to determine the requirements for the second block. You'll see this everywhere in the Scala standard library, especially with map or implicit parameters. If we had one giant list of parameters, the compiler often wouldn't be able to "guess" the type of the second argument based on the first, forcing you to write tedious, explicit type annotations everywhere. Currying gives the compiler a chance to breathe and figure things out for you.




📋 Practical Task

Build a Dynamic Discount Engine

You are tasked with creating a flexible pricing system for an e-commerce platform. Instead of writing separate functions for every possible sale, you will use currying to create a general discount applicator that can be specialized for different events.

Requirements:

  • Create a curried function named applyDiscount. The first parameter list should take a discountPercentage (Double), and the second parameter list should take the originalPrice (Double).
  • The function should return the final price after the discount is applied.
  • Using applyDiscount, create two specialized functions: blackFridayDiscount (which applies a 40% discount) and summerSaleDiscount (which applies a 15% discount).
  • Test both specialized functions with a product priced at 100.0 to ensure they return 60.0 and 85.0 respectively.
// Your code here
Rating
0 0

There are no comments for now.

to be the first to leave a comment.