3

我对 Haskell 比较陌生,并试图通过使用 Yesod 框架构建网站来获得一些经验。我现在面临的最大困难是我经常不确定一个函数需要什么类型,或者另一个函数返回什么类型。我也很难解释我犯错时产生的类型错误。

特别是,我希望能够做以下事情,但我目前不知道做这些事情的好方法。

  • 给定一个表达式,找出表达式的类型。通常我会使用 GHCi 来做这样的事情,但据我所知,如果我想这样做,我需要知道表达式的每个部分来自哪个包,我不知道该怎么做。我还希望能够检查从模板 Haskell 生成的函数的类型,例如 HomeR。有没有办法使用 GHCi 检查出现在 Yesod 项目的 .hs 文件中的任意表达式的类型或求值?
  • 与上述相同,给定出现在 Yesod 项目的某个 .hs 文件中的类型或类,得到它的定义吗?
  • 给定一个 Yesod 函数或类型,快速找到它的文档。我目前所做的是在谷歌上搜索给定的函数,但这有点烦人,因为第一个结果并不总是文档,有时它是旧版本的。有没有一种快速查找 Yesod 文档的有效方法?
4

2 回答 2

3

您问了几个问题,所以我将尝试分别回答每个问题:

(1) 查找表达式的类型

你不需要知道包名,只需要知道模块名。如果只使用 Yesod 函数,import Yesod在 GHCi 提示符下会导入它的大部分函数。除此之外,您必须使用 (3) 来查找并导入表达式所需的所有模块。

(2) 获取项目中定义的符号定义

如果你使用 vim 或 emacs 之类的编辑器,你可以为你的项目生成 TAGS,然后使用编辑器基于 TAGS 的跳转到定义功能。要为从 GHCi 加载的所有模块生成标签,可以使用以下命令之一

:ctags  -- ctags for vim
:etags  -- etags for emacs

如果要为整个项目生成标签,可以使用标签生成器,例如hasktags。还有一个关于此的Haskell Wiki 页面。

如果您有在 GHCi 中加载了定义的模块,您还可以使用 :i 符号来查找其定义的位置:

Prelude> :i maybe
maybe :: b -> (a -> b) -> Maybe a -> b  -- Defined in `Data.Maybe'

(3) 查找 hackage 包中定义的符号的文档

您可以使用Hayoo。它索引了大部分 hackage,我还没有找到任何它没有索引的包(除了 GHC API 文档,但这不是关于 hackage)。或者,Hoogle也能够搜索给定类型签名的函数,但它不会索引所有黑客攻击。特别是,Yesod 似乎不在它的索引中。

于 2013-08-19T09:32:40.160 回答
1

关于如何查找文档,您已经有了一些很好的答案,所以我只提一个关于处理令人困惑的类型错误的小技巧。

我发现将我不正确的函数分解成许多小函数很有帮助,这些函数都在顶层引入。当问题仅仅是算子优先级问题时,这可能会立即解决,但有时会出现更深层次的问题。

然后,您可以删除损坏函数上的类型注释,将其定义更改为undefined,并将其加载到 ghci 中。这通常允许 ghci 为您的组件函数推断出正确的类型,并且您可以使用 :t 找到该类型。为简单的子组件函数拥有正确的类型通常会直接导致正确的实现,之后您可以根据需要替换类型注释和/或重新组合事物。

此处演示了让 Haskell 帮助您找到正确类型的子组件的更原则性方法:http: //matthew.brecknell.net/post/hole-driven-haskell/

于 2013-08-19T17:40:46.413 回答