这里提出了一个类似的问题,但已经有十多年了,我希望在此期间已经取得了一些进展,现在可以产生不同的答案。
现在我正在使用 VSCode 并安装了“Haskell GHCi 调试适配器 Phoityne”。它可以工作,但由于 Haskell 的惰性(以及纯代码和 IO 代码的分离以及 Haskell 的函数性质),调试代码仍然很困难。
似乎已经提出了针对此类问题的一些解决方案。例如,我发现这篇文章比较了 Haskell 中的调试技术,并命名了几个试图通过引入函数“观察”来改善体验的包。除此之外,Hood、Hoed和Hat 都被命名了,我还在hackage 上发现了debug 。
然而,不幸的是,我没有让它们中的任何一个工作。FPretty安装 Hood 时,我收到错误消息,指出它具有与较新版本的基础包不兼容的依赖项(自 2018 年以来,这已作为问题提交)。霍德也面临同样的问题。安装 Hat 时,我遇到了很多错误,首先是抱怨缺少模块,然后在解释程序时调试崩溃。
结果,我无法测试其中任何一个。然而,我真正想要的是一个图形调试器(最好是 VSCode 中已实现的调试器的改进版本!),它跳转到正在检查的源代码行,然后显示一个小窗口,逐步展开递归(或者无需评估,或者更好的是,在递归完成后(即在实际评估之前)提供一些逐步评估的选项),类似于此 wiki 文章中如何显示foldr 的效果。
上述软件包之一可以执行此操作吗?对于 Haskell 社区来说,为 VSCode 提供这样的功能来改善生态系统并吸引新人不是很好吗?或者这已经可能了,但我只是不知道如何正确配置 Phoityne?或者你有完全不同的方法来有效地调试 Haskell 吗?您的工作流程是什么?
在 Haskell 中寻找一个可以将任意深度嵌套列表展平的函数时,即一个concat递归应用并在最后一次迭代(使用非嵌套列表)时停止的函数,我注意到这需要有一个更灵活的类型系统,因为列表深度不同,输入类型也不同。事实上,有几个 stackoverflow 问题——比如这个问题——其中的回答指出“不存在一个函数可以‘查看’不同深度的不同嵌套列表”。
编辑:一些答案提供哈斯克尔的解决方法,无论是对自定义数据类型或具有帮助TypeFamilies或MultiParamTypeClasses(如在由Noughtmare下面的答案,或者通过“Landei”在回答上述职位或由“约翰·L”回答这个职位)。然而,这些家族和类似乎也是因为缺少/替代haskell 中的依赖类型而引入的(例如,haskell wiki声明“类型家族 [...] 很像依赖类型”。
我现在的问题是,如果这是真的,哈斯克尔的确originially没有定义此类功能(即如扁平化不同深度的列表),而且,如果这些问题就会消失,一旦一个移动到语言实现由依赖类型?(例如 Idris、Agda、Coq 等)我没有使用这些语言的经验,这就是我问的原因。
例如,在 Idris 网站上,据说“类型可以作为参数传递给函数”,因此,我认为,在列表扁平化的情况下,可以简单地将列表的类型作为参数传递并实现以直接的方式获得所需的功能。这可能吗?
一个后续问题也将是:在haskell 中解决这个问题的那些族和类是否在haskell 中提供了依赖类型理论的完整实现,或者如果没有,有什么重要区别?