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?

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.

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.


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).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.