Skip to content

Instantly share code, notes, and snippets.

@hooman
Last active August 29, 2015 14:06
Show Gist options
  • Save hooman/2615b53c73ab61565128 to your computer and use it in GitHub Desktop.
Save hooman/2615b53c73ab61565128 to your computer and use it in GitHub Desktop.
A wrapper class to hold and pass around a Swift function in ObjC Code.
import Foundation
@objc
public final class FuncBox<T,U> {
private var _fn: [T->U]
public var fn: T->U { return _fn[0] }
// A trick to make callable types by (ab)using subscript.
public subscript(param:T) -> U { return _fn[0](param) }
public init(_ fn: T->U) { _fn = [fn] }
public var signature: UInt { return ObjectIdentifier(self.dynamicType.self).uintValue() }
public var parameterSignature: UInt { return FuncBox<T,Void>({ (p:T)->Void in }).signature }
public var returnSignature: UInt { return FuncBox<U,Void>({ (p:U)->Void in }).signature }
public func accepts(#signature: UInt) -> Bool { return parameterSignature == signature }
public func returns(#signature: UInt) -> Bool { return returnSignature == signature }
}
//public let voidSignature = FuncBox<Void,Void>({}).signature
typealias RenderFunction = (String) -> String
typealias RenderLambda = (String, RenderFunction) -> String
func renderText(text: String) -> String { return text.uppercaseString }
let lambda: RenderLambda = { (text, render) -> String in render(text) }
func f() { println("Void->Void") }
func f(x: Double, y: Double) -> Double { return x * y }
class Prefix {
let p: String
init(_ p: String) { self.p = p }
func prefixed(n: String) -> String { return p + " " + n }
}
let fn = FuncBox(renderText)
let fn2 = FuncBox(lambda)
let fn3 = FuncBox { (p:String)->String in p }
let fn4 = FuncBox(Prefix("Mr.").prefixed)
let fn5 = FuncBox<(Double,Double),Double>(f)
let fn6 = FuncBox<Void,Void>(f)
let fn7 = FuncBox<Void,String>({ "The is a test!" })
let fn8 = FuncBox(Prefix.prefixed)
fn.signature
fn.signature == fn2.signature // False
fn.signature == fn3.signature // True
fn.signature == fn4.signature // True
fn.parameterSignature == fn.returnSignature
fn6.returnSignature == fn7.parameterSignature
fn6.signature == fn6.parameterSignature
fn4.signature == fn8.signature
fn4.signature
fn8.returnSignature
fn.signature
fn["test"]
fn2["test", renderText]
fn3["me"]
fn4["Mehr"]
fn5[3,4]
fn6[]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment