Haskell 中的 Futamura 投影的证明

2024-04-22

我读了 Dan Piponi 的优秀博客文章二村博士的三个投影 http://blog.sigfpe.com/2009/05/three-projections-of-doctor-futamura.html。在文章的最后,他有一个附录,其中包含 Haskell 中 Futamura 投影的证明。然而,我发现他的文章缺乏有关所涉及语言的信息。为了让 Futamura 投影发挥作用,专家的源语言、目标语言和对象语言必须是什么?例如,如果我用 Haskell 编写一个 Haskell 到 LLVM 专用程序,Futamura 投影会起作用吗?如果您像 Dan Piponi 在他的文章中所做的那样编写一个 Haskell 程序来证明这一点,将会很有帮助。


是的,当且仅当专门化器的源语言和目标语言相同时,二村投影才会起作用。这是因为,如果专用化器是用它可以读取的相同语言编写的,则它只能应用于其自身。然而,专家的目标语言独立于其他两种语言。这会产生重要的后果,我将在本答案后面讨论。

为了证明我的假设,我将引入一种新的符号来松散地描述基于墓碑图 https://en.wikipedia.org/wiki/Tombstone_diagram。墓碑图(或 T 图)是编译器和其他相关的图形表示元程序 https://en.wikipedia.org/wiki/Metaprogramming。它们用于说明和推理以对象语言(T 底部)实现的程序从源语言(T 左侧)到目标语言(T 右侧)的转换。让我们将 T 图的想法扩展到适用于所有程序:

α → β : ℒ -- A program is a function from α to β as implemented in language ℒ.

对于元程序α and β本身就是程序:

(α → β : ????) × α → β : ???? -- An interpreter for language ???? as implemented in ????.
(α → β : ????) → (α → β : ????) : ???? -- A compiler from ???? to ???? as implemented in ????.
(ι × α → β : ????) × ι → (α → β : ????) : ???? -- A self-hosting specializer from ???? to ????.
(ι × α → β : ????) → (ι → (α → β : ????) : ????) : ???? -- A compiler compiler from ???? to ????.

这种表示法可以直接转换为 Haskell 中的类型定义。有了这个,我们现在可以用 Haskell 编写关于语言的 Futamura 投影的证明:

