在 Haskell 中查找函数源(工作流)

Find function source in Haskell (workflow)

我正在学习 Haskell 一段时间,所以我决定检查一些流行的项目以了解它在现实中的样子,并可能对过程进行逆向工程。

我选择 Hakyll 是因为它能做一些我熟悉的事情并且比较复杂。然后我立即陷入了这个问题:如何回溯导入?

比如说,在 JavaScript 中,每个导入都是显式的。

let Q = require("Q")         // namespace
let {foo} = require("Q/foo") // value

Haskell 默认为

import Q 

它一下子破坏了一切,人们似乎真的在滥用它。

现在我查看 tutorial,然后查看源代码,意识到我不知道一个或另一个函数位于何处,除了搜索之外不知道如何发现它。

是否有一些技巧可以发现这种信息,例如出现会显示源文件或其他内容的语法错误?您如何在工作流程中解决此类任务?

一些不需要可编译代码的选项:

我推荐 Stackage 的 hoogle,因为它的数据库加载了所有 Stackage。

如果你有工作代码:

  • 在 ghci
  • 中使用 :i 命令
  • 通过编辑器或命令行使用 ghc-mod

作为最后两个选项的示例,假设您有一个 module Foo.hs,如下所示:

module Foo where
import Data.Maybe
...

使用ghci

$ ghci Foo.hs
GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Foo              ( Foo.hs, interpreted )
Ok, modules loaded: Foo.
*Foo> :i catMaybes
catMaybes :: [Maybe a] -> [a]   -- Defined in ‘Data.Maybe’
*Foo>

使用ghc-mod

$ ghc-mod info Foo.hs catMaybes
catMaybes :: [Maybe a] -> [a]   -- Defined in ‘Data.Maybe’
$

如果你使用Intero for Emacs,它支持M-.的标准"go to definition"快捷方式。

其他 Intero 前端可能也使用其编辑器的标准 UI 来实现此功能;我知道已经有一个 NeoVim frontend

如果您想要 vim 中的这种 Haskell 代码浏览支持,您可以尝试 Stephen Diehl 的精彩教程 Vim and Haskell in 2016

Haskell 有多种编辑环境,可让您查询 GHC 编译器以获取有关代码的信息。比如我使用vim-hdevtools,我可以打开vim中的文件hakyll/src/Hakyll/Main.hs,将光标移动到Commands.build符号上,输入命令:HdevtoolsInfo,然后GHC会告诉我符号的类型和定义的位置,并给我跳转到定义的选项。

Commands.build ::
  Config.Configuration -> Logger.Logger -> Rules a -> IO ExitCode
        -- Defined at hackyll/src/Hakyll/Commands.hs:48:1

不过,我承认我确实花了很多时间getting vim-hdevtools to work