debugging - 如何在 Haskell 中调试变量/递归数据类型
问题描述
https://www.inf.ed.ac.uk/teaching/courses/inf1/fp/exams/exam-2016-paper1-answers.pdf
-- 3b
trace :: Command -> State -> [State]
trace Nil s = [s]
trace (com :#: mov) s = t ++ [state mov (last t)]
where t = trace com s
我很难理解第 3b 节。我尝试一一调试变量,但我总是以违反定义的数据类型而告终。代码让我感到困惑,我想看看变量包含什么。我怎样才能使用 Debug.Trace 来做到这一点?
https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base-4.12.0.0/Debug-Trace.html
谢谢你。
解决方案
看起来第 3b 节正在教授“递归的工作原理”这些幻灯片仅涵盖传统的 Haskell 列表。你所拥有的:#:
是相反的,有时称为snoc
列表。然后一个明智的设计trace
是也产生一个snoc
列表结果。但事实并非如此(可能是因为讲师认为通过这样折磨初学者,他们会学到一些东西)。Haskell 列表推导仅适用于列表,不适用于snoc
. (那么这些幻灯片中的一半内容对于这个练习是无用的。)所以 3b 正在通过递归教你结构反转(这是幻灯片中有用的一半)。
违反定义的数据类型
您提供的代码中的变量t
是函数的本地变量trace
,因此似乎难以访问。但它的定义
t = trace com s
不是:
- 我们知道
trace :: Command -> State -> [State]
- 我们可以在等式中
t
看到trace
它适用于两个参数。 - 所以 的类型
t
必须是 的结果的类型trace
,即[State]
。
您不确定trace
等式中参数的类型是什么t
?特别是com
从Command
论点解压缩到trace
顶层。
然后我们需要了解
:#:
. 我们有问题 3data Command = Nil | Command :#: Move
这就是
(:#:)
一个中缀运算符(这就是我把它放在括号中的原因)。- 然后我们可以向 GHCi 询问它的类型,以确保。
- 使用
:type
命令,确保放置括号。 作为对比,还需要
:type
通常的 Haskell Listcons
tructor(:)
的 —— 见左右反转?左边的项
(:#:)
是类型Command
。- 那么
com
等式中的变量 fort
必须是 typeCommand
; 这符合呼叫trace
的预期。
推荐阅读
- sql - 在大型 VBA/MS Access 项目中查找语法错误
- ruby - 对厨师语法感到困惑
- ibm-cloud - 如何从分析引擎上的 Apache Spark 读取和写入配置单元表
- python - 网页抓取;无法传递字典中的所有项目
- git - 试图在 vsts 中创建一个新的 repo 分支?
- python - 无法让计数器在 tweepy 中工作
- sql - 使用 NVL2 函数将 Oracle SQL 转换为 T-SQL 到 Case 语句
- laravel - 拉拉维尔。php artisan 显示返回 [];
- python-3.x - kv 根变量在 python 中不可访问
- typescript - How to understand syntax in TypeScript interface [key: string]