Eu queria saber se existe alguma maneira de puxar isso em Java. Acho que não é possível sem suporte nativo para fechamentos.
88
Eu queria saber se existe alguma maneira de puxar isso em Java. Acho que não é possível sem suporte nativo para fechamentos.
Respostas:
Java 8 (lançado em 18 de março de 2014) oferece suporte ao currying. O exemplo de código Java postado na resposta por missingfaktor pode ser reescrito como:
... o que é muito bom. Pessoalmente, com o Java 8 disponível, vejo poucos motivos para usar uma linguagem JVM alternativa, como Scala ou Clojure. Eles fornecem outros recursos de linguagem, é claro, mas isso não é suficiente para justificar o custo de transição e o suporte a IDE / ferramentas / bibliotecas mais fraco, IMO.
fonte
(def adder5 (partial + 5)) (prn (adder5 4)) (prn adder5 6)
O currying e a aplicação parcial são absolutamente possíveis em Java, mas a quantidade de código necessária provavelmente irá desligá-lo.
Algum código para demonstrar currying e aplicação parcial em Java:
FWIW aqui é o equivalente Haskell do código Java acima:
fonte
Há muitas opções para Currying com Java 8. Tipo de função Javaslang e jOOλ, ambos oferecendo Currying pronto para uso (acho que foi um descuido no JDK), e o módulo de Funções do Cyclops tem um conjunto de métodos estáticos para Currying funções JDK e referências de métodos. Por exemplo
'Currying' também está disponível para consumidores. Por exemplo, para retornar um método com 3 parâmetros, e 2 daqueles já aplicados, fazemos algo semelhante a este
Javadoc
fonte
currying
noCurry.curryn
código-fonte.EDIT : A partir de 2014 e Java 8, a programação funcional em Java agora não só é possível, mas também não é feia (atrevo-me a dizer bonita). Veja por exemplo a resposta do Rogério .
Resposta antiga:
Java não é a melhor escolha, se você pretende usar técnicas de programação funcional. Como missfaktor escreveu, você terá que escrever uma grande quantidade de código para conseguir o que deseja.
Por outro lado, você não está restrito a Java na JVM - você pode usar Scala ou Clojure, que são linguagens funcionais (Scala é, na verdade, funcional e OO).
fonte
Currying requer o retorno de uma função . Isso não é possível com java (sem ponteiros de função), mas podemos definir e retornar um tipo que contém um método de função:
Agora vamos caril uma divisão simples. Precisamos de um divisor :
e um DivideFunction :
Agora podemos fazer uma divisão com curry:
fonte
Bem, Scala , Clojure ou Haskell (ou qualquer outra linguagem de programação funcional ...) são definitivamente AS linguagens a serem usadas para currying e outros truques funcionais.
Dito isso, certamente é possível trabalhar com Java sem a quantidade excessiva de clichês que se poderia esperar (bem, ter que ser explícito sobre os tipos dói muito - dê uma olhada no
curried
exemplo ;-)).Os ensaios abaixo mostrar tanto, currying um
Function3
emFunction1 => Function1 => Function1
:bem como a aplicação parcial , embora não seja realmente à prova de tipos neste exemplo:
Isso é tirado de uma prova de conceito que acabei de implementar para me divertir antes do JavaOne amanhã em uma hora "porque estava entediado" ;-) O código está disponível aqui: https://github.com/ktoso/jcurry
A ideia geral poderia ser expandida para FunctionN => FunctionM, com relativa facilidade, embora "real typesafety" continue sendo um problema para o exemplo de aplicativo partia e o exemplo currying precisaria de um monte de código boilerplaty rapidamente , mas é factível.
Em suma, é factível, mas no Scala está fora da caixa ;-)
fonte
É possível emular currying com Java 7 MethodHandles: http://www.tutorials.de/threads/java-7-currying-mit-methodhandles.392397/
fonte
Sim, veja o exemplo de código para você:
Este é um exemplo simples com curriedAdd sendo uma função curried que retorna outra função, e isso pode ser usado para aplicação parcial dos parâmetros armazenados em curried que é uma função em si. Isso agora é mais tarde aplicado totalmente quando imprimimos na tela.
Além disso, mais tarde você pode ver como você pode usá-lo no estilo JS como
fonte
Mais uma abordagem das possibilidades do Java 8:
Você também pode definir métodos utilitários como este:
O que oferece uma sintaxe indiscutivelmente mais legível:
fonte
O currying de um método sempre é possível em Java, mas não oferece suporte de maneira padrão. Tentar fazer isso é complicado e torna o código bastante ilegível. Java não é a linguagem apropriada para isso.
fonte
Outra opção é aqui para Java 6+
então você pode conseguir curry desta maneira
fonte
Embora você possa fazer Currying em Java, é feio (porque não é suportado) Em Java é mais simples e rápido usar loops simples e expressões simples. Se você postar um exemplo de onde você usaria currying, podemos sugerir alternativas que fazem a mesma coisa.
fonte
2 * ?
Em Java, você faria isso com um loop.Esta é uma biblioteca para currying e aplicação parcial em Java:
https://github.com/Ahmed-Adel-Ismail/J-Curry
Ele também oferece suporte à desestruturação de Tuplas e Map.Entry em parâmetros de método, como, por exemplo, passar um Map.Entry para um método que usa 2 parâmetros, de modo que o Entry.getKey () irá para o primeiro parâmetro, e o Entry.getValue () irá para o segundo parâmetro
Mais detalhes no arquivo README
fonte
A vantagem de usar Currying no Java 8 é que ele permite definir funções de alta ordem e, em seguida, passar uma função de primeira ordem e argumentos de função de uma forma encadeada e elegante.
Aqui está um exemplo de Cálculo, a função derivada.
fonte
Sim, concordo com @ Jérôme, curring em Java 8 não é suportado de forma padrão como em Scala ou outras linguagens de programação funcionais.
fonte