在 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。
我正在学习 Haskell 一段时间,所以我决定检查一些流行的项目以了解它在现实中的样子,并可能对过程进行逆向工程。
我选择 Hakyll 是因为它能做一些我熟悉的事情并且比较复杂。然后我立即陷入了这个问题:如何回溯导入?
比如说,在 JavaScript 中,每个导入都是显式的。
let Q = require("Q") // namespace
let {foo} = require("Q/foo") // value
Haskell 默认为
import Q
它一下子破坏了一切,人们似乎真的在滥用它。
现在我查看 tutorial,然后查看源代码,意识到我不知道一个或另一个函数位于何处,除了搜索之外不知道如何发现它。
是否有一些技巧可以发现这种信息,例如出现会显示源文件或其他内容的语法错误?您如何在工作流程中解决此类任务?
一些不需要可编译代码的选项:
我推荐 Stackage 的 hoogle,因为它的数据库加载了所有 Stackage。
如果你有工作代码:
- 在 ghci 中使用
- 通过编辑器或命令行使用 ghc-mod
:i
命令
作为最后两个选项的示例,假设您有一个 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。