90%的HLS启动失败、类型提示缺失、F5调试报错,是因VSCode未正确找到haskell-language-server:它不识别wrapper、不自动fallback到.ghcup/bin,需手动配置serverExecutablePath为绝对路径,并确保项目根目录含.cabal或stack.yaml且已构建。

HLS 启动失败、类型提示不出现、F5 调试报错——90% 是因为 VSCode 没正确找到 haskell-language-server,而不是插件没装或代码写错了。
为什么 haskell-language-server 找不到或启动失败
VSCode 的 Haskell 插件默认会尝试在 PATH 中找 haskell-language-server,但它不认 haskell-language-server-wrapper,也不自动 fallback 到 .ghcup/bin/ 下的可执行文件(哪怕 ghcup install hls 已成功运行)。
常见错误现象包括:
- 状态栏一直显示 “Starting Haskell language server…” 卡住
- 输出面板中
Haskell日志里反复出现spawn ENOENT或command not found - 悬停函数无类型,
Ctrl+Click跳转失效,putStrLn下有红色波浪线但实际能编译
根本原因不是 HLS 没装,而是 VSCode 没“看见”它。解决方式非常直接:
- 运行
which haskell-language-server(macOS/Linux)或Get-Command haskell-language-server(PowerShell)确认路径 - 在 VSCode 设置中搜索
haskell.serverExecutablePath,填入完整绝对路径,例如:/home/username/.ghcup/bin/haskell-language-server或C:/ghcup/bin/haskell-language-server.exe - 不要填
haskell-language-server-wrapper—— 它只是个调度器,VSCode 不支持 - 重启 VSCode 窗口(不是重载窗口),否则设置不生效
项目根目录必须含 .cabal 或 stack.yaml
HLS 不是全局语言服务器,它按项目启动,且只在识别出 Haskell 项目结构时才加载。空文件夹、只有 Main.hs、或放错位置的配置文件都会导致 HLS 静默退出。
典型误操作:
- 用
code .打开的是src/子目录,而非项目根目录 -
cabal init -n生成的.cabal文件被手动删掉或改名 - 用了 Stack 但没运行过
stack build,stack.yaml存在但.stack-work/为空
验证是否识别成功:右下角状态栏出现 HLS ready;打开 src/Lib.hs 后,输出面板 Haskell 标签页应有类似 Run entered for haskell-language-server... 的日志行。
ghcup 安装后 PATH 没生效怎么办
尤其是 Windows 和 macOS 新终端,默认不会自动 source ghcup 写入的 shell 配置(如 ~/.ghcup/env)。结果就是终端里能跑 haskell-language-server --version,但 VSCode 启动的子进程找不到命令。
快速判断方法:在 VSCode 集成终端中执行 echo $PATH(Linux/macOS)或 $env:PATH(PowerShell),看输出里有没有 .ghcup/bin 路径。
修复步骤:
- macOS/Linux:检查
~/.bashrc或~/.zshrc是否包含source ~/.ghcup/env;没有就加上,然后source ~/.zshrc - Windows PowerShell:把
C:/ghcup/bin(或你安装的实际路径)加到系统环境变量PATH中,或在 VSCode 设置里直接填绝对路径(更稳妥) - VSCode 用户级设置中启用
terminal.integrated.env.相关选项来注入 PATH(不推荐,易冲突)
调试时 launch.json 配置要点
F5 启动调试失败,多数是因为没指定正确的可执行入口或 GHCi 加载方式。VSCode 的 Haskell 插件不支持直接调试 Main.hs,必须通过构建产物启动。
最小可用配置(放在项目根目录 .vscode/launch.json):
{
"version": "0.2.0",
"configurations": [
{
"type": "haskell",
"request": "launch",
"name": "Launch Main",
"executable": "hello-haskell-exe", // ← 必须与 .cabal 文件中 executable 名字一致
"cwd": "${workspaceFolder}"
}
]
}
注意:
-
executable值不是文件名,而是.cabal里executable段的name:字段值(如name: hello-haskell-exe) - 首次调试前需先运行
cabal build或stack build,确保可执行文件已生成 - 若用
cabal run能跑通但 F5 报错,大概率是名字没对上,去.cabal文件里核对
最常被忽略的一点:HLS 和调试器是两个独立进程,haskell-language-server 配好了,不代表 launch.json 就自动有效——它完全不读 HLS 配置,只依赖 .cabal 结构和构建产物是否存在。



















