Skip to content

Instantly share code, notes, and snippets.

@vtjnash
Created May 29, 2017 00:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vtjnash/79250ee485b50856bffaec32299d7130 to your computer and use it in GitHub Desktop.
Save vtjnash/79250ee485b50856bffaec32299d7130 to your computer and use it in GitHub Desktop.
# goal: compute [Nullable(x ^ 2 + x) for x in filter!(isodd, data)]
# using the following syntax:
data |>
(+filter!)( isodd ) |>
(+map)( x -> x^2 ) |>
(2 + map)((x, y) -> (x + y), data)
import Base: +
# masochistic oneliner
+(f) = ((g, args...) -> (arg -> f((arg -> isnull(arg) ? arg : g(arg)), arg, args...)))
# same function, written more sanely
+(f) = function(g, args...)
lift(arg) = isnull(arg) ? arg : g(arg)
lifted(arg) = f(lift, arg, args...)
return lifted
end
# same function, written for inserting arguments at arbitrary (parameterized) N
@inline _insert(i, xn, x1, x...) = (ifelse(i == 1, xn, x1), _insert(i - 1, ifelse(i == 1, x1, xn), x...)...)
+(N::Int, f::Function) = function(g, args...)
lift(args...) = isnull(args[N]) ? args[N] : g(args...)
lifted(arg) = f(lift, insert(args, arg, N)...)
end
+(f::Function) = (1 + f)
+(N::Int, f) = ((::Val{N}) where {N} -> function(g, arghead::Vararg{Any, N}, argtail...)
lift(arghead::Vararg{Any, N}, argn, argtail...) = isnull(arg) ? arg : g(arghead..., arg, argtail...)
lifted(arg) = f(lift, arghead..., arg, argtail...)
return lifted
end)(Val{N}())
# returns new tuple; N.B.: becomes no-op if i is out-of-bounds
# better codegen NTuple{Any}:
#@inline _insert(i, xn, x1, x...) = ifelse(i == 1, (xn, x1, x...), (x1, _insert(i - 1, xn, x...)...))
# better codegen NTuple{T}:
#@inline _insert(i, xn, x1, x...) = (ifelse(i == 1, xn, x1), _insert(i - 1, ifelse(i == 1, x1, xn), x...)...)
# simplest definition:
#insert(x::Tuple, v, i::Integer) = (x[1:(i - 1)]..., v, x[i:end]...)
# worst definition:
#@inline insert(x::Tuple, v, i::Integer) = _insert(v, i, x...)
#@inline function _insert(v, i::Integer, first, tail...)
# return ifelse(i == 1, (v, first, tail...), (first, _insert(v, i - 1, tail...)...))
# #return (ifelse(i == 1, (v,), ())..., first, _insert(v, i - 1, tail...)...)
#end
#_insert(v, i::Integer) = ()
function +(N::Int, f)
function(g, args...)
function build(f, ::Val{N}) where {N}
f2(argn, arg1, args...) = f(lift, arg1, argn, args...)
return build(f2, Val{N - 1}())
end
function build(f, ::Val{1})
lift(args...) = isnull(args[N]) ? args[N] : g(args...)
lifted(arg) = f(lift, arg, args...)
return lifted
end
return build(f, Val{N}())
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment