有条件的记忆功能?

Memoizing function with condition?

正在尝试为否定参数扩展记忆斐波那契函数。 波纹管是一个明显只适用于正值的代码:

fib :: Integer -> Integer
fib = (map fib' [0..] !!) . fromInteger
    where
    fib' 0        = 0
    fib' 1        = 1
    fib' n        = (fib $ n-2) + (fib $ n-1)
    negfib' 0     = 1
    negfib' 1     = -1
    negfib' n     = (fib $ n+2) - (fib $ n+1)

如何更改 fib 定义,以便在使用负数调用时它也可以使用 negfib' 缓存结果?

尝试使用模式守卫

fib n
    | n>= 0     = (map fib' [0..] !!) . fromInteger $ n
    | otherwise = (map negfib' [0..] !!) . fromInteger $ -n - 1

或包含在 lambda 函数中

fib = (\n -> if n >= 0
                 then map fib' [0..] !!) . fromInteger $ n
                 else map negfib' [0..] !!) . fromInteger $ -n - 1

这没有帮助,因为部分应用的斐波那契函数列表不是以这种方式预先生成的。

你非常接近!

进一步拉出地图语句:

fib = lookup
  where fibs = map fib' [0..]
        negfibs = map negfib' [0..]
        lookup n | n >= 0    = (fibs !!) . fromInteger $ n
                 | otherwise = (negfibs !!) . fromInteger $ -n - 1

现在 fibsnegfibs 的定义只发生一次(使用 fib 的定义)而不是每个 n.