Ordenação de parâmetros para fazer uso de currying

93

Refatorei recentemente o código duas vezes para alterar a ordem dos parâmetros porque havia muito código onde os hacks gostavam flipou \x -> foo bar x 42estavam acontecendo.

Ao projetar uma assinatura de função, quais princípios me ajudarão a fazer o melhor uso do currying?

John F. Miller
fonte

Respostas:

111

Para linguagens que suportam currying e aplicação parcial facilmente, há uma série de argumentos convincentes, originalmente de Chris Okasaki:

  • Coloque a estrutura de dados como o último argumento

Por quê? Você pode, então, compor operações nos dados de maneira adequada. Ex insert 1 $ insert 2 $ insert 3 $ s. Isso também ajuda para funções no estado .

Bibliotecas padrão, como "contêineres", seguem essa convenção .

Argumentos alternativos às vezes são fornecidos para colocar a estrutura de dados em primeiro lugar, para que ela possa ser fechada, gerando funções em uma estrutura estática (por exemplo, pesquisa) que são um pouco mais concisas. No entanto, o amplo consenso parece ser que isso não é uma vitória, especialmente porque o empurra para um código fortemente colocado entre parênteses.

  • Coloque o argumento mais variado por último

Para funções recursivas, é comum colocar o argumento que mais varia (por exemplo, um acumulador) como o último argumento, enquanto o argumento que varia menos (por exemplo, um argumento de função) no início. Isso combina bem com o último estilo da estrutura de dados.


Um resumo da visão de Okasaki é fornecido em sua biblioteca Edison (novamente, outra biblioteca de estrutura de dados):

  • Aplicação parcial : os argumentos com maior probabilidade de serem estáticos geralmente aparecem antes de outros argumentos para facilitar a aplicação parcial.
  • A coleção aparece por último : em todos os casos em que uma operação consulta uma única coleção ou modifica uma coleção existente, o argumento da coleção aparecerá por último. Este é um padrão de fato para bibliotecas de estrutura de dados Haskell e dá um certo grau de consistência à API.
  • Ordem mais comum : onde uma operação representa uma função matemática bem conhecida em mais de uma estrutura de dados, os argumentos são escolhidos para corresponder à ordem de argumento mais comum para a função.
Don Stewart
fonte
Como corolário do primeiro ponto, coloque também o argumento de que pode viver em uma estrutura de dados por último. Torna o mapa, a dobra e os amigos mais limpos. tl; dr coisa na lista vai por último.
John F. Miller de
1
A pesquisa não pode ser encadeada de qualquer maneira, então o primeiro ponto não oferece suporte a isso. haskell.org/haskellwiki/Parameter_order apresenta um argumento convincente ao contrário - "Uma vez que os objetos do tipo Map representam mapeamentos, é natural ter alguma função que transforma um objeto Map na função representada."
Brandon
11

Coloque os argumentos que você provavelmente reutilizará primeiro. Os argumentos da função são um ótimo exemplo disso. É muito mais provável que você deseje map fmais de duas listas diferentes do que mapear muitas funções diferentes na mesma lista.

Hammar
fonte
5
Se você estiver de fato mapeando muitas funções na mesma lista, talvez deva fazer uma lista de funções e, map ($myList)em vez disso, essa lista.
Squidly
3

Eu tendo a fazer o que você fez, escolher alguma ordem que pareça boa e então refatorar se descobrir que outra ordem é melhor. A ordem depende muito de como você vai usar a função (naturalmente).

agosto
fonte