Typecase Regular Swift Function to Curry Function

Typecase regular Swift function to Curry Function

You don't typecast it, you return nested closures that capture each parameter in turn:

func add(x: Int, y: Int) -> Int {
return x + y
}

func curry<T1, T2, T3>(f: (T1, T2) -> T3) -> T1 -> T2 -> T3 {
return {
(t1: T1) -> T2 -> T3 in

return {
(t2: T2) -> T3 in

return f(t1, t2)
}
}
}

let curriedAdd = curry(add)
let add3 = curriedAdd(3)
println(add3(5))
// 8

This is more succinct:

func curry<T1, T2, T3>(f: (T1, T2) -> T3) -> T1 -> T2 -> T3 {
return { t1 in { t2 in f(t1, t2) } }
}

I thought it would be fun to write a curry maker; here it is - if anyone knows how to make one of these that generates an actual function that would be amazing:

func curryRecipe(n: Int) -> String {
let types = join(", ", map(1...n, { "T\($0)" }))
let returnType = join(" -> ", map(1...n, { "T\($0)" }))
let closures = join(" in ", map(1...n, { "{ t\($0)" }))
let braces = join(" ", Array(count: n, repeatedValue: "}"))
return "func curry<\(types), R>(f: (\(types)) -> R) -> \(returnType) -> R {\r" +
" return \(closures) in f(\(types.lowercaseString)) \(braces)\r}"
}

println(curryRecipe(15))

Output:

func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R>(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R) -> T1 -> T2 -> T3 -> T4 -> T5 -> T6 -> T7 -> T8 -> T9 -> T10 -> T11 -> T12 -> T13 -> T14 -> T15 -> R {
return { t1 in { t2 in { t3 in { t4 in { t5 in { t6 in { t7 in { t8 in { t9 in { t10 in { t11 in { t12 in { t13 in { t14 in { t15 in f(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) } } } } } } } } } } } } } } }
}

Curry Function in Swift

You can achieve this pretty easily with closures:

/// Takes a binary function and returns a curried version
func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C {
return { a in { b in f(a, b) } }
}

curry(+)(5)(6) // => 11

let add: Int -> Int -> Int = curry(+)
add(5)(6) // => 11

It would be really nice to be able to do the same thing for functions that take 3, 4 or more arguments, but without duplicating the implementation. The signature of such a function might start something like:

/// Take a function accepting N arguments and return a curried version
func curry<T>(args: T...) -> /* ? */

What would the return type be? It would change based on the input to the function. This definitely isn't possible in Swift at the moment, and I don't think it would be possible at all without some kind of macro system. But even with macros I don't think the compiler would be satisfied unless it knew the length of the list at compile-time.

Having said that, it's really straight-forward to manually overload the currying function with a version that accepts 3, 4, 5 or more parameters:

func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D {
return { a in { b in { c in f(a,b,c) } } }
}

func curry<A,B,C,D,E>(f: (A, B, C, D) -> E) -> A -> B -> C -> D -> E {
return { a in { b in { c in { d in f(a,b,c,d) } } } }
}

// etc.

How to write a flip method in Swift?

A->B->C is the type of a function taking one argument of type A
and returning a function B->C (a "curried" function). The type of a function taking
two arguments is (A, B)->C:

func flip<A, B, C>(f: (A, B)->C) -> (B, A)->C {

return { (valueB: B, valueA: A) in
return f(valueA, valueB)
}
}

let x = flip(-)(10, 5)
println(x) // -5

It can slightly be shortened to

func flip<A, B, C>(f: (A, B)->C) -> (B, A)->C {

return { (valueB, valueA) in
f(valueA, valueB)
}
}

due to automatic type inference.

As far as I know, Swift does not automatically convert functions
taking multiple arguments into curried functions, compare
Typecase regular Swift function to Curry Function.

What is a generalized uncurry function in Scheme, for a curry function of n parameter?

A generic uncurry can be written to call a function, f, with arguments, t, one at a time -

(define ((uncurry f) . t)
(if (null? t)
f
(apply (uncurry (f (car t)))
(cdr t))))

Using it on (curry +) will not work because + is a variadic function. However, for functions of known arity, it works just fine -

(define (plus a b c)
(+ a b c))

((uncurry (curry plus)) 1 2 3) ; 6

