Вы можете создавать свои собственные натуральные числа ...
data Nat = Zero | Succ Nat deriving (Show, Eq, Ord)
len :: [a] -> Nat
len = foldr (const Succ) Zero
toLazy :: Int -> Nat
toLazy 0 = Zero
toLazy n = Succ (toLazy (n-1))
a = len [1..] > toLazy 42
Тогда a True, благодаря ленивой оценке. Очень важно, что len использует foldr, foldl не работает с бесконечными списками. И вы можете сделать некоторую арифметику тоже (не проверено):
instance Num Nat where
(+) (Succ x) y = Succ (x + y)
(+) Zero y = y
(*) Zero y = Zero
(*) x Zero = Zero
(*) (Succ x) y = y + (x * y)
fromInteger = toLazy
abs = id
negate = error "Natural only"
signum Zero = Zero
signum (Succ x) = Succ Zero
Например, 2 * бесконечность + 3 - это бесконечность:
let infinity = Succ infinity
*Main> 2 * infinity + 3
(Succ (Succ (Succ ^cCc (Succ (Succ (SuccInterrupted.
Второй раствор
Другое решение - использовать списки () в качестве ленивых натуральных чисел.
len = map (const ())
toLazy n = replicate n ()
a = len [1..] > toLazy 42
Проверка Взлом .
Редактировать: Добавлен экземпляр Num.
Edit2:
Перевод второго решения на Python:
import itertools
def length(x):
return itertools.imap(lambda: (), x)
def to_lazy(n):
return itertools.chain([()] * n)
Чтобы добавить числа, используйте itertools.chain, чтобы умножить, используйте itertools.product. Это не так красиво, как в Haskell, но работает.
На любом другом строгом языке с замыканиями вы можете имитировать лень, используя type () -> a вместо a. Используя это, можно перевести первое решение с Haskell на другие языки. Однако это быстро станет нечитаемым.
См. Также хорошая статья об однострочниках Python .