Skip to content

Latest commit

 

History

History
53 lines (38 loc) · 1.74 KB

Currying.md

File metadata and controls

53 lines (38 loc) · 1.74 KB

Currying

Currying is the technique of translating the evaluation of a multi-argument function into evaluating a sequence of single-argument function. Most purely functional programming languages (e.g. Haskell) do that by default.

It is also possible to implement curried functions in PowerShell, thanks to the ability of taking ScriptBlock as argument and return value. Consider the following PowerShell code to implement a curried a + b function:

function Add {
    param([int] $a)
    return {
        param([int] $b)      
        return $a + $b
    }
}

Seems like we could easily build a function that takes an arbitary integer and add it with 2:

$addTwo = Add 2

Let us try it out with 3, and the expected value should be 5:

> &$addTwo 3
3

Surprisingly, it returns 3 instead of 5.

This behaviour is caused by the variable scope design of PowerShell. In our Add function, $a is in local scope. $addTwo is a ScriptBlock, so it does not remember $a at all... When we were evaluating $addTwo, the value of $a was actually $null, and in non-strict mode it evaluated to 0, causing the result to be 3 instead of 5.

Two make it work, we need to return a closure, so the enviromental context could be captured:

function Add {
    param([int] $a)
    return {
        param([int] $b)      
        return $a + $b
    }.GetNewClosure()
}

> &(Add 2) 3
5

Repro env: Windows 11 22H2, PowerShell Core 7.3.0

References