Estoy tratando de encontrar una buena manera de memorizar una función para solo una parte de su dominio (enteros no negativos) en Haskell, usando Data.MemoCombinators
.Memorización parcial en 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)
Enfoque 1 es cómo me gustaría hacerlo, sin embargo, parece que no funciona. Supongo que esto se debe a que la función fib
se "recrea" cada vez que se invoca partFib
, descartando la memorización. fib
no depende de la entrada de partFib
, por lo que podría suponer que el compilador podría izarlo, pero aparentemente GHC no funciona de esa manera.
Enfoque 2 es cómo termino haciéndolo. Eerk, muchos cables feos.
¿Alguien sabe de una mejor manera de hacer esto?
Gracias, esto es mejor que lo que tenía. Nada es realmente tan "feo". Solo quiero que la definición se vea lo más similar posible a la implementación ingenua de Fibonacci. – dainichi
¿Por qué esto hace la diferencia? ¿No es 'f n = e' semánticamente exactamente lo mismo que' f = \ n -> e'? –
@Dan, semánticamente, sí. Pero la memorización entra al territorio operacional. La 'n' en el primero tiene un alcance sobre la cláusula' where', mientras que 'n' en el último no lo está, cambiando así la forma en que se comparten los thunks en la cláusula where. – luqui