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++ 代码时表达式的结合性和优先级?

    我编写了一个生成 AST 的基本编译器 正确考虑了表达式中运算符的优先级 但是 在执行代码生成以生成 C 代码时 我不确定如何处理括号的使用 对于这个表达式 A B c AST如下 A B C 应该正确生成包含括号的前一个表达式 但是如果第
  • .java 和 .scala 类之间是否可能存在循环依赖?

    假设我在 java 文件中定义了类 A 在 scala 文件中定义了类 B A 类使用 B 类 B 类使用 A 类 如果我使用 java 编译器 则会出现编译错误 因为 B 类尚未编译 如果我使用scala编译器A类将找不到 有没有可以同时
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • Haskell:无法预期类型“Integer”与实际类型“Int”

    我已经盯着这段代码有一段时间了 但我无法理解该错误消息 divisors Integer gt Integer divisors n t t lt 1 n mod n t 0 length a gt Integer length 0 len
  • Haskell:是的,没有类型类。为什么是整数?

    我有一个关于 GHCi 如何假定整数类型的问题 我正在阅读 Learn you a Haskell 是 否类型的课程 如果您想阅读全文 这里有一个链接 http learnyouahaskell com making our own typ
  • 如何在 Haskell 中向右或向左移动列表的 1 个元素?

    嗨 我一直在寻找答案 但找不到 假设我们有一个像这样的列表 1 10 4 5 3 我怎样才能将 5 向左移动 使这个列表变成 1 10 5 4 3 我尝试过了swapElementsAt通过找到该元素的索引 但它看起来非常不足 swapEl
  • 在依赖类型的函数式编程语言中,扁平化列表是否更容易?

    在 haskell 中寻找一个可以展平任意深度嵌套列表的函数时 即应用的函数concat递归并在最后一次迭代时停止 使用非嵌套列表 我注意到这需要有一个更灵活的类型系统 因为随着列表深度的变化 输入类型也会变化 确实 有几个 stackov
  • 特殊名称属性还允许哪些其他巧妙的技巧?

    研究中一个问题 https stackoverflow com questions 13259162 vb net power operator overloading from c sharp关于实现 Visual Basic Power
  • 是否可以用 C# 为 Android 编写应用程序?

    我们都知道Android运行Dalvik VM程序 通常开发人员用 Java 编写程序并将其编译为 Dalvik 字节码 我想知道是否有可能创建一个可以接受 C 代码并将其编译为 Dalvik 字节码的编译器 嗯 这是一种选择 或者您可以在
  • Haskell - 用防护罩替换外壳

    我想知道在这部分代码中是否可以用守卫替换 case 语句 firstFunction String gt Maybe MyType secondFunction MyType gt Integer myFunction String gt
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • 在 Yesod 生态系统中,对某些文本进行 urlencode 的最佳方式是什么?

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

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • Nullable 是不可能的,为什么不呢? [复制]

    这个问题在这里已经有答案了 如果这是一个愚蠢的问题 请原谅 我正在尝试更好地理解 Net 中的 Nullable 类型 从我从 Microsoft 源代码 使用 ReSharper 中注意到的内容 我了解到 Nullable 是一个结构 而
  • Flash Builder 条件编译变量

    我正在使用 Flash Builder 4 5 并且我想在调试和发布版本之间使用条件编译 我了解如何使用条件编译以及如何定义编译器常量 我需要的是 IDE 在调试和发布版本之间设置的预定义常量 一种在调试和发布版本之间为编译器指定不同参数的
  • : 中缀运算符在 Haskell 中的作用是什么?

    我正在阅读Haskell 简要介绍 http www haskell org tutorial index html 这不是那么温和 并且它反复使用 操作符而不直接解释它的作用 那么 它到底有什么作用呢 是 前置 运算符 x xs 返回一个
  • 为什么 ZipList 不是 List 的默认应用实例

    我目前正在学习 Haskell 中的应用程序 如果我没记错的话 列表有两个不同的应用实例 List and ZipList 第二个被定义为包装列表值的新类型 这ZipList应用实例对我来说似乎更直观 这可能是一个愚蠢的问题 但有具体原因吗
  • 如何在Windows上安装机器人操作系统ROSJava?

    ROS 的文档很糟糕 一个很大的讽刺是 ROS 的 Groovy 和 ROSJava 版本的创建是为了让 Windows 等平台上的开发人员能够利用出色的机器人 SDK 而所有安装说明仍然面向 Linux ubuntu 用户 The ROS
  • 可以读取目标文件吗?

    我很好奇 obj文件 我几乎不知道它们是什么 或者它们包含什么 所以我用 Vim 文本编辑器打开它们 我在里面发现了一种类似外星人的语言 有什么办法可以理解它们代表什么以及它们的内容是什么 另外 它们的用途是什么 Thanks Sure 但
  • 如何在不声明新数据的情况下更改类型(String,Int)元组的 Ord 实例?

    我正在尝试对类型列表进行排序 String Int 默认情况下 它按字符串排序 然后按整数排序 如果字符串相等 我希望它是相反的 首先比较整数 然后如果相等则比较字符串 另外 我不想切换到 Int String 我找到了一种通过定义实例来实

随机推荐

  • 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 在文章的最后 他有一个附录 其中包