2019 年年中对 Haskell 的一个有倾向性的初学者指南

这是一份面向 Haskell 初学者或有其他类似语言经验并希望学习 Haskell 的人的指南。

  • 关键原则:基于流行度和简单性做决策,熟练后可大胆选择库和语言扩展,深入后也可退回以更好理解代码。
  • 学习

    • 不同人学习方式不同,新接触函数式编程可参考[CIS 194 Spring 2013]课程,有一定经验可做小项目,[Haskell Programming from First Principles](haskellbook)、[Real World Haskell]较适合,[Programming in Haskell]练习题多,[Learn you a Haskell for great good!]趣味性强但不实用,还可关注[Oskar Wickstrom 的 Haskell at Work]频道,关键是多练习写 Haskell 代码。
    • 遇到困难可提问,要告知对方经验水平,可在[r/haskell]、功能编程聊天群、Twitter 等提问,也可参考相关提问指南,个人偏好使用[r/haskellquestions]和 StackOverflow 答案。
  • 设置

    • 操作系统:通常无选择灵活性,多数 Haskellers 使用 Linux,其次是 macOS 和 Windows,优先使用更流行的平台以便获得更多帮助。
    • 构建工具:非 trivial 项目需使用构建工具,推荐使用stackcabal v2-build,不建议使用nix,OGH18 的“Build tools and …”部分对stack有很好的介绍。
    • 编辑器支持:不同编辑器对 Haskell 的支持程度不同,基于intero的工具插件工作较可靠,可尝试使用intero插件。
    • ghci - 交互式解释器:Haskell 安装自带ghci,可用于获取表达式类型、设置多行输入等,使用stack ghci可加载包中的所有模块。
    • hoogle:Haskell 专用搜索引擎,可按名称或类型搜索函数等,可设置本地使用或创建浏览器快捷方式,DuckDuckGo 已有相关快捷方式。
    • hlint:优秀的代码检查工具,能提供代码改进建议,像有资深 Haskeller 在旁帮助。
    • 在线编译器:如[repl.it]可用于分享代码,方便他人帮助。
    • 设置 CI:使用stack可参考文档设置 Travis CI,[summoner]和[packcheck]可提供更灵活的 CI 配置,CircleCI 也有相关 orb,Gitlab CI 也是不错的选择。
    • 可参考[Aelve guide]和[State of the Haskell ecosystem]获取库推荐,使用[packdeps]查看库的依赖关系,选择文档良好的库,避免依赖老旧博客或 StackOverflow 答案,有疑问可询问。
    • 不要使用自定义 Prelude,坚持使用base标准库中的默认 Prelude。
  • 代码

    • 应用架构:根据经验,不同语言的应用架构在 Haskell 中可能不适用,可向他人寻求特定问题的帮助。
    • 纯函数:纯函数很重要,初学者尽量使大部分代码依赖纯函数,可向他人请教方法。
    • 部分函数:尽量避免编写部分函数,若必须使用,应添加注释说明原因,对于 IO 相关函数要格外小心处理可能的错误。
    • 使用记录:Haskell 的内置记录在中小规模应用中可用,若有字段名重复问题可添加前缀,可使用microlens库,避免使用DuplicateRecordFields扩展。
    • 错误处理

      • :为函数定义合适的自定义错误 ADTs,返回Either MyError [..]表示可能的失败,通常不偏离此原则,特殊情况可使用Maybe
      • 应用:错误处理策略取决于应用架构,可默认使用Either,若需聚合错误可使用Either [MyError]Validation数据类型,也可自己定义类似数据类型。
    • 测试:[hspec]适合编写和组织测试,若感兴趣可使用[hedgehog]进行属性测试,还可使用[doctest]进行文档测试。
    • 抽象:避免过度抽象,初学者应先学习写好“无聊”的代码,好的代码是能编译且理解原因的代码。
  • 调试

    • 打印调试:可使用[Debug.Trace]模块进行快速打印调试,调试完成后删除导入。
    • 使用调试器ghci有调试器,但未实际使用无法评价。
    • 性能分析:GHC 优化较好,一般初学者/中级项目不会有执行速度问题,若有可使用 GHC 的内置仪器性能分析生成报告,可使用[flamegraph]和[ghc-prof-aeson-flamegraph]转换和展示报告,还可使用[profiteur]和[profiterole]探索性能分析结果。
  • 仍有疑虑:Haskell 有众多语言扩展是为了实验,大多不影响日常工作,可参考 OGH18 的 34 个默认扩展,遇到 monomorphism restriction 可在 StackOverflow 上找到解决方案。
  • 结束语:有疑问可寻求帮助,开心学习 Haskell。
  • 感谢:感谢 /u/TracyChavez 的评论促使撰写此帖。
阅读 11
0 条评论