sublime text 本身不运行 haskell,所有功能依赖外部工具链;90% 配置失败源于 ghc、haskell-language-server 或 runhaskell 未正确加入 path,需手动注入环境变量、确保项目含 .cabal 或 hie.yaml、安装 lsp 及 lsp-haskell 插件,并完全重启编辑器。

Sublime Text 本身不提供 Haskell 运行能力,所谓“运行”就是调用系统已安装的 runhaskell 或 ghci;语法增强提示(如 hover 类型、跳转定义)则完全依赖 haskell-language-server(HLS)是否启动成功、路径是否被 Sublime 正确继承、项目配置是否完整——配不起来,90% 是环境变量没对上,不是插件装错了。
怎么让 Ctrl+B 直接跑单文件 Haskell 脚本
默认 Build System 对 .hs 文件无效,必须手动创建 Haskell.sublime-build。关键不是“写对 JSON”,而是命令和上下文要匹配真实使用场景:
-
"cmd": ["runhaskell", "$file"]最适合无模块依赖的脚本(比如含main = print "hello"的单文件),它不生成中间文件,改完即跑 - 别用
["ghc", "-e", "main", "$file"]:GHC 不支持直接 -e 执行模块,会报cannot find symbol main -
"working_dir": "$file_path"必须设,否则readFile "data.txt"这类相对路径会失败 - Windows 用户若遇到
'runhaskell' is not recognized,不是插件问题,是 Sublime 没继承系统 PATH——检查where runhaskell输出路径,再手动注入 Sublime 的Preferences.sublime-settings的env.PATH
为什么 hover 看不到完整类型签名(比如缺 forall 或约束)
HLS 默认开启类型美化(type pretty-printing),把 forall a. Eq a => a -> a -> Bool 折叠成 a -> a -> Bool,掩盖了多态和约束细节。这不是 bug,是设计选择,但函数式开发中你常需要原始签名来推理类型。
- 在项目根目录建
hls.yaml(HLS v2.1+ 支持),内容为:{"plugins": {"ghcide": {"typecheck": {"showFullTypes": true}}}} - 同时确保
hie.yaml存在且 cradle 配置正确,例如:cradle: direct: arguments: []
- 改完后必须执行
Ctrl+Shift+P→LSP: Restart Servers,仅重启 Sublime 不生效——HLS 进程绑定的是旧配置 - 如果仍不显示,检查 HLS 版本是否匹配 GHC:GHC 9.4.x 需 HLS 2.4.x,错一个 patch 版本就可能忽略
hls.yaml
Sublime 底部状态栏卡在 “Haskell: Starting…” 不变绿
这不是插件卡死,是 haskell-language-server 启动失败或未完成索引。LSP 插件只负责转发请求,它不处理解析逻辑——失败原因几乎全在外部工具链。
- 先确认终端能跑通:
haskell-language-server --version、ghc --version、which haskell-language-server——任一失败,Sublime 就不可能起来 - 项目根目录必须有
.cabal、package.yaml或hie.yaml,否则 HLS 启动时静默降级,状态栏也不报错 - macOS/Linux 用户:从 Dock 启动 Sublime 时,它不读 shell 的
PATH,import os; print(os.environ.get('PATH'))在 Sublime 控制台里看不到~/.ghcup/bin——必须手动在Preferences.sublime-settings中补全 - Windows 用户注意路径空格:如果项目路径含中文或空格(如
C:\My Projects\haskell-app),HLS 可能解析cabal.project失败,报Failed to parse result of calling cabal
最易被忽略的一点:HLS 启动后首次索引整个项目依赖树,可能耗时 20–60 秒,期间所有 hover、跳转都无响应。这不是配置问题,是 GHC 编译器本身的解析开销——别急着关掉重试,等右下角变成 “Haskell: Ready” 再操作。











