We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Why Curry?

It's fairly obvious that:

def sum(a: int, b: int) -> int:
    return a + b

is simpler than:

from collections.abc import Callable


def sum(a: int) -> Callable[[int], int]:
    def inner_sum(b: int) -> int:
        return a + b

    return inner_sum

So why would we ever want to do the more complicated thing? Well, currying can be used to change a function's signature to make it conform to a specific shape. For example:

def colorize(converter: Callable[[str], str], doc: str) -> None:
    # ...
    converter(doc)
    # ...

The colorize function accepts a function called converter as input, and at some point during its execution, it calls converter with a single argument. That means that it expects converter to accept exactly one argument. So, if I have a conversion function like this:

def markdown_to_html(doc: str, asterisk_style: str) -> str:
    # ...

I can't pass markdown_to_html to colorize because markdown_to_html wants two arguments. To solve this problem, I can curry markdown_to_html into a function that takes a single argument:

def markdown_to_html(asterisk_style: str) -> Callable[[str], str]:
    def asterisk_md_to_html(doc: str) -> str:
        # do stuff with doc and asterisk_style...

    return asterisk_md_to_html

markdown_to_html_italic: Callable[[str], str] = markdown_to_html("italic")
colorize(markdown_to_html_italic, doc)