Haskell 在递归函数中标记项目

2023-12-06

一般来说,我对 Haskell 和函数式编程还很陌生,所以如果这个问题看起来简单或愚蠢,请原谅我。

我有一个简单语言的解析器,可以生成抽象语法树。为了展平 AST(将 while 和 if 语句转变为跳转),我需要在树中放置标签。问题是我不知道下一个标签应该是什么(我仍然在强制思考,因为如果我有状态,这一切都不会成为问题)。

到目前为止我所拥有的功能如下:

transform :: Stmt -> FStmt
transform (Seq stmt) = FSeq (map transform stmt)
transform (Assign var val) = FAssign var val
transform (While cond stmt) = FWhile "label1" (Jumpf cond "label2") (transform stmt) (Jump "label1") "label2"
transform (If cond stmt1 stmt2) = FIf (Jumpf cond "label") (transform stmt1) "label" (transform stmt2)

在当前状态下,该函数“展平”AST,但不会尝试放置正确的标签(它为每个构造使用相同的字符串)。

基本上问题是,在顺序语句的情况下(每个程序都是顺序语句),我想不出一种方法来传递应该在标签中使用的下一个值。

先感谢您。


如果我正确理解你的问题,你可以向函数添加一个额外的参数自由索引像这样:

transform :: Stmt -> FStmt
transform = snd . transform' 0

transform' :: Int -> Stmt -> (Int, FStmt)
transform' freeIdx (Seq stmt) = (freeIdx', FSeq stmt')
  where
    (freeIdx', stmt') = mapAccumL transform' freeIdx stmt
transform' freeIdx (Assign var val) = (freeIdx, FAssign var val)
transform' freeIdx (While cond stmt) =
    (freeIdx', FWhile label1 (Jumpf cond label2) stmt' (Jump label1) label2)
  where
    label1 = "label" ++ show freeIdx
    label2 = "label" ++ show (freeIdx + 1)
    (freeIdx', stmt') = transform' (freeIdx + 2) stmt
