Uma solução genérica é introduzir um novo tipo. Pode estar mais envolvido, mas tem a vantagem de trabalhar para qualquer tipo que não defina seu próprio infinito.
Se T
é um tipo para o qual lteq
está definido, você pode definir InfiniteOr<T>
com lteq
algo como isto:
class InfiniteOr with type parameter T:
field the_T of type null-or-an-actual-T
isInfinite()
return this.the_T == null
getFinite():
assert(!isInfinite());
return this.the_T
lteq(that)
if that.isInfinite()
return true
if this.isInfinite()
return false
return this.getFinite().lteq(that.getFinite())
Deixo para você traduzir isso para a sintaxe exata do Java. Espero que as idéias sejam claras; mas deixe-me explicá-los de qualquer maneira.
A idéia é criar um novo tipo que tenha todos os mesmos valores de algum tipo já existente, mais um valor especial que, tanto quanto você pode dizer através de métodos públicos, age exatamente da maneira que você deseja que o infinito aja, por exemplo, é maior que algo mais. estou a usarnull
para representar o infinito aqui, pois isso parece o mais direto em Java.
Se você deseja adicionar operações aritméticas, decida o que elas devem fazer e implemente-as. Provavelmente é mais simples se você manipular os casos infinitos primeiro e depois reutilizar as operações existentes com valores finitos do tipo original.
Pode ou não haver um padrão geral para se é benéfico ou não adotar uma convenção de lidar com infinitos do lado esquerdo antes dos infinitos do lado direito ou vice-versa; Não sei dizer sem experimentar, mas para menos que ou igual ( lteq
), acho mais simples olhar primeiro para o infinito do lado direito. Noto que nãolteq
é comutativo, mas eadd
mul
é; talvez isso seja relevante.
Nota: apresentar uma boa definição do que deve acontecer com valores infinitos nem sempre é fácil. É para comparação, adição e multiplicação, mas talvez não subtração. Além disso, há uma distinção entre números cardinais e ordinais infinitos aos quais você pode prestar atenção.