{-# LANGUAGE RankNTypes #-}

module Futamura where

newtype Program a b language = Program { runProgram :: a -> b }

type Interpreter source object = forall a b.       Program (Program a b source, a) b object
type Compiler    source target = forall a b.       Program (Program a b source) (Program a b target) target
type Specializer source target = forall input a b. Program (Program (input, a) b source, input) (Program a b target) source
type Partializer source target = forall input a b. Program (Program (input, a) b source) (Program input (Program a b target) target) target

projection1 :: Specializer object target -> Interpreter source object -> Program a b source -> Program a b target
projection1 specializer interpreter program = runProgram specializer (interpreter, program)

projection2 :: Specializer object target -> Interpreter source object -> Compiler source target
projection2 specializer interpreter = runProgram specializer (specializer, interpreter)

projection3 :: Specializer source target -> Partializer source target
projection3 specializer = runProgram specializer (specializer, specializer)

我们使用RankNTypes语言扩展隐藏类型级机制,使我们能够专注于所涉及的语言。对自身应用专门化器也是必要的。

在上面的程序中,第二个投影特别令人感兴趣。它告诉我们,给定一个自托管 Haskell 到 LLVM 专用程序,我们可以将其应用于用 Haskell 编写的任何源语言 ???? 的解释器,以获得 ???? 到 LLVM 编译器。这意味着我们可以用高级语言编写解释器,并使用它生成针对低级语言的编译器。如果专门化器有任何好处,那么生成的编译器也会相当不错。

另一个值得注意的细节是自托管专用程序与自托管编译器非常相似。如果您的编译器已经执行部分评估,那么将其转变为专用器应该不需要太多工作。这意味着实施二村预测比最初认为的要容易得多,回报也大得多。我还没有对此进行过测试,所以请持保留态度。

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

Haskell 中的 Futamura 投影的证明 的相关文章

  • C# 中的 C/C++ 代码编译器

    在 C 中 我可以使用下面的代码编译 VB 和 C 代码 但无法编译 C C 代码 有什么办法可以做到这一点吗 C 编译器 public void Compile string ToCompile string Result null st
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • Parsec.Expr 具有不同优先级的重复前缀

    Parsec Expr buildExpressionParser 的文档说 相同优先级的前缀和后缀运算符只能出现一次 即 如果 为前缀否定 则不允许使用 2 但是 我想解析这样的字符串 具体来说 考虑以下语法 sentence ident
  • 如何使用foldr为列表创建显示实例?

    我想为我的数据类型 我的列表 编写自己的显示实例 到目前为止 我的方法是有效的 但我总是在末尾有一个逗号 我已经尝试用最后一个元素启动折叠并将其从列表中删除 但它很麻烦而且不起作用 有没有更简单的方法来获得正确的解决方案 实际 1 2 3
  • 在 Haskell 中将字符串转换为整数/浮点数?

    data GroceryItem CartItem ItemName Price Quantity StockItem ItemName Price Quantity makeGroceryItem String gt Float gt I
  • 如何在 Haskell Pipes 中将两个 Consumer 合并为一个?

    我使用Haskell流处理库pipes https hackage haskell org package pipes编写一个命令行工具 每个命令行操作都可以将结果输出到stdout并记录到stderr with pipes API I n
  • 不同的 JDK 更新会产生不同的 Java 字节码吗?

    假设场景 我有一个项目 其源合规性级别指定为 1 5 现在 我使用两种不同的 JDK 编译此项目 首先使用 JDK 6 Update 7 然后使用 JDK 6 Update 20 这两个不同的 JDK 是否会生成不同的 Java 字节代码
  • cabal install wx 缺少 C 库

    Env 操作系统 feodra 16 Haskell 平台 wxGTK 开发 GHHC 7 0 4 我正在尝试安装 wxHaskell 阴谋集团安装wx 然后给出这些错误 缺少对外国库的依赖 缺少 C 库 wx baseu 2 8 wx b
  • 如何在 Haskell 中使 CAF 不是 CAF?

    如何将常量应用形式变成 而不是常量应用形式 以阻止它在程序的生命周期中保留 我尝试过这种方法 Dummy parameter to avoid creating a CAF twoTrues gt Bool twoTrues map Tru
  • 我可以从 GHCi 中找到 GHC 版本吗?

    gt 我在里面输入什么GHCi发现它正在使用哪个 GHC 版本 gt import System Info gt browse arch String compilerName String compilerVersion Data Ver
  • 使用 Haskell 绘制图表

    是否可以使用 Haskell 绘制一个简单的图表 你们中的任何人都可以告诉我该怎么做吗 该图应至少包含 3 个点 Haskell 图表 https github com timbod7 haskell chart似乎不错 The wiki
  • 为什么我不能声明推断类型?

    我有以下内容 runcount Eq a Num b gt a gt b runcount runcountacc 0 runcountacc Eq a Num b gt b gt a gt b runcountacc n runcount
  • 了解C/C++中函数调用的堆栈框架? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我也是 C C 和汇编语言的新手 这
  • 这是 unsafeCoerce 的安全使用吗?

    我遇到的情况是 我目前正在使用极其可怕的函数 unsafeCoerce 幸运的是 这并不是为了任何重要的事情 但我想知道这是否是该函数的安全使用 或者是否有其他方法可以解决其他人知道的这个特定问题 我的代码类似于以下内容 data Toke
  • Haskell数据类型转换问题

    我目前正在学习 Haskell 并且一直在编写一些非常简单的程序来练习 我的程序之一是 import System IO main do putStrLn Give me year y lt getLine let res show cal
  • 使用默认值压缩而不是删除值?

    我正在 haskell 中寻找一个函数来压缩两个长度可能不同的列表 我能找到的所有 zip 函数都只是删除列表中比其他列表长的所有值 例如 在我的练习中 我有两个示例列表 如果第一个比第二个短 我必须用 0 填充 否则我必须使用 1 我不允
  • 如何与更高级别的类型合作

    玩弄教堂的数字 我遇到了无法指导 GHC 类型检查器处理高阶类型的情况 首先我写了一个版本 没有任何类型签名 module ChurchStripped where zero z z inc n z s s n z s natInteger
  • 在ghci中,如何删除现有的绑定?

    我收到一个 绑定影响现有绑定 错误 类似于以下错误this https stackoverflow com questions 2902716 in haskell what does it mean if a binding shadow
  • 引用与指针的执行速度

    我最近阅读了一篇关于托管语言是否比本机语言 特别是 C 与 C 慢 或快 的讨论 一位参与讨论的人士表示 托管语言的 JIT 编译器将能够对引用进行优化 而这在使用指针的语言中是不可能实现的 我想知道的是 对于引用而不是指针可以进行 什么样
  • 当约束成立时,将没有约束的 GADT 转换为另一个有约束的 GADT

    我们能否将构造函数没有给定约束的 GADT 转换为具有上述约束的 GADT 我想这样做是因为我想要深度嵌入箭头并用 目前 似乎需要的表示做一些有趣的事情Typeable 一个理由 https stackoverflow com a 1223

随机推荐

  • IE9、IE11 和 Safari 的复制到剪贴板选项

    我正在尝试在网页上实现复制到剪贴板按钮 下面是我写的代码 function copyToClipboard element var temp
  • com.google.android.mms.* 在哪里? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在编写一个从 Android 手机发送彩信的应用程序 我正在尝试按照这篇文章中的说明进行操作 An
  • Ruby 中按身份分组

    鲁比的怎么样group by http ruby doc org core 2 2 3 Enumerable html method i group by方法按标识对数组进行分组 或者更确切地说self 其元素 a abccac chars
  • 设置 jQuery 的 get 速记超时

    是否可以使用 jQuery 的 get 简写来设置 ajax 超时参数 如果不是 使用速记发送的请求是否会超时 jQuery get url data callback data textStatus XMLHttpRequest data
  • 禁用 Google 应用测量调试日志记录

    在 Xcode 7 2 上 如何禁用这些调试 应用程序测量紧急显示 2016 01 07 11 52 53 085 MyApp 1457
  • Gradle 将工件部署到本地目录内的 Maven 存储库

    Gradle 与 Maven 的等价物是什么
  • 如何允许Java程序一次只运行一个实例?

    我需要防止用户多次启动我的 Java 应用程序 WebStart Swing 应用程序 因此 如果应用程序已经在运行 则不应再次启动它或显示警告 再次关闭 有没有一些方便的方法来实现这一目标 我考虑过阻止端口或将某些内容写入文件 但希望您可
  • EntityFramework 如何覆盖属性

    我刚刚开始在 VS2010 中使用 EF 那东西真是太神奇了 坦白说我有些不明白 例如 我有带有属性的 EntityType 它们是从数据库结构生成的 现在 我只需在代码中重写该属性 我不需要将属性的值保存回数据库 但每次从数据库读取它时
  • 在 React 中渲染 Three.js 元素?

    我正在尝试制作一个渲染 Three js 场景的 React 组件 但是 每当我尝试安装组件而不是看到正在渲染的任何类型的场景时 我只看到文本 object HTMLCanvasElement 正在显示 这是我的组件 import Reac
  • 获取DLL函数的内存地址

    我想知道是否有可能 使用 C 和 WindowsAPI 是否有一个函数可以让我获得 dll 中函数的 32 位 我认为 内存地址 例如 如何获取 kernel32 dll 中 Beep 的 32 位 xxxxxxxx 地址 其次 如果我在汇
  • Symfony2:在实体类中获取 security.context

    是否可以得到security context在实体类中 我知道以下不起作用 我不知道如何实施 user part Set createdAt ORM PrePersist public function setCreatedAt user
  • 使用 Pyparse 解析多个项目并将其分组在一起

    这是建立在构建一个简单的解析器 能够使用 PyParse 解析不同的日期格式 https stackoverflow com questions 28113532 build a simple parser that is able to
  • 如何检测元素是否已滚动但仅滚动一次?

    我正在尝试检测某个元素是否已滚出并完成了以下代码 window bind scroll function var btn intro div summary a href top if window scrollTop gt btn off
  • Sqlite - 降级时

    最近我更新了我的android游戏 编辑sqlite数据库在我的表中添加新字段 更新后 我收到4个崩溃报告 其中3个来自同一设备 三星Galaxy S4 android database sqlite SQLiteException 无法降
  • JQuery 对话框在关闭时冻结

    termSheetPrinted dialog autoOpen false resizable true height 800 width 950 position center title Term Sheet close functi
  • 在 Spark SQL 中将结构转换为映射

    我正在尝试转换一个数据集 该数据集声明一列具有特定的struct类型 例如struct
  • React 中的 Map 函数(错误:TypeError:e.map 不是函数)

    我想从道具渲染项目 我可以使用初始状态来完成 但不能使用服务器的响应来完成 我的渲染函数 const data this props return div data map item index gt div span item id sp
  • 修复颠覆中犯下的错误

    这似乎是人们可能想要用颠覆做的最基本的事情之一 但我使用版本控制系统的时间并不长 不知怎的 我似乎无法弄清楚这一点 而且我不知道在哪里svn文档看看 基本上 修订版 167 工作得很好 但我犯了一个错误 并将其提交为修订版 168 而且我不
  • 无法在 mac osx 上的 QT 中创建新项目

    过去几天我一直坚持这个问题 我已经安装了 QT 4 8 并且也安装了库 但是当我开始创建一个新项目时 我只能选择使用 CMake 创建一个普通的 C 项目 我没有使用自动 qmake 的选项 我不知道为什么 如果有人可以帮忙 我们将不胜感激
  • Haskell 中的 Futamura 投影的证明

    我读了 Dan Piponi 的优秀博客文章二村博士的三个投影 http blog sigfpe com 2009 05 three projections of doctor futamura html 在文章的最后 他有一个附录 其中包