首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell:回忆录

Haskell:回忆录
EN

Stack Overflow用户
提问于 2016-01-06 23:23:44
回答 1查看 240关注 0票数 1

我正试图重新学习Haskell,在许多年后,忘记了一切,我发现自己仍然困惑我的回忆录。特别是,我正在编写一个程序来生成D[n] of n对象(没有项目的排列);数字D[n]可以由D[1]=0D[2]=1D[n]=(n-1)(D[n-1]+D[n-2])递归定义。

因此,这是可行的:

代码语言:javascript
复制
der :: Int -> Integer
der n = lder !! n
  where lder = 1 : 0 : zipWith3 (\n d1 d2 -> n * (d1+d2)) [1..] lder (tail lder)

这一点也是如此(这有点笨拙,因为它需要三个功能):

代码语言:javascript
复制
nder :: Int -> Integer
nder n = nderTab !! n

nderTab :: [Integer]
nderTab = [nderCalc n | n <- [0..]]

nderCalc :: Int -> Integer
nderCalc n
  | n == 0    = toInteger 1
  | n == 1    = toInteger 0
  | otherwise = toInteger (n-1) * (nder (n-1) + nder (n-2))

但这并不是:

代码语言:javascript
复制
nders :: Int -> Integer
nders n = (map der [0 ..]) !! n
  where der 0 = 1
        der 1 = 0
        der n = (nders (n-2) + nders (n-1)) * toInteger (n-1)

最后,您会发现这是标准回忆录Fibonacci数函数的副本。我的函数工作,但没有回忆录,因为它挂在大于30的值上。此外,如果我编写此函数仅对大于或等于1的值进行操作:

代码语言:javascript
复制
nders :: Int -> Integer
nders n = (map der [1 ..]) !! n
  where der 1 = 0
        der 2 = 1
        der n = (nders (n-2) + nders (n-1)) * toInteger (n-1)

它坏了。我很想知道最后两个函数有什么问题。

EN

回答 1

Stack Overflow用户

发布于 2016-01-07 04:32:56

使用

代码语言:javascript
复制
nders :: Int -> Integer
nders n = (map der [0 ..]) !! n
  where der 0 = 1
        der 1 = 0
        der n = (nders (n-2) + nders (n-1)) * toInteger (n-1)

map der [0..]部分将为nders的任何应用程序重新计算,特别是包括der中的递归调用。

您可以移出表的定义,这样它就不会(在语法上)依赖于n,而n应该做正确的事情:

代码语言:javascript
复制
nders :: Int -> Integer
nders = (memoized !!)
  where 
    memoized = map der [0 ..]

    der 0 = 1
    der 1 = 0
    der n = (nders (n-2) + nders (n-1)) * toInteger (n-1)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34644761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档