If you don't supply all three arguments, the "remainder" of the curried function will be returned -

(((uncurry (curry plus)) 1 2) 3)     ; 6
((((uncurry (curry plus)) 1) 2) 3) ; 6
(((((uncurry (curry plus))) 1) 2) 3) ; 6

Subsequent calls to uncurry could be used if additional arguments need to be supplied at a later time -

((uncurry ((uncurry (curry plus)) 1)) 2 3) ; 6

However, if you try to apply too many arguments, a run time error will be raised -

((uncurry (curry plus)) 1 2 3 4)     ; error, expected procedure; 6 given

Is there a way to perform a generalized uncurry function on curried, variadic functions? That was what the question was referring to with "generalized", needs to be able to work on a variable number of arguments.

I recommend you see molbdnilo's comment on your question. You cannot effectively curry a variadic function like + because currying is the abstraction of arity. To put this another way, if + can take 0 to infinite arguments, how many applied arguments should (curry +) take before it returns a sum rather than a function?

Maybe you are looking for partial application?

(define ((partial f . a) . b)
(apply f (append a b)))
((partial + 1 2)) ; 3
((partial + 1) 2) ; 3
((partial +) 1 2) ; 3

pattern match in curry function: which paramter to match against

Let's step through your function:

1.We apply the first parameter "b" to curr3 and get back a function that takes a string and gives us back a string:

  val first:String => String = curr3("b")

which is equivalent to (basically we've thrown away the first parameter n):

  val first:String => String = {
case "a" => "a"
case "b" => "b"
}

2.We apply the second parameter to first and get back "a":

  val second:String = first("a")
println(second) // prints a

So the first parameter is taken in but never used. If you want to match on the first parameter you could do this:

  def curr3(n: String): String => String = s => n match {
case "a" => "a"
case "b" => "b"
}

But now we're just throwing away the second parameter s. I think you don't really need a curried function here (unless you want to do something with the second paramater) and you could do something simple similar to the first example:

  def curr3(n: String) = n match {
case "a" => "a"
case "b" => "b"
}

Understanding Generic Functions in Common Lisp?

What value would creating a generic functions add?

I like to declare the generic function explicitly because it is possible to add documentation and declarations that are relative to the generic function (optimize for speed/space/debug), and other details such as method combination (a.k.a. when you have multiple methods applicable for a given call, this defines which are executed and in which order). Here for example I can define talk as having a progn method combination (all methods are executed as-if encapsulated in a progn form):

(defgeneric talk (subject)
(:documentation "Say something to standard output")
(:method-combination progn))

This is a bit contrived example, but here we go:

(defclass human () ())
(defmethod talk progn ((a human))
(print "hello"))

(defclass wolf () ())
(defmethod talk progn ((a wolf))
(print "owooooo!"))

(defclass werewolf (human wolf) ())

Defining a class that inherits from both means that a call to talk for an instance of the class can execute two methods (sorted in a somewhat topological order called the Method Resolution Order). So with this method combination all the methods are executed:

* (talk (make-instance 'werewolf))
"hello"
"owooooo!"

But, I would say that being able to document the generic function is by itself a good enough reason to declare it with defgeneric.

Why are generic functions useful?

If you define talk as a generic function you allow any class to participate in code that calls talk (e.g. a library), this is a way to allow extensions without having to close the set of possible values, unlike using something like typecase in a function where you can only list a predefined set of cases.

For example the standard functions print-object is called at various times in your Lisp implementation (in the inspector, the REPL, the debugger), if you want you can implement a method for your custom types without having to hack the internals of your environment.

Are they like instances in other OO languages that provide structure?

Generic functions are, unlike in other OO languages, not tied to a single class or instance. They can be specialized1 on more than one argument, which means none of them "owns" the generic function.


1. specialized is defined as follows:

specialize v.t. (a generic function) to define a method for the generic function, or in other words, to refine the behavior of the generic function by giving it a specific meaning for a particular set of classes or arguments.

The idea behind this is that methods can be more or less specific: a method of two arguments a and b that specializes both on (a number) and (b string) is more specific than another one that specializes only on (b vector), and methods are actually sorted from the most specific to the least specific ones (resp. from the least to the most) when combining them. You can even specialize a function on (a (eql 10)) to cover only the specific case of an argument a being eql to 10.



Related Topics



Leave a reply



Submit