transform' freeIdx (If cond stmt1 stmt2) =
    (freeIdx'', FIf (Jumpf cond label) stmt1' label stmt2')
  where
    label = "label" ++ show freeIdx
    (freeIdx', stmt1') = transform' (freeIdx + 1) stmt1
    (freeIdx'', stmt2') = transform' freeIdx' stmt2

但如果你了解 State monad,你可以这样设计:

transform :: Stmt -> FStmt
transform = flip evalState 0 . transform'

transform' :: Stmt -> State Int FStmt
transform' (Seq stmt) = FSeq <$> mapM transform stmt
transform' (Assign var val) = return $ FAssign var val
transform' (While cond stmt) = do
    label1 <- freeLabel
    label2 <- freeLabel
    stmt' <- transform' stmt
    return $ FWhile label1 (Jumpf cond label2) stmt' (Jump label1) label2
transform' (If cond stmt1 stmt2) = do
    label <- freeLabel
    stmt1' <- transform' stmt1
    stmt2' <- transform' stmt2
    return $ FIf (Jumpf cond label) stmt1' label stmt2'

freeLabel :: State Int String
freeLabel = do
    i <- get
    put $ i + 1
    return $ "label" ++ show i
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 在递归函数中标记项目 的相关文章

  • Haskell 中函数和函子有什么区别?只有定义吗?

    在 Haskell 中 当编写函数时 这意味着我们将某个东西 输入 映射到另一个东西 输出 我尝试 LYAH 来理解 Functor 的定义 看起来和普通 Functor 一样 函数被称为函子有什么限制吗 Functor 是否允许有 I O
  • 为什么 Haskell 中有协函子和逆变函子的区别,而范畴论却没有区别?

    这个答案是从范畴论的角度来看的 https math stackexchange com a 661989 72174包括以下语句 事实是 协函子和逆变函子之间没有真正的区别 因为每个函子只是一个协变函子 More in details a
  • 如何让 Show 显示函数名称?

    作为一个让我熟悉 Haskell 的简单练习 在 Youtube 上闲逛并偶然进入美国倒计时游戏节目之后 我想为数字游戏制作一个求解器 你得到 6 个数字 需要将它们与 为了得到给定的结果 到目前为止我所得到的是非常脑死亡的 let ope
  • 在 Haskell 中计算移动平均线

    我正在学习 Haskell 所以我尝试实现移动平均函数 这是我的代码 mAverage Int gt Int gt Float mAverage x a fromIntegral k fromIntegral x k lt rawAvera
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • 将数据类型设置为 Kind * -> * 这不是函子

    布伦特 约尔吉类型分类百科全书 https www haskell org haskellwiki Typeclassopedia给出以下练习 举一个类型的例子 gt 不能将其制成 的实例Functor 不使用undefined 请告诉我什
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • 在 Haskell 中,为什么我必须在这段代码中使用美元符号?

    我仍在尝试破解这段代码 import Data Char groupsOf groupsOf n xs take n xs groupsOf n tail xs problem 8 x maximum map product groupsO
  • 以下两个 lambda 函数的空间复杂度

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • Haskell 泛化问题(涉及列表理解)

    假设我想知道a上的所有要点 x y 矩形内的平面has 我可以使用列表推导式来计算 如下所示 let myFun2D x y x lt 0 2 y lt 0 2 现在 如果我想为一个人完成同样的事情 x y z 空间 我可以采取同样的方式并
  • 用 C++ 生成 AST

    我正在用 C 制作一个解释器 到目前为止我已经有了词法分析器来生成标记 问题是我不确定如何生成 行走 解析树 我正在考虑使用数组数组来制作解析树 但我不确定如何以正确的顺序将标记实际插入到解析树中 我不确定是自上而下 左右还是自下而上 左右
  • 标准的能力

    我发现了一些使用标准的旧例子here http www serpentine com blog 2009 09 29 criterion a new benchmarking library for haskell 看起来好像早在 2009
  • 如何在 Haskell 中制作打勾游戏的图案?

    实现有 2 个参数的函数 ticktick 第一个参数是自然数元组 定义游戏场地的行数和列数 第二个列表包含由玩家 x 和玩家 o 轮流玩的坐标给出的井字游戏比赛的记录 打印游戏的实际状态 其中游戏区域将由字符 和 界定 空方块 以及字符
  • Haskell:Data.Numbers.Primes 库在哪里?

    我尝试导入 Data Numbers Primes import Data Numbers Primes 伦哈斯克尔给了我 5 hs 1 8 Could not find module Data Numbers Primes Use v t
  • 有没有更好的方法将 UTC 时间转换为大纪元时间?

    我想将文件的修改时间设置为从 exif 数据获取的时间 为了从 exif 获取时间 我发现 Graphics Exif getTag Exif gt String gt IO Maybe String 要设置文件修改时间 我发现 Syste
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • 找不到模块“Yesod”

    我有以下代码 LANGUAGE TypeFamilies QuasiQuotes MultiParamTypeClasses TemplateHaskell OverloadedStrings module Simple where imp
  • Haskell - lambda 表达式

    我试图了解什么是有用的以及如何在 Haskell 中实际使用 lambda 表达式 我不太明白使用 lambda 表达式相对于定义函数的约定方式有何优势 例如 我通常会执行以下操作 let add x y x y 我可以简单地打电话 add
  • ST monad 是如何工作的?

    我知道 ST monad 有点像 IO 的弟弟 而 IO 又是添加了状态 monadRealWorld魔法 我可以想象状态 也可以想象 RealWorld 以某种方式放入 IO 中 但每次我写一个类型签名ST the sST monad 的

随机推荐

  • 安装 Apple 的网络链接调节器工具

    我已经在运行 Lion 的机器上安装了 xcode 4 3 1 我在任何地方都找不到网络链接调节器工具 我已经检查了实用程序文件夹 还有xcode contents developer 目录 没有这样的运气 我是否需要安装特定组件或者该工具
  • CodeIgniter - 声明全局变量的最佳位置

    我只想用一个 variable在几个地方 不仅是视图和控制器 而且在routes php和其他配置文件 我不想要这样的事情 使用 Config 类加载配置文件 使用 CIget instance等等 我只想声明一个给定的 variable
  • 有没有简单的方法在 Windows 版 xampp 中安装 SSH?

    有没有简单的方法在 Windows 版 xampp 中安装 SSH 我不相信是这样 即使可以 您也无法像在 nix 机器上所期望的那样无缝访问 apache 和 mysql 如果你已经死心了 最好的选择就是安装 openssh 服务器 ht
  • 在 Next.js 中将回调从服务器组件传递到客户端组件

    我陷入了创建自定义按钮组件 将其标记为客户端组件 然后传递其onClick来自服务器端组件的回调 它给了我这个错误 error Error Event handlers cannot be passed to Client Componen
  • lambda 函数可以模板化吗?

    在 C 11 中 有没有办法模板化 lambda 函数 或者它本身就太具体而无法模板化 我知道我可以定义一个经典的模板化类 函子 但问题更像是 该语言是否允许模板化 lambda 函数 2018 年更新 C 20 将附带模板化和概念化的 l
  • 在WPF中使用C#代码删除IE缓存和Cookie

    我在 WPF 应用程序中使用 WebBrowser 控件 并且希望从代码中清除 IE cookie 缓存 我尝试使用以下代码 string Cookies System IO Directory GetFiles Environment G
  • 从java中的类对象构造类实例

    我需要从类对象数组创建类的新实例 如下所示 static Class spells Fireball class Iceball class 所以当我想调用火球时我应该能够做类似的事情 Spell Currentspell new spel
  • 如何获取本地安装的 Python 模块的列表?

    如何获取我的计算机上安装的 Python 模块的列表 help modules 在 Python shell 提示符中
  • ggplot 多线图上缺少图例

    我正在从包含每年最小值 平均值和最大值的数据框中绘制年度温度数据 我一直无法在我的情节上找到传说 理想情况下 图例应具有图例标题并将线条颜色标记为 最小值 平均值 和 最大值 任何帮助 将不胜感激 数据看起来像 示例 数据名为 s 示例数据
  • 从阅读器中删除或忽略字符

    我正在将所有字符读入流中 我正在使用 inputStream read 读取它 这是 java io Reader 输入流 读入缓冲区时如何忽略 等特殊字符 code private final void FillBuff throws j
  • 如何在地图中平滑移动标记而不闪烁

    每次我收到服务器请求以获取设备的新位置并更新地图上标记的位置时 我的标记都会出现问题 当我的车辆设备移动时 标记将跳转到新位置并闪烁 我怎样才能避免这种情况不闪烁 或者我的标记可以顺利移动 先感谢您 var map var marker v
  • 需要通过 Union() 中的匿名类型显式转换

    我有 2 个 var objects 通过这两个函数检索 private IQueryable
  • 为什么这个正则表达式中的后向表达式没有“明显的最大长度”?

    给定一个包含一定数量的方括号和其他字符的字符串 我想找到所有右方括号 前面有一个左方括号和一些字母 例如 如果字符串是 abc 123 abc 我只想找到第二个右括号 以下正则表达式 会找到第二个右括号 也是最后一个 abc 123 abc
  • 在屏幕上的随机位置生成一个圆圈

    我一直在绞尽脑汁 到处搜索 试图找出如何在屏幕上生成一个随机位置来生成一个圆圈 我希望这里有人可以帮助我 因为我完全被难住了 基本上 我试图创建一个形状 当用户触摸时 该形状总是在屏幕上的随机位置生成 override func touch
  • Rails 将普通旧字符串作为 BLOB 保存到 SQlite?我快要疯了!

    我不知道为什么会发生这种情况 但 Rails 正在将字符串作为 BLOB 保存到 SQLite 在我的应用程序中创建新用户之前 我会先获取他们的纯字符串密码并对其进行 MD5 然后再保存到数据库 class User lt ActiveRe
  • OptaPlanner 在 CartesianProductMoveSelector 创建的 CompositeMove 上抛出 IllegalStateException

    所以基本上我的问题是 OptaPlanner 抛出这个 java lang IllegalStateException The entity has a variable previousEntry with value which has
  • 将字符(与传递字符串)传递给 EL 中的支持 bean 方法

    我想直接从命令按钮调用设置器并传递一个值 我的问题是 如果将其作为字符串传回 则设置器需要一个字符和 jsf 有没有一种好方法可以在前端 修复 这个问题 而不必在我的支持 bean 上超载 setter 命令按钮
  • PHP脚本内存泄漏问题

    我正在从命令行运行下面的 PHP 代码 问题是 它的内存消耗远远超过了应有的水平 我一生都无法弄清楚内存被消耗在哪里 for i 0 i lt 100 i classObject classObjects i echo i memory g
  • PhantomJS 的行为与 Firefox webdriver 不同

    我正在编写一些使用 Selenium Web 驱动程序 Firefox 的代码 大多数事情似乎都有效 但是当我尝试将浏览器更改为 PhantomJS 时 它的行为开始有所不同 我正在处理的页面需要缓慢滚动才能加载越来越多的结果 这可能就是问
  • Haskell 在递归函数中标记项目

    一般来说 我对 Haskell 和函数式编程还很陌生 所以如果这个问题看起来简单或愚蠢 请原谅我 我有一个简单语言的解析器 可以生成抽象语法树 为了展平 AST 将 while 和 if 语句转变为跳转 我需要在树中放置标签 问题是我不知道