Polimorfismo, classes e inferência de tipos

Deduzir tipos gerais pelas aplicações, padrões e operações usadas, sem confundir classes com tipos.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

Polimorfismo e restrições

  • Uma variável de tipo representa qualquer tipo compatível. trocar (x,y) = (y,x) tem tipo (a,b) -> (b,a); duplicar x = (x,x) tem tipo a -> (a,a).
  • Uma lista exige elementos do mesmo tipo; um par pode combinar tipos. A assinatura [a] -> a não garante que a função trate []: generalidade não é cobertura de casos.
  • Uma classe declara operações disponíveis num tipo. A restrição Eq a => permite comparar valores de tipo a; não cria uma classe de objetos.
OperaçãoRestrição
==, /=, elemEq
<, >=, compareOrd, que exige Eq
show, readShow, Read; read pode falhar com texto inválido.
+, -, *, literais inteirosNum
div, mod, quot, remIntegral
/, literais fracionáriosFractional
sqrt, sin, expFloating

Nos GHC atuais, Num não exige Eq. Somar e eliminar repetidos pode exigir (Num a, Eq a); retira restrições redundantes quando uma classe já implica a outra.

Inferir o tipo mais geral

  1. Dá variáveis de tipo aos argumentos.
  2. Iguala os tipos impostos por padrões, listas e aplicações.
  3. Acrescenta as classes pedidas pelas operações e retira as redundantes.

Em duas f x = f (f x), com x :: a, o resultado de f x volta a entrar em f. Logo f :: a -> a e duas :: (a -> a) -> a -> a, sem restrições: nenhuma operação específica é usada.

contem :: Eq a => a -> [a] -> Bool
contem x xs = x `elem` xs

media :: Fractional a => a -> a -> a
media x y = (x+y)/2

Ordenar três valores por comparações e escolher o central exige apenas Ord a. A fórmula x+y+z-minimum [x,y,z]-maximum [x,y,z] exige também Num a e pode perder precisão em vírgula flutuante: o tipo regista as operações, não a equivalência matemática.

Setas, aplicação e conversões

  • a -> b -> c significa a -> (b -> c): recebe a e devolve uma função. A aplicação associa ao contrário: f x y é (f x) y. Os parênteses em (a -> b) -> a -> b marcam uma função como argumento.
  • (.) :: (b -> c) -> (a -> b) -> a -> c. A saída da função da direita tem de entrar na função da esquerda.
  • length xs :: Int não divide com /. Usa fromIntegral (length xs); a conversão nunca é automática.
  • Com divisor não nulo, div/mod arredondam para baixo e quot/rem truncam para zero. Para -7 e 3 dão (-3,2) e (-2,-1). Não mistures o quociente de um par com o resto do outro.

Dedução por restrições.

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

Navegação

Cursor de leitura, sem edição. h, j, k, l movem; / pesquisa nesta página. v seleciona caracteres; V seleciona linhas; y copia. Tab permite destacar ou comentar. Espaço ou Enter abre blocos recolhíveis. Nos cartões, h, j, k, l mudam o foco.

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Copiar fórmula

A cópia automática não está disponível. Copia o LaTeX abaixo.

Pesquisar nesta página

Enter procura · n / N repetem · Esc cancela. Ctrl / Cmd K pesquisa todo o site.

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.