Próbuję znaleźć dobry sposób na zapamiętanie funkcji tylko dla części jej domeny (nieujemnych liczb całkowitych) w Haskell, używając Data.MemoCombinators
.Częściowa notacja w Haskell
import Data.MemoCombinators
--approach 1
partFib n | n < 0 = undefined
| otherwise = integral fib n where
fib 0 = 1
fib 1 = 1
fib k = partFib (k-1) + partFib (k-2)
--approach 2
partFib2 n | n < 0 = undefined
| otherwise = fib n
fib = integral fib'
where
fib' 0 = 1
fib' 1 = 1
fib' n = partFib2 (n-1) + partFib2 (n-2)
Podejście 1 to sposób, w jaki chciałbym to zrobić, ale wydaje się, że nie działa. Zakładam, że dzieje się tak dlatego, że funkcja fib
jest "odtwarzana" za każdym razem, gdy wywoływana jest nazwa partFib
, odrzucając tę funkcję. fib
nie zależy od wejścia partFib
, więc można założyć, że kompilator może go podnieść, ale najwyraźniej GHC nie działa w ten sposób.
Podejście 2 to sposób, w jaki to robię. Eerk, dużo brzydkiego okablowania.
Czy ktoś wie o lepszy sposób to zrobić?
Dzięki, to jest lepsze niż to, co miałem. Nic tak naprawdę nie jest "brzydkie". Po prostu chcę, aby definicja wyglądała tak, jak to jest możliwe w przypadku naiwnej implementacji Fibonacciego. – dainichi
Dlaczego to robi różnicę? Czy 'f n = e' nie jest semantycznie identyczne jak' f = \ n -> e'? –
@Dan, semantycznie, tak. Ale memoizacja wchodzi na terytorium operacyjne. "N" w pierwszym jest ograniczone do "zdania" gdzie 'n' w drugim nie jest, zmieniając w ten sposób sposób dzielenia zdań w klauzuli where. – luqui