玩转无穷大——懒惰算术

2023-12-30

许多现代编程语言允许我们处理潜在的无限列表并对它们执行某些操作。

示例[Python]:

EvenSquareNumbers = ( x * x for x in naturals() if x mod 2 == 0 )

这样的列表可以存在,因为只计算实际需要的元素。 (懒惰评价)

我只是出于兴趣想知道是否有可能(甚至在某些语言中实践过)将惰性求值机制扩展到算术。

例子: 给定偶数的无限列表evens = [ x | x <- [1..], even x ]我们无法计算

length evens

因为这里所需的计算永远不会终止。

但我们实际上可以确定

length evens > 42

无需评估整体length term.

这在任何语言中都可能吗?哈斯克尔呢?

编辑:为了使这一点更清楚:问题不在于如何确定惰性列表是否短于给定数字。它是关于以延迟完成数值计算的方式使用传统的内置函数。

sdcvvc 展示了 Haskell 的解决方案:

data Nat = Zero | Succ Nat deriving (Show, Eq, Ord)

toLazy :: Integer -> Nat
toLazy 0 = Zero
toLazy n = Succ (toLazy (n-1))

instance Num Nat where
   (+) (Succ x) y = Succ (x + y)
   (+) Zero y = y
   (*) Zero y = Zero
   (*) x Zero = Zero
   (*) (Succ x) y = y + (x * y)
   fromInteger = toLazy
   abs = id
   negate = error "Natural only"
   signum Zero = Zero
   signum (Succ x) = Succ Zero

