Created
November 28, 2011 01:02
-
-
Save devboy/1398638 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
package org.devboy; | |
import haxe.macro.Type; | |
import neko.Lib; | |
import haxe.macro.Expr; | |
import haxe.macro.Context; | |
class Funk | |
{ | |
@:macro public static function partial( expressions: Array<Expr> ): Expr | |
{ | |
var pos = Context.currentPos(); | |
function mk(e:ExprDef) return { expr: e, pos: pos }; | |
var methodExpression = expressions.shift(); | |
var methArgs = extractArgumentsOfMethodType( Context.typeof( methodExpression ) ); | |
var argumentExpressions: Array<Expr> = []; | |
var args: Array<FunctionArg> = []; | |
var expression: Expr; | |
for ( i in 0...methArgs.length ) | |
{ | |
expression = (expressions.length - 1) >= i ? expressions[i] : null; | |
if ( expression != null && isWildcard(expression) ) | |
{ | |
args.push( { name: methArgs[i].name, opt: false, type: null, value: null } ); | |
argumentExpressions.push( mk( EConst( CIdent( methArgs[i].name ) ) ) ); | |
} | |
else if( expression != null && !isWildcard(expression) ) | |
{ | |
argumentExpressions.push( expression ); | |
} | |
else | |
{ | |
args.push( { name: methArgs[i].name, opt: false, type: null, value: null } ); | |
argumentExpressions.push( mk( EConst( CIdent( methArgs[i].name ) ) ) ); | |
} | |
} | |
return mk( EFunction( null, | |
{ | |
ret: null, params: [], args: args, | |
expr: mk( EReturn( mk( ECall( methodExpression, argumentExpressions )))) | |
} | |
)); | |
} | |
@:macro public static function curry( expressions: Array<Expr> ): Expr | |
{ | |
var pos = Context.currentPos(); | |
function mk(e:ExprDef) return { expr: e, pos: pos }; | |
var methodExpression = expressions.length > 1 ? partial(expressions) : expressions.shift(); | |
var methArgs = extractArgumentsOfMethodType( Context.typeof( methodExpression ) ); | |
var lastMethodArgumentExpressions: Array<Expr> = []; | |
for ( arg in methArgs) | |
lastMethodArgumentExpressions.push( mk( EConst( CIdent( arg.name ) ) ) ); | |
var lastMethodArgs: Array<FunctionArg> = methArgs.length > 0 ? [{ name: methArgs[methArgs.length-1].name, opt: false, type: null, value: null }] : []; | |
var lastMethodExpression = mk( EFunction( null, | |
{ | |
ret: null, params: [], args: lastMethodArgs, | |
expr: mk( EReturn( mk( ECall( methodExpression, lastMethodArgumentExpressions )))) | |
} | |
)); | |
methArgs.pop(); | |
var chainedExpression: Expr = lastMethodExpression; | |
var currentArg = methArgs.pop(); | |
while (currentArg != null) | |
{ | |
chainedExpression = mk( EFunction( null, | |
{ | |
ret: null, params: [], args: [{ name: currentArg.name, opt: false, type: null, value: null }], | |
expr: mk( EReturn( chainedExpression )) | |
})); | |
currentArg = methArgs.pop(); | |
} | |
return chainedExpression; | |
} | |
private inline static function isWildcard( expression:Expr ): Bool | |
{ | |
switch( expression.expr ) | |
{ | |
case EConst( c ): | |
switch( c ) | |
{ | |
case CIdent(s): | |
return s == "_"; | |
default: | |
return false; | |
} | |
default: | |
return false; | |
} | |
} | |
private inline static function extractArgumentsOfMethodType( methodExpression: haxe.macro.Type ): Array<{ name : String, opt : Bool, t : Type }> | |
{ | |
return switch( methodExpression ) | |
{ | |
case TFun(args, ret): args; | |
default: null; | |
} | |
} | |
private inline static function createExpressionDefinition( pos: Position, expressionDefinition: ExprDef ) | |
{ | |
return { expr: expressionDefinition, pos: pos }; | |
} | |
} |
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
package org.devboy.hxTask; | |
import neko.Lib; | |
import org.devboy.Funk; | |
class Main | |
{ | |
static function main() | |
{ | |
var func = function( x: Float, y: Float, z: Float ): Float | |
{ | |
return x * y * z; | |
} | |
var curried = function(x: Float) | |
{ | |
return function(y: Float) | |
{ | |
return function(z: Float) | |
{ | |
return func(x, y, z); | |
} | |
} | |
} | |
Lib.println( curried(2)(2)(2) ); // returns 8 | |
var funkCurried = Funk.curry( func ); | |
type( funkCurried ); | |
Lib.println( funkCurried(2)(2)(2) ); // returns 8 | |
} | |
} |
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
package org.devboy.hxTask; | |
import neko.Lib; | |
import org.devboy.Funk; | |
class Main | |
{ | |
static function main() | |
{ | |
var abc = function( a, b, c ) return a + b + c; | |
var ac = Funk.partial( abc, _, 10, _ ); | |
Lib.println(ac(5,15)); // returns 30 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment