前言

时隔半年再次开始学Haskell, 然后在配环境中度过了一个哭笑不得的下午…

Haskell环境是啥呢…?

按我不完全的理解, 主要有:

  1. 一个编译器, 比如ghc; 它还附带一个REPL叫ghci
  2. 一个包管理器兼项目管理器stack
  3. 一个提供后台语言分析支持的Language Engine, 比如Haskell-Ide-Engine(HIE)

然后呢还有一个东西叫cabal, 是一个历史遗留下来的包管理器, 有一套自己的包系统啊blabla的, 也没多大关系了…

stack和cabal的更多信息: Why is stack not cabal?. ANNOUNCING: first public beta of stack. What is the difference between Cabal and Stack?

本来呢, 目标是把上面三个, 最主要是第三个搞好; 但是由于我太菜了, 直到本文写好为止, 都…

WSL

如果配好了stack, 那剩下两个基本上就是水到渠成了.

第一反应当然是选择WSL配置!

sudo pacman -S stack

装完, 主要参考了这里, 配了一波stack.yaml, 然后开始折腾三, 照着这里的做法,

git clone https://github.com/haskell/haskell-ide-engine
cd haskell-ide-engine
stack install

然后报错:

Cabal file info not found for apply-refact-0.7.0.0, updating
Selected mirror https://s3.amazonaws.com/hackage.fpcomplete.com/
Downloading root
Waiting to acquire cache lock on $HOME/.stack/pantry/hackage/hackage-security-lock
fdLock: invalid argument (Invalid argument)

Google之后, 在这里发现这可能是WSL的一个bug, 并且看起来修不了…

然后我在Cabel的issue里发现了一种可能的解决方法: 在项目目录下的cabal.project做出如下修改:

constraints:
  lukko -ofd-locking

报错依旧, 可能这个方法只能修cabel-install. 由于我对Haskell的包管理体系还完全不熟悉, 所以不知道能不能把这个方法移植到stack上, 但这条路看起来是行不通了…

那万能的AUR呢?

Google后发现果然有直接有HIE的包.

然后熟练地输入

sudo pikaur -S haskell-ide-engine

熟练地得到报错:

Traceback (most recent call last):
  File "/usr/sbin/pikaur", line 9, in <module>
    main()
  File "/usr/lib/python3.8/site-packages/pikaur/main.py", line 401, in main
    create_dirs()
  File "/usr/lib/python3.8/site-packages/pikaur/main.py", line 373, in create_dirs
    raise Exception(result)
Exception: InteractiveSpawn returned 1:
STDOUT:


STDERR:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to create bus connection: Host is down

经过Google发现WSL基本上不可能折腾出systemd出来, 遂放弃, 转而去装了个yay

后来发现我还是太菜了. 按照装包的惯性, 我加了sudo, 但是pikaur默认是不想带着root权限跑(怕恶意aur), 所以它会试着派生出一个普通权限的进程, 而这时用到了systemd. 所以只要不加sudo, 它就完全可以正常地在WSL上运行…

然而我发现得太晚了…

装好yay之后, 尝试安装那个AUR, 发现它其实就是手动做法, 把源码下下来然后stack install

(o_ _)ノ

我换Windows版总行了吧…

下载win版安装, 然后stack setup, 报错:

...(一些OS相关信息)
(internalexception (handshakefailed (error_misc "network.socket.sendbuf: failed (no error)")))

我…迷惑…

啥玩意叫failed (no error)啊啊啊啊啊啊???

Google之后发现完全没有相关的结果, 大家都有error就我没有…遂怀疑是某堵墙的问题(因为它好像要从raw.githubcontent)那里下点什么东西

然后去找了一会才找到powershell怎么给命令挂代理(好像win10自带的全局代理不可以…), 本质上也是加环境变量:

$Env:http_proxy=http://127.0.0.1:1080
$Env:https_proxy=http://127.0.0.1:1080

然后再跑就没问题了… f**k GFW

这setup好像还顺路装了个msys2

好. 去HIE的目录下愉快地stack install吧!

然后编译到一半报错:

某个项目     > Registering library for 项目-版本..
terminateProcess: permission denied (Permission denied)

我有给管理员啊…而且Ctrl+C重来后还在不一样的地方报错; 还不是所有包都会报这个错…

无奈Google, 发现了一个神奇的方法(这里):

chcp 65001

把当前powershell代码页切换到UTF-8就好了…

什么鬼啊w(゚Д゚)w

然后又历经几次奇奇怪怪的报错, 多编译了几次, 总算把这200+的依赖编译完了, 一运行:

hie.exe: could not detect mingw toolchain

Boom!

气急败坏的我甚至跑去WSL里输了个hie.exe, 然后还是报错:

hie.exe: 当前目录: getDirectoryContents:findFirstFile: permission denied ()

过一天重启之后再次在powershell里运行, 报的错跟WSL里的一样了…

最后

发现了一个VSCode扩展Simple GHC (Haskell) Integration for VSCode, 只需要GHCi就可以运行就能提供的基本的补全, 对我这种轻度使用是完全ok了….

所以我是白折腾了..?