Haskell 如何立即计算出如此巨大的数字?

2024-03-10

我开始学习 Haskell,当我学习一门新语言时我喜欢做的事情之一就是欧拉计划 https://projecteuler.net/问题作为我主要参考资料的补充。

对于第二个问题,即查找小于 400 万的偶数斐波那契数之和,我提出了以下解决方案:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
f :: Integer -> Integer
f n =
  let evenFib = filter (\n -> n `mod` 2 == 0) fibs
  in sum (takeWhile (<n) evenFib)

这很好用;f 4000000返回正确答案。它立即就会这样做。出于好奇,我开始输入越来越大的数字......

Prelude> f 40000000
19544084
Prelude> f 400000000000
478361013020
Prelude> f 40000000000000000000000000000000
13049874051046942401006156573274
Prelude> f 2370498572349582734598273495872349587234958723948752394857
2805750129675962215536656398462489370528480907433875715844

这些值中的每一个都会立即返回。我无法保证最后两个答案的准确性,因为我在其他语言中的实现不适用于这么大的数字。

所以,我的问题是,Haskell 在这里做什么?它如何立即返回这些值(无论它们实际上是否正确)?此外,这些答案确实正确吗,还是 Haskell 只是编造的东西?


这可能与 Haskell 特别无关,而是与您用于其他解决方案的算法有关。

由于斐波那契数增长得相当快(平均每一步增长 1.6 倍),所以没有那么多斐波那契数小于 40000000000000000000000000000000,可能少于 100。

计算机添加少于 100 个这样大小的数字(不是特别大)应该需要几微秒。

我不确定你的其他实现是什么样的,但一个常见的错误是像这样编写斐波那契函数:

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

这太可怕了,因为fib n calls fib (n-1),然后调用fib (n-2),并将答案返回fib n。但接下来你必须去计算一下fib (n-2)再次因为您尚未保存答案。

更好地实施fib在 Haskell(或者任何其他语言)中,如下所示:

fib 0 = 0
fib n = fib' 0 1 n

fib' _ curr 1 = curr
fib' last curr n = fib' curr (last+curr) (n-1)

请注意,每个fib'调用仅使一次递归全部,而不是两次。我上面写的大概是这样的0 : 1 : zipWith (+) fibs (tail fibs)正在做,但是上面的代码有点混乱,但可能也更容易翻译成其他语言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 如何立即计算出如此巨大的数字? 的相关文章

  • 通过 Emacs 评估 ghci 或 Hugs 中的缓冲区

    在 Emacs 中使用 sml mode 我已经能够使用以下命令将缓冲区内容直接发送到较差的 SML 进程C c C b 现在我只想用 Haskell 做同样的事情 Haskell 模式似乎不支持这一点 所以我想知道 使用 Emacs 和
  • 类 GADT 类型变量的未来角色?

    A 昨天的问题 https stackoverflow com q 41135212 3072788有一个定义HList 来自HList https hackage haskell org package HList 0 4 1 0 doc
  • Haskell Cabal 包 - 找不到 Paths_ 模块

    我正在开发一个 Haskell 项目 Happstack 服务器 Blaze HTML 前端作为主要库 我想添加一个静态数据目录 看起来你可以使用 Cabal 使用自动生成的Path
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • 如何手动推断表达式的类型

    给定 Haskell 函数 head filter fst 现在的问题是如何手动 手动 找到类型 如果我让 Haskell 告诉我我得到的类型 head filter fst Bool b gt Bool b 但我想了解仅使用所用函数的签名
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • 纯函数怎么能做IO呢?

    我最近了解到莫纳德随机数 http hackage haskell org package MonadRandom 0 1 13 docs Control Monad Random Class html t 3aMonadRandom图书馆
  • 将 num 的签名键入 double?

    我才刚刚开始为你学习 Haskell 以获得伟大的好处 并且我在类型类方面遇到了一些麻烦 我想创建一个接受任何数字类型并强制其为双精度的函数 我的第一个想法是定义 numToDouble Num gt Double 但我认为这不起作用 因为
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • 以下两个 lambda 函数的空间复杂度

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon
  • 在 Yesod 生态系统中,对某些文本进行 urlencode 的最佳方式是什么?

    我想对一些文本进行 url 编码 例如 用 20 替换每个空格等 我找到了 HTTP Network HTTP Base urlEncode 并且可以使用它 但我想知道是否还有其他通常在 Yesod 生态系统中使用的东西 不幸的是 由于 U
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • 你能识别 Haskell 程序中的无限列表吗? [复制]

    这个问题在这里已经有答案了 可能的重复 如何判断列表是否是无限的 https stackoverflow com questions 7371730 how to tell if a list is infinite 在Haskell中 你
  • 找不到模块“Yesod”

    我有以下代码 LANGUAGE TypeFamilies QuasiQuotes MultiParamTypeClasses TemplateHaskell OverloadedStrings module Simple where imp
  • 管道:多个流消费者

    我编写了一个程序来计算语料库中 NGram 的频率 我已经有一个函数 它消耗一串令牌并生成一个订单的 NGram ngram Monad m gt Int gt Conduit t m t trigrams ngram 3 countFre
  • Haskell Data.Decimal 作为 Aeson 类型

    是否可以解析一个数据 十进制 https hackage haskell org package Decimal 0 4 2 docs Data Decimal html使用 Aeson 包从 JSON 获取 假设我有以下 JSON foo
  • 如何在Haskell中实现词法分析器和解析器

    我在这里得到了这段代码 它是用Haskell结构的命令式编程语言编写的程序 所以问题是 我如何为这种语言实现词法分析器和解析器 该程序被定义为一系列语句有 6 种类型 goto write stop if goto 和 int int n
  • 如何打乱列表?

    如何从一组数字 1 2 3 直到我击中x 我的计划是重新调整列表 1 2 3 并把它砍在x chopAt 3 2 3 1 2 3 chopAt 3 2 1 3 2 1 3 chopAt 3 3 1 2 3 chopAt chopAt x y

随机推荐