Para fins de aprendizagem, estou definindo gcd'
função em termos de subtração repetida:
gcd' :: Integer -> Integer -> Integer
gcd' x y
| x == y = x
| x < y = gcd' x (y - x)
| y < x = gcd' (x - y) y
(Função gcd do Prelude )
O problema é que o GHC reclama disso:
As correspondências de padrões não são exaustivas. Em uma equação para 'mdc'':
Padrões do tipo 'Inteiro', 'Inteiro' não correspondidos: _ _
Eu vi uma lei matemática relativa aos números que dizia:
Para todos os números 𝑥 e 𝑦, é verdade que 𝑥 é menor que 𝑦, ou 𝑦 é menor que 𝑥, ou 𝑥 é igual a 𝑦.
Nesse sentido, esses três guardas cobrem todos os cenários possíveis. Porque é que o GHC está preocupado com esta definição?
Como explicou Willem, isso ocorre porque o GHC não sabe que
<
/>
/==
são uma coleção exaustiva de possibilidades. Na verdade, ele nunca sabe disso para qualquer verificação com valor booleano.Haskell, entretanto, tem uma alternativa onde o GHC é capaz de deduzir a exaustividade: correspondência de padrões em tipos de soma. E isso também pode ser usado para tomar decisões com base em pedidos. Seu algoritmo ficaria assim:
Eu diria que isso é realmente melhor que a versão com
otherwise
.O problema é que Haskell não é tão inteligente para saber isso para dois itens
x
ey
, ele sempre vale issox < y
,x > y
oux == y
, e na verdade nem vale. Na verdade, para aNaN
, não é válido:É melhor trabalhar com uma condição que seja sempre verdadeira:
otherwise
, que é um alias paraTrue
:Observe que uma implementação mais rápida
gcd'
é: