Skip to content

Instantly share code, notes, and snippets.

@uehaj
Last active December 29, 2015 01:09
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save uehaj/7591318 to your computer and use it in GitHub Desktop.
Handle Optional as Applicative
import java.util.Optional;
ExpandoMetaClass.enableGlobally() //you need this to add method through EMC to Closure.
// see: http://jira.codehaus.org/browse/GROOVY-3674
Optional.metaClass.and = { Optional xs -> // Haskell's <*> (ap)
delegate.flatMap({Closure f->
xs.map({x->
if (f.parameterTypes.size() > 1) {
// In Haskell, if the number of supplied actural arguments is lesser
// then the number of expecting parameters(which is always 1),
// function is automatically partially applied, but Groovy don't.
// So we need call curry(partiall apply) explicitly.
return f.curry(x)
}
else {
return f.call(x)
}
})})
}
Closure.metaClass.mod = { Optional xs -> // Haskell's <$> (fmap)
Optional.of(delegate) & xs
}
Closure.metaClass.applyOptional = { Object... args ->
def result = Optional.of(delegate)
args.each {
result = result & it
}
return result
}
Optional<String> arg1 = Optional.of("Abc")
Optional<String> arg2 = Optional.of("Def")
Optional<String> NULL = Optional.empty()
assert ({a,b -> a+' '+b} % arg1 & arg2) == Optional.of("Abc Def")
assert ({a,b -> a+' '+b} % arg1 & NULL) == NULL
assert ({a,b -> a+' '+b} % NULL & arg1) == NULL
assert ({a,b -> String.join(' ', a, b)} % arg1 & arg2) == Optional.of("Abc Def")
assert ({a,b -> String.join(' ', a, b)} % arg1 & NULL) == NULL
assert ({a,b -> String.join(' ', a, c)} % NULL & arg1) == NULL
Closure c1 = {a,b -> a+b}
Closure c2 = {a,b -> a.toUpperCase()+b.toLowerCase()}
Closure c3 = {a,b -> a.length() * b.length()}
assert (c1 % arg1 & arg2) == Optional.of("AbcDef")
assert (c1 % arg1 & NULL) == NULL
assert (c1 % NULL & NULL) == NULL
assert (c2 % arg1 & arg2) == Optional.of("ABCdef")
assert (c2 % NULL & arg2) == NULL
assert (c2 % NULL & NULL) == NULL
assert (c3 % arg1 & arg2) == Optional.of(9)
assert c1.applyOptional(arg1, arg2) == Optional.of("AbcDef")
assert c1.applyOptional(arg1, NULL) == NULL
assert c1.applyOptional(NULL, NULL) == NULL
assert c2.applyOptional(arg1, arg2) == Optional.of("ABCdef")
assert c2.applyOptional(NULL, arg2) == NULL
assert c2.applyOptional(NULL, NULL) == NULL
assert c3.applyOptional(arg1, arg2) == Optional.of(9)
assert ({a,b -> a+' '+b} % arg1 & arg2) == Optional.of("Abc Def")
assert ({a,b,c -> a+' '+b+' '+c} % arg1 & arg2 & arg1) == Optional.of("Abc Def Abc")
assert ({a,b,c,d -> a+' '+b+' '+c+' '+d} % arg1 & arg2 & arg1 & arg2) == Optional.of("Abc Def Abc Def")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment