Last active
October 22, 2015 17:03
-
-
Save hooman/d8629fb001798d3bee6e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Y-Combinator for creating recursive closures. | |
/// | |
/// :param: `In` Arbitrary input parameter type(s) of the closure. | |
/// :param: `Out` Arbitrary return type (including `Void`) of the closure. | |
/// :param: `f` represents the recursive closure. | |
/// :returns: Returns a recursive closure. | |
/// | |
/// It is used with a pair of closures: An outer closure that names the inner closure (`f`) | |
/// and lets the inner closure recurse on itself by capturing itself using the parameter of | |
/// the outer closure (`f`). For example: | |
/// | |
/// .. parsed-literal:: | |
/// | |
/// let fac = Y { f in { x in | |
/// | |
/// /* f(x) = */ x < 2 ? 1 : x * f(x - 1) | |
/// }} | |
/// | |
/// **Note:** `In` and `Out` can be arbitrary tuples, hence you may have arbitrary number and | |
/// type of arguments and return values for the closure. Including empty tuple `()` or `Void`. | |
/// | |
func Y <In, Out> ( f: (In->Out) -> (In->Out) ) -> (In->Out) { | |
return { x in f(Y(f))(x) } | |
} | |
// A couple of examples to try in a playground: | |
let fac = Y { f in { n in | |
n < 2 ? 1 : n * f(n - 1) | |
}} | |
let fib = Y { f in { n in | |
n <= 2 ? 1 : f(n-1) + f(n-2) | |
}} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This translates beautifully to Swift, doesn't it? A useful reference for anyone looking at this: http://mvanier.livejournal.com/2897.html.