Wiele współczesnych języków programowania pozwala nam obsługiwać potencjalnie nieskończone listy i wykonywać na nich określone operacje.Gra z nieskończonością - Leniwa arytmetyka
Przykład [Python]
EvenSquareNumbers = (x * x for x in naturals() if x mod 2 == 0)
Te listy mogą istnieć ze względu jedynie elementy, które są rzeczywiście wymagane są obliczane. (Leniwa ocena)
Po prostu zastanawiałem się, czy nie jest interesujące, czy możliwe jest (lub nawet praktykowane w niektórych językach) rozszerzenie mechanizmu leniwego oceniania na arytmetykę.
Przykład: względu na nieskończoną listę liczb parzystych evens = [ x | x <- [1..], even x ]
Nie mogliśmy obliczyć
length evens
od obliczania wymaganej tutaj nigdy nie zakończyć.
Ale moglibyśmy stwierdzić, że
length evens > 42
bez konieczności oceniać cały length
termin.
Czy jest to możliwe w dowolnym języku? A co z Haskellem?
Edytuj: Aby uczynić punkt jaśniejszym: Pytanie nie dotyczy tego, jak ustalić, czy lista leniwych jest krótsza niż podana liczba. Chodzi o używanie konwencjonalnych funkcji wbudowanych w taki sposób, że obliczenia numeryczne odbywają się leniwie.
sdcvvc pokazał rozwiązanie Haskell:
data Nat = Zero | Succ Nat deriving (Show, Eq, Ord)
toLazy :: Integer -> Nat
toLazy 0 = Zero
toLazy n = Succ (toLazy (n-1))
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
len [] = Zero
len (_:x') = Succ $ len x'
-- Test
len [1..] < 42
Czy to możliwe również w innych językach?
'Perl6' ma leniwy list http://perlcabal.org/syn/S09.html#Lazy_lists –