Performance 如何在Haskell中记忆LCS

Performance 如何在Haskell中记忆LCS,performance,function,haskell,memoization,lcs,Performance,Function,Haskell,Memoization,Lcs,作为修改算法知识的一部分,我决定用Java实现最长的公共子序列问题,然后用我最喜欢的新语言Haskell实现 lcs :: (Eq a) => [a] -> [a] -> [a] lcs [] _ = [] lcs _ [] = [] lcs (x:xs) (y:ys) = if (x == y) then x : lcs xs ys else longer (lcs xs (y:ys), lcs (x:xs) ys) where longer (

作为修改算法知识的一部分,我决定用Java实现最长的公共子序列问题,然后用我最喜欢的新语言Haskell实现

lcs :: (Eq a) => [a] -> [a] -> [a]

lcs [] _ = []
lcs _ [] = []

lcs (x:xs) (y:ys) = 
    if (x == y) then x : lcs xs ys
    else longer (lcs xs (y:ys), lcs (x:xs) ys)
    where longer (a, b) = if (length a > length b) then a else b
我发现Haskell令人满意的一点是,与命令式语言相比,编写算法不仅可以让您更好地理解算法,还可以编写更简洁的代码。然而,这段代码严重依赖于利用递归调用,递归调用形成了一个实质性的调用二叉树。这使它成为记忆的完美候选

问题是我真的不知道如何做到这一点。对我来说,与我的命令式思维产生共鸣的自然选择是创建一个辅助函数,第三个参数作为缓存,它是从([Char],[Char])到[Char]的映射,并在函数的每次递归调用上进行检查(
成员
?)。并根据结果从映射返回值或插入要计算的内容


再说一遍,这似乎是一种编写Haskell代码的不纯方式,因为这基本上意味着模拟状态和副作用。更糟糕的是,这会将以前优雅的解决方案与地图上的操作结合起来。那么正确的处理方法是什么呢

这回答了你的问题吗?这回答了你的问题吗?