Em F #, o uso do operador pipe-forward,, |>
é bastante comum. No entanto, em Haskell, eu só vi composição de funções,, (.)
sendo usada. Eu entendo que eles estão relacionados , mas há um motivo de linguagem para que o pipe-forward não seja usado em Haskell ou é outra coisa?
haskell
f#
functional-programming
composition
Ben Lings
fonte
fonte
&
é de Haskell|>
. Enterrado profundamente neste tópico e levei alguns dias para descobrir. Eu uso muito, porque você naturalmente lê da esquerda para a direita para seguir o seu código.Respostas:
Estou sendo um pouco especulativo ...
Cultura : Eu acho que
|>
é um operador importante na "cultura" F #, e talvez da mesma forma.
para Haskell. F # tem um operador de composição de função,<<
mas acho que a comunidade F # tende a usar menos o estilo sem pontos do que a comunidade Haskell.Diferenças de idioma : Não sei o suficiente sobre os dois idiomas para comparar, mas talvez as regras para generalizar as ligações let sejam suficientemente diferentes para afetar isso. Por exemplo, eu sei em F # às vezes escrevendo
não irá compilar e você precisa de conversão eta explícita:
para fazê-lo compilar. Isso também afasta as pessoas do estilo de composição / sem pontos e em direção ao estilo de tubulação. Além disso, a inferência de tipo F # às vezes exige pipelining, para que um tipo conhecido apareça à esquerda (veja aqui ).
(Pessoalmente, acho o estilo sem pontos ilegível, mas suponho que cada coisa nova / diferente parece ilegível até que você se acostume a ela.)
Eu acho que ambos são potencialmente viáveis em qualquer idioma, e história / cultura / acidente podem definir porque cada comunidade se estabeleceu em um "atrator" diferente.
fonte
.
e$
, então as pessoas continuam a usá-los.Em F #
(|>)
é importante por causa da verificação de tipo da esquerda para a direita. Por exemplo:geralmente não verifica o tipo, porque mesmo se o tipo de
xs
for conhecido, o tipo do argumentox
para o lambda não é conhecido no momento em que o verificador de tipo o vê, então ele não sabe como resolverx.Value
.Em contraste
vai funcionar bem, porque o tipo de
xs
vai levar ao tipo dex
ser conhecido.A verificação de tipo da esquerda para a direita é necessária devido à resolução de nomes envolvida em construções como
x.Value
. Simon Peyton Jones escreveu uma proposta para adicionar um tipo semelhante de resolução de nome a Haskell, mas ele sugere o uso de restrições locais para rastrear se um tipo suporta uma operação específica ou não. Portanto, na primeira amostra, o requisito quex
precisa de umaValue
propriedade seria transportado atéxs
ser visto e esse requisito pudesse ser resolvido. Porém, isso complica o sistema de tipos.fonte
Mais especulação, desta vez do lado predominantemente de Haskell ...
($)
é a inversão de(|>)
, e seu uso é bastante comum quando você não pode escrever código sem pontos. Portanto, o principal motivo que(|>)
não é usado em Haskell é que seu lugar já está ocupado($)
.Além disso, falando com um pouco de experiência em F #, acho que
(|>)
é tão popular no código F # porque se assemelha àSubject.Verb(Object)
estrutura do OO. Uma vez que o F # visa uma integração funcional / OO suave,Subject |> Verb Object
é uma transição bastante suave para novos programadores funcionais.Pessoalmente, também gosto de pensar da esquerda para a direita, então uso
(|>)
em Haskell, mas não acho que muitas outras pessoas o façam.fonte
Data.Sequence.|>
, mas$>
parece razoável evitar conflitos aí. Honestamente, existem apenas alguns operadores bonitos, então eu usaria apenas|>
para ambos e gerenciaria os conflitos caso a caso. (Também eu estaria tentado a apenas apelidoData.Sequence.|>
comosnoc
)($)
e(|>)
são aplicação, não composição. Os dois estão relacionados (como as notas da pergunta), mas eles não são o mesmo (seufc
é(Control.Arrow.>>>)
para funções).|>
realmente me lembra do UNIX|
mais do que qualquer outra coisa.|>
F # é que ele tem boas propriedades para IntelliSense no Visual Studio. Digite|>
e você obterá uma lista de funções que podem ser aplicadas ao valor à esquerda, semelhante ao que acontece ao digitar.
depois de um objeto.Acho que estamos confundindo as coisas. Haskell's (
.
) é equivalente a F #'s (>>
). Não deve ser confundido com F #'s (|>
), que é apenas uma aplicação de função invertida e é como Haskell ($
) - invertido:Eu acredito que os programadores de Haskell usam
$
frequentemente. Talvez não com a frequência que os programadores de F # costumam usar|>
. Por outro lado, alguns caras do F # usam>>
até um grau ridículo: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspxfonte
$
operador de Haskell - invertido, você também pode defini-lo facilmente como: oa |> b = flip ($)
que se torna equivalente ao pipeline do F #, por exemplo, você pode fazer[1..10] |> map f
.
) o mesmo que (<<
), enquanto (>>
) é a composição reversa. Isso é( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
vs( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
seja equivalente a>>
. Não sei se F # tem,<<
mas isso seria o equivalente (como no Elm).Se você quiser usar o F #
|>
em Haskell, em Data.Function é o&
operador (desdebase 4.8.0.0
).fonte
&
lugar|>
? Eu sinto que|>
é muito mais intuitivo, e também me lembra do operador de pipe Unix.Composição da esquerda para a direita em Haskell
Algumas pessoas também usam o estilo da esquerda para a direita (passagem de mensagens) em Haskell. Veja, por exemplo, biblioteca mps no Hackage. Um exemplo:
Acho que este estilo fica bem em algumas situações, mas é mais difícil de ler (é preciso conhecer a biblioteca e todos os seus operadores, a redefinição
(.)
também atrapalha).Existem também operadores de composição da esquerda para a direita e da direita para a esquerda em Control.Category , parte do pacote básico. Compare
>>>
e<<<
respectivamente:Há uma boa razão para preferir a composição da esquerda para a direita às vezes: a ordem de avaliação segue a ordem de leitura.
fonte
Já vi
>>>
ser usado para issoflip (.)
, e frequentemente uso isso, especialmente para cadeias longas que são mais bem compreendidas da esquerda para a direita.>>>
é, na verdade, de Control.Arrow e funciona em mais do que apenas funções.fonte
>>>
é definido emControl.Category
.Além do estilo e da cultura, isso se resume a otimizar o design da linguagem para código puro ou impuro.
O
|>
operador é comum em F # principalmente porque ajuda a ocultar duas limitações que aparecem com o código predominantemente impuro:Observe que a primeira limitação não existe em OCaml porque a subtipagem é estrutural em vez de nominal, de modo que o tipo estrutural é facilmente refinado por meio da unificação conforme a inferência de tipo progride.
Haskell faz uma troca diferente, optando por focar no código predominantemente puro, onde essas limitações podem ser removidas.
fonte
Acho que o operador de pipe forward do F # (
|>
) deve vs ( & ) em haskell.Se você não gosta do
&
operador ( ), pode personalizá-lo como F # ou Elixir:Porque
infixl 1 |>
? Veja o documento em Data-Function (&)(.)
(
.
) significa composição da função. Significa (fg) (x) = f (g (x)) em matemática.é igual a
ou
O
$
operador ( ) também é definido em Data-Function ($) .(
.
) é usado para criarHight Order Function
ouclosure in js
. Consultar exemplo:Uau, menos (código) é melhor.
Compare
|>
e.
É a diferença entre
left —> right
eright —> left
. ⊙﹏⊙ |||Humanização
|>
e&
é melhor que.
Porque
Como fazer programação funcional em linguagem orientada a objetos?
visite http://reactivex.io/
Suporta:
fonte
Este é meu primeiro dia para experimentar Haskell (depois de Rust e F #), e pude definir o operador F # |>:
E parece que funciona:
Aposto que um especialista em Haskell pode lhe dar uma solução ainda melhor.
fonte
x |> f = f x