Skip to content

Instantly share code, notes, and snippets.

@fcard
Last active August 29, 2015 14:22
Show Gist options
  • Save fcard/a37683ab25561953138a to your computer and use it in GitHub Desktop.
Save fcard/a37683ab25561953138a to your computer and use it in GitHub Desktop.
Simple curried functions in Julia
# Definition
immutable Curried{N}
func::Function
end
Base.call(cf::Curried{1}, arg) = cf.func(arg)
Base.call(cf::Curried{1}, arg, args...) = error("Wrong numbers of arguments in curried function.")
Base.call{N}(cf::Curried{N}, arg) = Curried{N-1}(cf.func(arg))
Base.call{N}(cf::Curried{N}, arg, args...) = cf(arg)(args...)
# Helper functions
funcname(funcdef) = funcdef.args[1].args[1]
funcargs(funcdef) = funcdef.args[1].args[2:end]
funcbody(funcdef) = funcdef.args[2]
anonargs(anondef) = anondef.args[1].args
makeanon(arg,body) = :($arg -> $body)
# API -- @curried
function _curried(funcdef)
if funcdef.head == :(->)
_curried(funcbody(funcdef), anonargs(funcdef))
else
:(const $(esc(funcname(funcdef))) =
$(_curried(funcbody(funcdef), funcargs(funcdef))))
end
end
function _curried(body, args)
N = length(args)
F = foldr(makeanon, body, args)
quote
$Curried{$N}($F)
end
end
macro curried(fundef)
_curried(fundef)
end
# Usage
@curried f(x,y,z) = x+y+z
@curried function g(x,y,z)
x*y*z
end
const h = @curried (x,y,z) -> [x,y,z]
const f1 = f(1)
println(f1(2,3)) #-> 6
const g23 = g(2,3)
println(g23(4)) #-> 24
const ha = h('a')
println(ha('b', 'c')) #-> ['a','b','c']
println(f(1,2,3)) #-> 6
println(g(2,3,4)) #-> 24
println(h(1,2,3)) #-> [1,2,3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment