实现惰性函数式语言

2023-12-27

当实现惰性函数式语言时,有必要将值存储为未计算的 thunk,仅在需要时才进行计算。

有效实施的挑战之一,如在例如中所讨论的。无脊椎无标签 G 机,是这个评估必须对每个重击执行一次,并且后续访问必须重用计算值 - 如果不这样做将导致至少二次方减速(也许是指数级?我不确定我的头脑.)

我正在寻找一个简单的示例实现,其操作很容易理解(而不是像 GHC 这样的工业强度实现,它是为了性能而不是简单性而设计的)。我遇到了 minihaskellhttp://www.andrej.com/plzoo/ http://www.andrej.com/plzoo/其中包含以下代码。

由于它被称为“高效的解释器”,我认为它确实只执行一次每个评估并保存计算值以供重用,但我很难看出在哪里以及如何进行;我只能在解释器本身中看到一个赋值语句,这看起来不像是覆盖了 thunk 记录的一部分。

所以我的问题是,这个解释器是否确实进行了这样的缓存,如果是的话,在哪里以及如何进行? (如果没有,现有的最简单的实现是什么?)

代码来自http://www.andrej.com/plzoo/html/minihaskell.html http://www.andrej.com/plzoo/html/minihaskell.html

let rec interp env = function
  | Var x ->
     (try
     let r = List.assoc x env in
       match !r with
           VClosure (env', e) -> let v = interp env' e in r := v ; v
         | v -> v
       with
       Not_found -> runtime_error ("Unknown variable " ^ x))
   ... snipping the easy stuff ...
  | Fun _ as e -> VClosure (env, e)
  | Apply (e1, e2) ->
      (match interp env e1 with
       VClosure (env', Fun (x, _, e)) ->
         interp ((x, ref (VClosure (env, e2)))::env') e
     | _ -> runtime_error "Function expected in application")
  | Pair _ as e ->  VClosure (env, e)
  | Fst e ->
      (match interp env e with
       VClosure (env', Pair (e1, e2)) -> interp env' e1
     | _ -> runtime_error "Pair expected in fst")
  | Snd e ->
      (match interp env e with
       VClosure (env', Pair (e1, e2)) -> interp env' e2
     | _ -> runtime_error "Pair expected in snd")
  | Rec (x, _, e) -> 
      let rec env' = (x,ref (VClosure (env',e))) :: env in
    interp env' e
  | Nil ty -> VNil ty
  | Cons _ as e -> VClosure (env, e)
  | Match (e1, _, e2, x, y, e3) ->
      (match interp env e1 with
       VNil _ -> interp env e2
     | VClosure (env', Cons (d1, d2)) ->
         interp ((x,ref (VClosure(env',d1)))::(y,ref (VClosure(env',d2)))::env) e3
     | _ -> runtime_error "List expected in match")

关键是记录:通知!r, r := v。每当我们从环境中查找变量时,我们实际上都会返回一条记录,我们会取消引用该记录以查看它是否是一个thunk。如果它是一个 thunk,我们对其进行评估,然后保存结果。我们在应用程序期间创建 thunk(注意对ref构造函数)、递归定义和模式匹配,因为这些是绑定变量的构造。

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

实现惰性函数式语言 的相关文章

  • 测试列表是否已排序

    在 haskell 中找到最小列表确实很容易 foldl1 min 9 5 7 3 7 4 6 10 给我3 我更换了min with lt 测试列表是否已排序 foldl1 lt 9 5 7 3 7 4 6 10 我收到此错误消息 No
  • 为什么Haskell没有split函数? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在许多语言中 都有一个函数可以使用指定的分隔符将字符串分成几部分 它经常被称为split 您可以在 Python C Java JavaScri
  • 仪器化状态单子

    我正在努力给予Monad and MonadState的实例State 计算的数量 gt gt return get and put运营 data Counts Counts binds Int returns Int gets Int p
  • 我是否应该使用 GHC Haskell 扩展?

    当我学习 Haskell 时 我发现有很多语言扩展 http haskell org ghc docs latest html users guide ghc language features html在现实生活中使用的代码 作为初学者
  • 在 Haskell 中对单位的组成(例如英寸、美元等)进行建模

    跟进自我之前的一个问题 https stackoverflow com q 73375273 222529 我问如何创建一个可以对单元进行建模的类型 例如Inch 作为 Haskell 中的一种类型 我现在面临的问题是如何对该单元和其他单元
  • 在生成此 SOP 函数时,如何修复类型错误,包括“无法对 Traversable 进行量化”?

    我只是说我什至不确定这是否可能 这是迄今为止我在 Haskell 中尝试过的最通用的事情 我正在尝试制作一个更通用的版本applyFunc在发现https stackoverflow com a 58890226 3096687 https
  • 在 Haskell 中为自定义数据类型创建 Read 类型类的实例

    我有一个自定义数据类型Foo Foo a Int b Int 我正在尝试使 Foo 成为 read 的自定义实例 我已经有一个功能了bar String gt Foo我尝试这样做 instance Read Foo a b where re
  • 应用交换律

    带有效果的应用程序编程 http staff city ac uk ross papers Applicative html麦克布莱德和帕特森的论文提出了互换法 u lt gt pure x pure f gt f x lt gt u 为了
  • 无法通过 cabal 安装“System.Random”

    我尝试通过 Cabal 通过 Powershell 和 Git Bash 安装 System Random 得到这个结果 PS C Users xxx gt cabal install random Resolving dependenci
  • 如何在 Haskell 中枚举递归数据类型?

    这篇博文 http lukepalmer wordpress com 2008 05 02 enumerating a context free language 对于如何使用 Omega monad 对角枚举任意语法有一个有趣的解释 他提
  • Haskell 二进制解析

    我一直在尝试在 haskell 中实现一个协议解析器 而且我对这门语言还很陌生 特别是当涉及到 monad 时 我一直在使用binary 0 5 0 2 并描述了协议的标头和所有有效负载 我想要解析的消息如下所示 header payloa
  • Haskell 中的常量变量声明

    要声明常量变量 我可以在 Ruby 中执行以下操作 class COLOR RED 10 BLUE 20 GREEM 30 end COLOR RED回报10 COLOR BLUE回报20 等等 我如何在 Haskell 中实现这一点 我想
  • 计算两点之间的距离(Haskell)

    给定两个元组的输入 我希望能够使用以下公式计算两点之间的距离 距离 sqrt x1 x2 2 y1 y2 2 所以我希望函数调用和输出如下所示 gt distance 5 10 3 5 5 385 当我尝试运行下面的代码时 它告诉我输入 w
  • 我应该使用镜头中的什么来按索引构建只读吸气剂?

    我有一个内部细节被隐藏的类型 我想提供某种镜头 可以在特定索引处读取所述类型的元素 但是not修改它们 一个Ixed我的类型的实例似乎没有做我想要的事情 因为它明确允许修改 尽管不允许插入或删除 如果我想允许只读索引 我不确定我使用什么 如
  • 处理许多不相关的类型时避免样板

    我正在编写处理以下值的代码语言 扩展 注释 语法 http hackage haskell org packages archive haskell src exts 1 1 4 doc html Language Haskell Exts
  • 带有查询参数的渲染 url

    无法找到简单问题的解决方案 答案应该是显而易见的 如何在 hamlet 模板中使用查询参数渲染 url I e ItemsR 将生成http localhost 3000 items我如何生成类似的东西http localhost 3000
  • 有没有办法在 Emacs 中使用 Djinn 自动生成 Haskell 代码?

    标题几乎说明了一切 我正在寻找这样的东西 f Int gt Bool gt Int f body Djinn 可以使用定理证明来通过证明该类型存在来生成此类函数的代码 我想知道 是否有现有的方法可以从 Emacs 中获取此功能 因此 我不需
  • 管道中缺少 ResourceT 实例

    我在尝试使用时遇到奇怪的错误ResourceT http hackage haskell org package conduit 1 0 9 1 docs Data Conduit html t 3aResourceT来自管道 1 0 9
  • Haskell 中的类型化抽象语法和 DSL 设计

    我正在 Haskell 中设计 DSL 我想要进行赋值操作 像这样的东西 下面的代码只是为了在有限的上下文中解释我的问题 我没有类型检查 Stmt 类型 data Stmt forall a Assign String Exp a Assi
  • 为什么 Haskell 中的点是从右向左排列的?

    如果我们有两个函数 f and g 然后在哈斯克尔h f g相当于h x f g x IE 这些函数从右到左应用于输入 有什么根本原因可以解释为什么它是从右到左 而不是从左到右吗 IE 他们为什么不做h f g相当于h x g f x 反而

随机推荐

  • Asp.net Mvc3 webgrid 和分页

    我正在尝试学习Asp net mvc 我知道它与形式不同 我可能需要改变我的思维方式 我的问题是关于 webgrid 的 当我将 webgrid 添加到我的页面并使用 Post 按下搜索按钮时 它会使用寻呼机等呈现表格 但是寻呼机上的链接不
  • Linux 内核中 IRQ 和中断向量之间的区别

    当涉及到内核 API 的工作时 我对 IRQ 和向量有点困惑 我想使用向量 0xfa 进行一些由可编程 lapic 生成的中断处理 我查看了 API 例如request irq and set intr gate also alloc in
  • 结合 Git Bash 并在 CMDER 中的当前文件夹中打开

    请描述我 谁有这样的经验 如何正确设置CMDER的选项以在当前文件夹中使用Git Bash打开新控制台 例如在此处打开CMDER 该字符串不起作用 C Program Files x86 Git bin sh exe login i new
  • 使用来自存储 C#.Net CNG 的密钥进行 ECDSA 签名文件

    我正在尝试使用 CNG API 和 Microsoft 证书存储中的证书通过 ECDSA 签署文件 我已经阅读了大量文档并且即将完成 但我对从证书导入私钥感到困惑 我已经用 RSA 做了同样的事情 但它的做法似乎非常不同 这是我到目前为止的
  • bash 中的 for 循环只是打印 n 次命令而不是重复

    我有一个包含 6000 多行的 input txt 文件 如果一行 a 包含超过 10 个单词 那么我希望将其拆分 但不是在第 10 个单词处 而是在第一个逗号字符出现的位置处 并且 如果新行也有超过10个单词 那么它也应该被拆分 并不断重
  • 堆叠特征中 super 的含义取决于调用站点?

    我无法用语言对此进行很好的描述 所以 请看这个例子 trait Base def foo Base trait One extends Base override def foo One lt super foo trait Two ext
  • Emacs 中的缓冲区切换

    我想模拟 Alt Tab 因为它适用于 GTK 上的各个窗口 但在 emacs 中的缓冲区内使用 Ctrl Tab 因此 举例来说 如果我在 emacs 中打开了 10 个缓冲区 而我目前正在处理两个缓冲区 例如 Buffer1 和 Buf
  • 企业库错误

    我收到有关我们的生活环境中罕见的间歇性错误的报告 我试图重现它但没有成功 而且这个错误本身有点神秘 除此之外 它似乎涉及企业库跟踪 我们使用的是 5 0 版本 总而言之 有点痛苦 这发生在 Windows Sever 2008 上 应用程序
  • Windows 8 应用程序本地存储

    我正在尝试使用 C 开发 Windows 8 应用程序 我需要在本地设置中存储两个列表 字符串和日期时间 List
  • HTTP/2 中是否有必要缓存bust?

    在 HTTP 1 中 为了避免额外的网络请求来确定资源是否应该保留缓存 我们将设置一个高值max age or Expires静态资产的值 并为每个修订版提供唯一的 URL 但在 HTTP 2 中 请求很便宜 所以我们可以在不清除缓存的情况
  • 有没有一种简单的方法可以从两个整数复合键创建唯一的整数键?

    由于与问题不太相关的各种原因 我有一个表 其中包含由两个整数组成的复合键 我想从这两个数字中创建一个唯一的键 我最初的想法是连接它们 但当我意识到 51 1 的复合键会产生与 5 11 相同的唯一键 即 511 时 我很快遇到了问题 有没有
  • 以编程方式访问 Excel 自定义文档属性

    我正在尝试将自定义属性添加到以编程方式创建的工作簿中 我有一个用于获取和设置属性的方法 但问题是工作簿为 CustomDocumentProperties 属性返回 null 我无法弄清楚如何初始化此属性 以便我可以从工作簿中添加和检索属性
  • PHP - 使用 GZIP 压缩静态 css 文件

    所以我有一个CSS文件 style css 在同一目录中我有 images 文件夹 如何制作一个压缩 style css 的脚本 但来自另一个文件夹 现在我有这个
  • 更新数百万个文档的嵌套字段

    我使用脚本进行批量更新来更新嵌套字段 但这非常慢 POST index type bulk update id 1 script inline ctx source nestedfield add params nestedfield pa
  • Agda 函数、类型匹配函数

    我想创建一个辅助函数 它将从索引或参数化类型中获取术语并返回该类型参数 showLen len A Set gt Vec A len gt showLen len showType len A Set gt Vec A len gt Set
  • 测试点是否在匹配的引号之间 (emacs lisp)

    我们如何检查是否 point 在匹配的 引号 内 示例 1 point 但不在范围之内 示例 2 此处引用 point 那里引用 在 Emacs Lisp 中 您正在寻找的是syntax ppss 定义于syntax el 它返回 10 个
  • 如何在Python中捕获自定义异常[重复]

    这个问题在这里已经有答案了 我正在使用一个 python 库 其中在某一时刻定义了一个异常 如下所示 raise Exception Key empty 我现在希望能够捕获该特定异常 但我不知道该怎么做 我尝试了以下方法 try raise
  • C++ 中的比较性能( foo >= 0 与 foo != 0 )

    我最近一直在写一段代码 其中性能非常重要 基本上我有以下情况 int len some very big number int counter some rather small number for int i len i gt 0 i
  • flutter:带有后备文本的 CircleAvatar

    我正在学习 Flutter 想做一个Widget就像内置的一样CircleAvatar 但是 我希望这种行为是 指定图像 NetworkImage 和缩写 即 BB 当图像未加载时 显示缩写 如果图像加载 则显示图像并删除缩写 下面的代码可
  • 实现惰性函数式语言

    当实现惰性函数式语言时 有必要将值存储为未计算的 thunk 仅在需要时才进行计算 有效实施的挑战之一 如在例如中所讨论的 无脊椎无标签 G 机 是这个评估必须对每个重击执行一次 并且后续访问必须重用计算值 如果不这样做将导致至少二次方减速