# 如何安装 Haskell 工具链? **Published by:** [MirrorPoster](https://paragraph.com/@mirrorposter/) **Published on:** 2022-05-01 **URL:** https://paragraph.com/@mirrorposter/haskell ## Content 本文介绍如何在类 UNIX 系统上(Linux、MacOS、FreeBSD)从零开始一步步安装 Haskell 工具链(编译器、构建工具、编辑器),特别是考虑到国内特殊网络环境,会介绍如何使用国内源。注意:在 2023 年的今天,Cabal 已经取得了长足进步,因此本文将完全不涉及 Stack。如果你使用 Windows,好消息是 Haskell 工具链完整支持 Windows,但超出本文范围之外。尽管如此,本文仍然适用于 WSL。目前国内只有上海交大和中科大有 Haskell 工具链的完整镜像(GHCup、Hackage、Stackage)。本文采用中科大镜像,你可以手动修改命令来使用其他镜像。本文的目标读者是对 Haskell 没有任何了解的初学者。安装 GHCup、GHC 和其他工具GHCup 是一个 Haskell 工具链的版本管理器。简单来说,它可用于安装不同版本的 GHC、Cabal、HLS 等工具。准备工作GHCup 是一个近期出现的工具,因此国内目前只有中科大和上海交大有镜像。在安装 GHCup 之前,我们要做一件额外的工作,创建 ~/.cabal 目录,并创建 ~/.cabal/config 文件,填入如下内容:repository mirrors.ustc.edu.cn url: https://mirrors.ustc.edu.cn/hackage/ secure: True 这是因为 GHCup 在安装 Cabal 时会进行初始化(会下载一个 100MB 的文件),但此时我们还没有替换 Hackage 源!这一步首先替换 Hackage 源。之后安装过程就会如丝般顺滑。执行安装在终端中运行如下命令:curl --proto '=https' --tlsv1.2 -sSf https://mirrors.ustc.edu.cn/ghcup/sh/bootstrap-haskell | BOOTSTRAP_HASKELL_YAML=https://mirrors.ustc.edu.cn/ghcup/ghcup-metadata/ghcup-0.0.7.yaml sh (是的,一行。) 很快,你会看到如下界面:ghcup 安装脚本**安装过程请仔细阅读所有提示。**针对三个问题,下面是我的推荐:**是否将 ghcup 目录加入 PATH?**直接回车接受默认值,如果你在看这篇文章,说明你一定会用到。**是否安装 Haskell Language Server?**安装与否均可,之后想装也很容易。这里输入 Y 安装(你大概是希望使用更高级的 IDE 功能的)。**是否安装 Stack?**输入 N,不安装。之后一路回车,GHCup 将下载安装推荐版本的 GHC 和 Cabal,并完成初始化。(截至本文写作时,GHC 版本是 8.10.7)。结束后,你会看到一大片提示,请仔细阅读所有输出。这里必做的事情是设置当前 shell 的 PATH (或者重启一下 shell 也行):source ~/.ghcup/env 测试安装搞定!你已经可以用起来 Haskell 了。$ ghc --version The Glorious Glasgow Haskell Compilation System, version 8.10.7 $ cabal --version cabal-install version 3.6.2.0 compiled using version 3.6.2.0 of the Cabal library $ ghci GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help Prelude> putStrLn "Hello, Haskell!" Hello, Haskell! Prelude> Leaving GHCi. 配置 GHCup 源我们上面用了环境变量临时修改了 GHCup 元数据地址,这里我们把镜像写到配置里让国内源永久生效。修改 ~/.ghcup/config.yaml(如不存在就创建),添加如下内容:url-source: OwnSource: https://mirrors.ustc.edu.cn/ghcup/ghcup-metadata/ghcup-0.0.7.yaml GHCup 的用法ghcup 有一个很好用的命令叫 tui,所有 ghcup 的操作均可以从这里完成,运行 ghcup tui 会显示如下界面。ghcup tui其中打双对勾的是当前选中版本。比如你安装了 GHC 9.2.1 和 GHC 8.10.7 两个版本,但是目前选中的是 8.10.7,那么运行 ghc 命令会调用 8.10.7 版本而非 9.2.1 版本。你可以安装多个版本,但一次只能选中一个版本(用 s 键选中别的版本)。好了,剩下的命令都顾名思义,自己试试即可。 如果想安装 HLS 的话,随时可以从这里安装。配置编辑器本文的重点不是配置编辑器,下面只给出一些提示。请参阅其他资料(尤其是相应插件自己的文档)了解如何配置、如何使用。Visual Studio CodeVisual Studio Code 是目前最流行的代码编辑器之一,Haskell 语言服务器则为 LSP 提供了较好的支持,两者相得益彰。只需在扩展市场中搜索名为 Haskell 的扩展并安装即可。 之后,任意打开一个 .hs 文件,Visual Studio Code 就会自动调用 GHCup 已经安装的 HLS,可以充分体验 Haskell 的 IDE 编辑体验了!(如果 VSCode 提示你要下载 HLS,请下转故障排除章节。) 恭喜,至此你已经完成配置了 2023 年最先进的 Haskell 工具链+编辑环境!尽情享受吧!EmacsEmacs 默认没有 Haskell 代码高亮,但可以安装 haskell-mode。它的功能非常丰富,推荐阅读其文档。比如一个很有用的命令是 haskell-process-load-or-reload ,可以用来快速打开一个 ghci 并载入当前文件。 如果想要使用 HLS:先手动通过 ghcup 安装 HLS。再安装 lsp-mode、lsp-haskell。That’s all!Vim 和 Neovimvim 原生支持 Haskell 的代码高亮。要与 HLS 集成,可使用 coc.nvim。Cabal 应急生存手册使用 Haskell 时,强烈建议首先创建一个项目。这是因为 Cabal 让使用第三方库非常方便。Cabal 有一个不错的使用指南,值得收藏: https://cabal.readthedocs.io/en/3.6/创建项目$ mkdir my-first-haskell-project $ cd my-first-haskell-project $ cabal init # 在当前目录下初始化一个 Cabal 项目 Guessing dependencies... Generating LICENSE... Warning: unknown license type, you must put a copy in LICENSE yourself. Generating CHANGELOG.md... Generating app/Main.hs... Generating my-first-haskell-project.cabal... Warning: no synopsis given. You should edit the .cabal file and add one. You may want to edit the .cabal file and add a Description field. $ tree . . ├── CHANGELOG.md ├── app │ └── Main.hs └── my-first-haskell-project.cabal 1 directory, 3 files 可以看到,Cabal 创建了 3 个文件。其中 CHANGELOG.md 是用来记录版本更新内容的,对初学者来说不用关心。增加第三方依赖打开 .cabal 文件,除去基本的项目信息外,有一个 executable 段落:executable my-first-haskell-project main-is: Main.hs -- 入口文件名 build-depends: base ^>=4.14.3.0 -- 依赖 hs-source-dirs: app -- 代码目录 default-language: Haskell2010 -- 默认语言 其中, ^>= 对 base (Haskell 标准库) 的版本增加了限制。对学习者来说,可以忽视这些限制(直接去掉版本限制)。下面我们增加 time 这个库为一个依赖:executable my-first-haskell-project main-is: Main.hs build-depends: base, time -- 这里添加了 time 库 hs-source-dirs: app default-language: Haskell2010 然后,就可以在代码文件 app/Main.hs 中使用了:module Main where import Data.Time.LocalTime -- 来自 time 库 main :: IO () main = do now <- getZonedTime print now (补充说明:Cabal 在编译时会自动求解一套互相兼容的包的版本,因此不写版本限制对学习者来说最方便,出问题的概率小了很多。但同时要注意这是不好的开发实践,在发布软件时最好先使用 cabal gen-bounds 命令生成兼容的版本范围。尽管不写版本范围让可行解的范围大了不少,但仍然有可能出现不兼容问题——会输出大量令人生畏的报错信息——这多数情况是因为你的某个依赖实在是太旧了,最好换一个新的同类包。)编译、运行和 REPL$ cabal build # 编译 [一大堆输出] [1 of 1] Compiling Main [一堆输出] Linking ..../my-first-haskell-project $ cabal run # 运行 [cabal run 会自动调用 cabal build,所以这里可能是 Up to date 也可能是和 cabal build 一样的一大堆输出] 2022-01-11 01:38:32.87706 CST $ cabal repl [一大堆输出] *Main> # ghci,但自动载入 Main 模块,并且可以自由用任何第三方依赖里的模块 Cabal 在编译时会自动从 Hackage 上下载并构建第三方依赖。因此你可以自由地在 Hackage 上找自己感兴趣的包,然后加到项目依赖里来实验。比如下面这些好玩的包,可以试试看!gloss, 2D 图形库。reanimate, 类似 manim 的动画库。首页有很多酷炫例子。gi-gtk-declarative, GUI 库。inline-r, 与 R 语言无缝协作。Chart, 绘制 2D 图表。accelerate, 硬件加速的数组运算库,可以编译到 GPU 上运行!ad, 自动微分。等等等等……Hackage 上有很多有趣的包,现在都是你的了。故障排除如何彻底卸载?如何彻底重新安装?rm -rf ~/.cabal ~/.ghcup ~/.ghc VSCode 提示我要下载 HLS,但我在 GHCup 那里已经下载过了?有如下原因:你没有使用 GHCup 安装 HLS。现在去安装一下?如果还不行,再看下面的。你没有添加 GHCup 的路径到 PATH 中。如果始终不行,参考下面的配置。在 Haskell 扩展页面,点击页面上的小齿轮打开扩展配置。找到 “Haskell: Server Executable Path” 配置项。输入 ~/.ghcup/bin/haskell-language-server-wrapper 。重启 VSCode。这时候重新打开文件应该就可以正确调用到 GHCup 安装的 HLS 上了。编辑器提示我 HLS 启动失败,怎么回事?最可能的原因是你启用了 HLS 目前不支持的新版本 GHC。如果想使用 HLS,请务必在 ghcup tui 中选中一个有 hls-powered 标记的 GHC 版本(比如 9.0.1, 8.10.7 等)。其他环境错误Mac 上安装时,若报错信息中有 configure 字样,是因为没有安装 Xcode Command Line Tools。如果步骤“执行安装”中运行命令后提示类似 curl: command not found,需要安装curl。Linux 下命令为:sudo apt install curl。在 Linux 下可能需要额外安装一些包。以 Linux Mint 20.3(同 Ubuntu 20.04)为例:执行sudo apt install build-essential libgmp-dev libncurses5-dev libncursesw5-dev 来安装 gcc、gmp 库、ncurses 库。其他发行版可参照之。修订记录2023-07-09: 少量格式和字句修正;「2022」更新到「2023」。2022-09-15: 将 ghcup metadata 版本升级至 0.0.7。 ## Publication Information - [MirrorPoster](https://paragraph.com/@mirrorposter/): Publication homepage - [All Posts](https://paragraph.com/@mirrorposter/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@mirrorposter): Subscribe to updates