首页 文章

如何处理像Yesod这样的Haskell框架中的类型

提问于
浏览
3

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

特别是,我希望能够做到以下几点,但我目前还不知道如何做到这一点 .

  • 给出一个表达式,找出表达式的类型 . 通常我会使用GHCi这样的东西,但据我所知,如果我想这样做,我需要知道表达式的每个部分来自哪个包,我不知道该怎么做 . 我还希望能够检查从模板Haskell生成的HomeR等函数的类型 . 有没有办法使用GHCi来检查Yesod项目的.hs文件中出现的任意表达式的类型或者?

  • 沿着与上面相同的行,给定一个出现在Yesod项目中的某个.hs文件中的类型或类,得到它的定义?

  • 给定Yesod函数或类型,快速找到它的文档 . 我目前所做的是在Google上搜索给定的功能,但这有点烦人,因为第一个结果并不总是文档,有时它是旧版本 . 有没有一种快速查找Yesod文档的有效方法?

2 回答

  • 3

    你问过几个问题,所以我会尝试单独回答每个问题:

    (1)查找表达式的类型

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

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

    如果您使用像vim或emacs这样的编辑器,则可以为项目生成TAGS,然后使用编辑器基于TAGS的跳转到定义功能 . 要从GHCi为所有已加载的模块生成标记,可以使用以下命令之一

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

    如果要为整个项目生成标记,可以使用标记生成器,例如hasktags . 关于此,还有一个Haskell Wiki Page .

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

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

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

    你可以使用Hayoo . 它索引了大部分的hackage,我还没有't found any package which it doesn't索引(除了GHC API文档,但这不是hackage) . 或者,有Hoogle,它也能够搜索给定类型签名的函数,但它似乎不在它的索引中 .

  • 1

    你已经有了一些关于如何查找文档的好答案,所以我只想提一下处理混乱类型错误的小技巧 .

    我发现将错误的函数分解为许多小的函数是有帮助的,这些函数都是在顶层引入的 . 当问题仅仅是运算符优先级问题时,这可能会立即解决,但有时会出现更深层次的问题 .

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

    这里演示了一个更有原则的方法来让Haskell帮助您找到正确类型的子组件:http://matthew.brecknell.net/post/hole-driven-haskell/

相关问题