Skip to content

Instantly share code, notes, and snippets.

@rizumita
Created November 25, 2011 22:03
Show Gist options
  • Save rizumita/1394522 to your computer and use it in GitHub Desktop.
Save rizumita/1394522 to your computer and use it in GitHub Desktop.
Objective-C Currying
@interface NSObject (Curry)
- (id)curry:(SEL)selector;
@end
@implementation NSObject (Curry)
- (id)curry:(SEL)selector {
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
if (signature) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = selector;
invocation.target = self;
NSScanner *scanner = [NSScanner scannerWithString:NSStringFromSelector(selector)];
int argsCount = 0;
while (![scanner isAtEnd]) {
if ([scanner scanUpToString:@":" intoString:nil]) {
argsCount++;
}
[scanner scanString:@":" intoString:nil];
}
__block int index = 0;
__block id (^f)(void *) = ^(void *arg) {
[invocation setArgument:&arg atIndex:index + 2];
index++;
if (index == argsCount) {
[invocation invoke];
void *returnValue;
[invocation getReturnValue:&returnValue];
return (__bridge_transfer id)returnValue;
} else {
return f;
}
};
return f;
} else {
return nil;
}
}
@end
@interface NSString (Extras)
- (id)first:(NSString *)str1 second:(NSString *)str2 third:(NSString *)str3;
@end
@implementation NSString (Extras)
- (id)first:(NSString *)str1 second:(NSString *)str2 third:(NSString *)str3 {
return [self stringByAppendingFormat:@" %@ %@ %@", str1, str2, str3];
}
@end
int main (int argc, const char * argv[]) {
@autoreleasepool {
NSString *str = @"test";
id (^f)(void *) = [str curry:@selector(first:second:third:)];
f = f(@"1");
f = f(@"2");
NSLog(@"%@", f(@"3"));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment