如何使用 PureScript 进行调试?

如何解决如何使用 PureScript 进行调试?

问题

以下是一个最小的、人为的例子:

read :: FilePath -> Aff String
read f = do
  log ("File: " <> f) -- (1)
  readTextFile UTF8 f -- (2)

我想在 (1) 上的潜在错误发生之前在 (2) 中进行一些调试日志记录。到目前为止,在 Spago REPL 中执行以下代码适用于成功案例:

$ spago repl
> launchAff_ $ read "test/data/tree/root.txt"
File: test/data/tree/root.txt
unit

问题:如果 (2) 有错误 - file is directory here - ,(1) 似乎根本没有执行:

$ spago repl
> launchAff_ $ read "test/data/tree"
~/purescript-book/exercises/chapter9/.psci_modules/node_modules/Effect.Aff/foreign.js:532
                throw util.fromLeft(step);
                ^

[Error: EISDIR: illegal operation on a directory,read] {
  errno: -21,code: 'EISDIR',syscall: 'read'
}

原始问题更复杂,包括多层递归(请参阅 E-Book exercise 3),我需要在其中记录以调试上述错误。

问题

  1. 我如何正确记录这里即将发生的错误?
  2. (可选)是否有更复杂、完善的调试替代方案 - purescript-debugger?一个专门的 VS Code 调试扩展/功能将是锦上添花。

解决方法

首先,您观察到的症状并不意味着第一行没有执行。它确实总是执行,由于控制台在 PureScript REPL 中的工作方式,您只是看不到它的输出。输出被吞了。遗憾的是,这不是 REPL 的唯一问题。

您可以通过将 log 替换为 throwError 并观察错误总是被抛出来验证第一行总是被执行。或者,您可以让第一行修改可变单元格而不是写入控制台,然后检查单元格的内容。

最后,这只发生在 REPL 中。如果您将 launchAff_ 调用放入 main 并运行该程序,您将始终获得控制台输出。


现在是手头的实际问题:如何调试跟踪。

如果您负担得起,登录到控制台是可以的,但还有一种更优雅的方式:Debug.Trace.trace

这个函数有一个隐藏的效果——即它的类型说它是纯的,但它在调用时确实产生了效果。这个小谎言让您可以在纯设置中使用 trace,从而调试纯代码。不需要Effect!只要只用于调试就可以,但不要放在生产代码中。

它的工作方式是它需要两个参数:第一个被打印到控制台,第二个是打印后要调用的函数,整个过程的结果是该函数返回的任何内容。例如:

calculateSomething :: Int -> Int -> Int
calculateSomething x y =
    trace ("x = " <> show x) \_ ->
        x + y

main :: Effect Unit
main =
  log $ show $ calculateSomething 37 5

>  npx spago run       
'x = 37'               
42                     

第一个参数可以是任何东西,而不仅仅是一个字符串。这让您可以轻松打印大量内容:

calculateSomething :: Int -> Int -> Int
calculateSomething x y =
    trace { x,y } \_ ->
        x + y

>  npx spago run
{ x: 37,y: 5 }
42

或者,将其应用于您的代码:

read :: FilePath -> Aff String
read f = trace ("File: " <> f) \_ -> do
  readTextFile UTF8 f

但这里有一个微妙的细节:只要您调用 read,这种跟踪就会发生,即使结果 Aff 永远不会实际执行。如果您需要在有效执行时进行跟踪,则需要将 trace 调用作为操作的一部分,并注意不要使其成为序列中的第一个操作:

read :: FilePath -> Aff String
read f = do
  pure unit
  trace ("File: " <> f) \_ -> pure unit
  readTextFile UTF8 f

当然,每次需要在有效上下文中进行跟踪时都这样做有点不方便,因此有一个特殊的函数可以为您执行此操作 - 它称为 traceM

read :: FilePath -> Aff String
read f = do
  traceM ("File: " <> f)
  readTextFile UTF8 f

如果您查看它的 source code,您会发现它与我在上面的示例中所做的完全一样。


可悲的是,当发生异常时,trace 不会在 REPL 中帮助您,因为它仍在打印到控制台,因此它仍然会因同样的原因被吞下。

但是即使没有被吞下,输出也有点乱,因为trace实际上是彩色输出的(帮助你在其他输出中分辨出来),而PureScript REPL与颜色:

> calculateSomething 37 5
←[32m'x = 37'←[39m
42
,

除了 Fyodor Soikin's great answer 之外,我还发现了一个使用 VS Code 调试视图的变体。

1.) 确保build with sourcemaps

spago build --purs-args "-g sourcemaps"

2.) 向 VS Code launch.json 添加调试配置:

{
  "version": "0.2.0","configurations": [
    {
      "type": "pwa-node","request": "launch","name": "Launch Program","skipFiles": ["<node_internals>/**"],"runtimeArgs": ["-e","require('./output/Main/index.js').main()"],"smartStep": true // skips files without (valid) source map
    }
  ]
}

"./output/Main/index.js" / .main() 替换为编译后的 .js 文件/要调试的函数。

3.) 设置断点并通过源映射支持逐步执行 .purs 文件。

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res