Quais são algumas técnicas que eu poderia usar para refatorar consistentemente o código, removendo a dependência de tipos existenciais? Normalmente, eles são usados para desqualificar construções indesejadas do seu tipo, bem como para permitir o consumo com um mínimo de conhecimento sobre o tipo especificado (ou seja, é o meu entendimento).
Alguém criou uma maneira simples e consistente de remover a dependência deles no código que ainda mantém alguns dos benefícios? Ou pelo menos alguma maneira de escorregar em uma abstração que permita sua remoção sem exigir uma rotatividade significativa de código para lidar com a alteração?
Você pode ler mais sobre tipos existenciais aqui ("se você ousar ..").
functional-programming
haskell
type-systems
Petr Pudlák
fonte
fonte
Respostas:
Tipos existentes não são realmente considerados uma prática ruim em programação funcional. Eu acho que o que está enganando você é que um dos usos mais citados para os existenciais é o antipadrão de classe tipográfica existencial , que muitas pessoas acreditam ser uma má prática.
Esse padrão é frequentemente traçado como uma resposta à questão de como ter uma lista de elementos de tipo heterogêneo que implementam a mesma classe de tipo. Por exemplo, você pode querer ter uma lista de valores que possuem
Show
instâncias:O problema com código como este é este:
AnyShape
é obter sua área.AnyShape
construtor para trazer um dos tipos de forma para oAnyShape
tipo.Então, como se vê, esse trecho de código realmente não oferece nada que este menor não:
No caso de classes com vários métodos, o mesmo efeito pode geralmente ser realizado mais simplesmente usando uma codificação "registro de métodos" - em vez de usar uma classe de tipo
Shape
, você define um tipo de registro cujos campos são os "métodos" doShape
tipo , e você escreve funções para converter seus círculos e quadrados emShape
s.Mas isso não significa que tipos existenciais sejam um problema! Por exemplo, no Rust, eles têm um recurso chamado objetos de característica que as pessoas geralmente descrevem como um tipo existencial sobre uma característica (versões de classes de tipos de Rust). Se as classes de tipo existenciais são um antipadrão em Haskell, isso significa que Rust escolheu uma solução ruim? Não! A motivação no mundo Haskell é sobre sintaxe e conveniência, não realmente sobre princípios.
Uma maneira mais matemática de colocar isso é apontar que o
AnyShape
tipo de cima eDouble
é isomórfico - há uma "conversão sem perdas" entre eles (bem, exceto pela precisão do ponto flutuante):Então, estritamente falando, você não está ganhando ou perdendo poder ao escolher um contra o outro. O que significa que a escolha deve se basear em outros fatores, como facilidade de uso ou desempenho.
E lembre-se de que tipos existenciais têm outros usos fora deste exemplo de lista heterogênea; portanto, é bom tê-los. Por exemplo, o
ST
tipo de Haskell , que nos permite escrever funções que são externamente puras, mas usam internamente operações de mutação de memória, usa uma técnica baseada em tipos existenciais para garantir a segurança no momento da compilação.Portanto, a resposta geral é que não há resposta geral. Os usos de tipos existenciais só podem ser julgados em contexto - e as respostas podem ser diferentes dependendo de quais recursos e sintaxe são fornecidos por diferentes idiomas.
fonte
Eu não estou muito familiarizado com Haskell, então tentarei responder à parte geral da pergunta como um desenvolvedor de C # funcional não acadêmico.
Depois de fazer algumas leituras, verifica-se que:
Os curingas Java são semelhantes aos tipos existenciais:
Diferença entre os tipos existenciais do Scala e o curinga do Java por exemplo
Os curingas não são implementados no C # completamente: a variação genérica é suportada, mas a variação do site de chamada não é:
C # Generics: Curingas
Você pode não precisar desse recurso todos os dias, mas quando sentir isso (por exemplo, ter que introduzir um tipo extra para fazer as coisas funcionarem):
Curingas em restrições genéricas de C #
Com base nessas informações, os tipos / curingas existenciais são úteis quando implementados adequadamente e não há nada errado com eles, mas provavelmente podem ser mal utilizados, como outros recursos de idioma.
fonte