len [] = Zero
len (_:x') = Succ $ len x'

-- Test 

len [1..] < 42 

这在其他语言中也可能吗?


您可以创建自己的自然数...

data Nat = Zero | Succ Nat deriving (Show, Eq, Ord)

len :: [a] -> Nat
len = foldr (const Succ) Zero

toLazy :: Int -> Nat
toLazy 0 = Zero
toLazy n = Succ (toLazy (n-1))

a = len [1..] > toLazy 42

那么 a 是 True,这要归功于惰性求值。 len 使用foldr 至关重要,foldl 不适用于无限列表。你也可以做一些算术(未经测试):

instance Num Nat where
   (+) (Succ x) y = Succ (x + y)
   (+) Zero y = y
   (*) Zero y = Zero
   (*) x Zero = Zero
   (*) (Succ x) y = y + (x * y)
   fromInteger = toLazy
   abs = id
   negate = error "Natural only"
   signum Zero = Zero
   signum (Succ x) = Succ Zero

例如,2 * 无穷大 + 3 是无穷大:

let infinity = Succ infinity

*Main> 2 * infinity + 3
(Succ (Succ (Succ ^cCc (Succ (Succ (SuccInterrupted.

第二种解决方案

另一种解决方案是使用 () 列表作为惰性自然数。

len = map (const ())
toLazy n = replicate n () 
a = len [1..] > toLazy 42

Check Hackage http://hackage.haskell.org/package/peano-inf.

编辑:添加实例编号。

Edit2:

将第二个解决方案翻译成Python:

import itertools

def length(x):
    return itertools.imap(lambda: (), x) 

def to_lazy(n):
    return itertools.chain([()] * n)

要添加数字,请使用 itertools.chain,要乘法,请使用 itertools.product。这不像 Haskell 中那么漂亮,但它确实有效。

在任何其他带有闭包的严格语言中,您可以使用类型 () -> a 而不是 a 来模拟惰性。使用它可以将第一个解决方案从 Haskell 翻译成其他语言。然而,这很快就会变得不可读。

也可以看看一篇关于 Python 俏皮话的好文章 http://blog.sigfpe.com/2008/09/on-writing-python-one-liners.html.

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

玩转无穷大——懒惰算术 的相关文章

随机推荐

  • 在 web2py 的本地安装中安装 Python 模块

    我在 Windows 机器上运行 web2py 我正在开发一个应用程序 但它不断出错 因为它说我尝试使用的模块未安装 然而它安装在我的本地 python 安装中 如何安装模块以便 web2py 可以识别它们 web2py 可以识别本地 Py
  • 如何在 Android 中的可跨越字符串之间留出空间?

    Code private void setSpans Editable s ColorInt int backgroundColor BackgroundColorSpan spans s getSpans 0 s length Backg
  • Java 中数据类型的默认值是什么? [复制]

    这个问题在这里已经有答案了 我对 Java 很陌生 总是对数据类型有疑问 那么有哪些defaultJava 中所有数据类型的值 byte 0 short 0 int 0 long 0 float 0 0f double 0 0d char
  • 单击 ListView 项目会更改项目内元素的状态吗?

    我不知道如何解释这个问题 但我会尝试 我有一个包含多个项目的 ListView 每个项目内部都有一个 TextView 和两个 ImageView 我希望当我单击它们时 ImageView 会发生变化 并且当我长时间按下 ListView
  • 如何清除 Android 中的旧徽章计数

    我设置 0 表示其显示徽章计数为 1 如何清除我的旧徽章计数 徽章计数设置方法 public static void setBadge Context mContext int count String launcherClassName
  • 使用 Visual Studio 2010 将 VB6 迁移到 .Net

    有人使用 Visual Studio 2010 将 VB6 项目迁移到 Net 吗 我已经在 VS2005 中测试了迁移 但是生成的 Net 代码非常混乱 因此我们决定不迁移到 Net 那么VS2010的迁移向导比VS2005或VS2008
  • REST API 上的 CakePHP 身份验证

    因此 我正在为我正在开发的 Web 应用程序创建一个 REST API 并且我知道身份验证的基本方法是在每个请求上发送凭据或发送令牌 由于我以前从未使用过令牌 因此我想我可以为每个请求发送凭据 关键是我找不到任何有关如何在控制器中处理此问题
  • 使用 pandas.SparseSeries.from_coo() 函数的非 NDFFrame 对象错误

    我正在尝试将 COO 类型稀疏矩阵 来自 Scipy Sparse 转换为 Pandas 稀疏序列 从文档 http pandas pydata org pandas docs stable sparse html http pandas
  • 在 Keras 中设置 LearningRateScheduler

    我正在 Keras 中设置学习率调度程序 使用历史损失作为 self model optimizer lr 的更新程序 但 self model optimizer lr 上的值不会插入到 SGD 优化器中 并且优化器为使用默认学习率 代码
  • 如何禁用 vscode 中的误报错误?

    我写了这个基本的 C 程序 int main int argc char const argv int n rand int a n return a 0 哪个在 gcc 中正确编译 但是 MS C C 智能感知在显示错误曲线时指出expr
  • 用多行突出显示 ggplot 中的一行

    我想改变size linetype colorggplot 中的一行等 这是一个最小的可重现示例 library tidyverse Data in wide format df wide lt data frame Horizons se
  • 从 UIButton 中获取 UILabel

    我有一个 UIButton 其中 UILabel 作为子视图添加到其中 有没有一种简单的方法可以将 UILabel 从中取出 以便我可以更改它的标题 如果您指定一个tag当您仍然有对它的引用时 您可以稍后通过搜索视图来找到它tag 像这样
  • 如何正确使用 ES6“导出默认值”和 CommonJS“要求”?

    我一直在努力Webpack教程 http blog madewithlove be post webpack your bags 在其中一个部分中 它给出了包含该问题的一行本质的代码示例 export default class Butto
  • 使用 C# 获取 MySQL 记录数

    我想知道如何使用 C 获取查询的记录计数 这是我使用的代码 MySqlDataReader recordset null query new MySqlCommand SELECT FROM test ORDER BY type ID AS
  • 双括号初始化 - 优点

    知道我们可以通过使用双括号初始化来初始化java中的集合 对此进行了一些搜索 发现由于其性能问题 不建议使用它 private static final Set
  • VBA复制文件;抑制“文件已存在”并确定是否成功?

    我有一些代码用于将文件夹从本地 PC 复制到网络共享驱动器 以进行备份 我对我的代码有两个问题 首先 当代码运行时 它的作用就像 Windows 中的复制 粘贴 如果文件已经存在 它会询问我是否要覆盖它们 我确实想覆盖它们 因为我每天都运行
  • 如何使用设备货币格式格式化浮点值?

    我有一个可以打印计算出的货币值的应用程序 我想以默认货币格式显示该值 例如在欧洲你可以写 1 000 95 在美国我想你会写 1 000 95 在其他货币中 小数部分显示的值或多或少 在美国为 2 但在日本为 0 如何获得所有现有货币的尽可
  • Android Viewpager 项目访问

    我的目标是能够滑动 3 个不同的布局 并能够单击每个布局上的项目 目前 滑动功能运行良好 可以查看所有 3 个布局 活动 public class FetchMenu extends Fetch protected ImageView bl
  • 添加更高版本的语句?

    我正在使用 1 6 即 API 4 来构建我的应用程序 更高版本支持几个命令 我想编写这些命令并使应用程序更兼容更高版本 就像 我使用标签 我想使用 setLeftStripDrawable 和 setRightStripDrawable
  • 玩转无穷大——懒惰算术

    许多现代编程语言允许我们处理潜在的无限列表并对它们执行某些操作 示例 Python EvenSquareNumbers x x for x in naturals if x mod 2 0 这样的列表可以存在 因为只计算实际需要的元素 懒惰