Итак, я читал, как вы можете преобразовать ADT в то, что напоминает вещественные числа, и манипулировать ими на таких страницах, как этот вопрос SO и эта серия из трех частей и особенно это .
Мое внимание привлек раздел "Проблемы" последней ссылки, и я попытался решить Nat
в нем, хотя в статье говорится, что это невозможно.
Nat = 1 + Nat
Nat - Nat = 1
Nat(1 - 1) = 1
Nat = 1 / (1 - 1)
Это может показаться полной ерундой, поскольку я просто разделил на 0 (и, возможно, вы правы), но если вы прочитаете любую из этих ссылок или что-то подобное, вы заметите, что это очень похоже на определение списка.
List(x) = 1 / (1 - x)
Таким образом, вы можете написать Nat как Nat = List(1) = 1 + 1 + 1 + ...
, и это именно то, что вы получили бы, повторяя подстановку в исходном уравнении. Это также эквивалентно определению таких натуральных чисел в Haskell:
type Nat = [()]
Это определенно допустимая кодировка натуральных чисел, где 0 = []
и S(N) = () : N
.
Итак, мой вопрос в том, как же я получил из этого достоверный результат? Я просто разделил на ноль. Не говоря уже о самом исходном уравнении, в значительной степени противоречащем друг другу.
Так почему же я получил что-то, что имеет смысл в конце этого? Это просто чистое совпадение или деление на 0 каким-то образом определено в этом контексте, что имеет смысл?
1 != 1*1
, поэтому правильнее было бы написатьNat = 1 + 1*1 + 1*1*1 + ...
. - person chepner   schedule 28.09.20161
- это идентичность*
. Другими словамиx * 1 = 1
для любого x. Итак,1
и1*1
эквивалентны. - person The Red Fox   schedule 28.09.2016((), ())
отличается от()
.x * 1 == x
, потому что вы можете без потерь преобразовать значение(a, ()) :: (x,())
вa :: x
и наоборот. - person chepner   schedule 28.09.2016=
, поскольку он изоморфен, если хотите. - person Reid Barton   schedule 28.09.2016