我从2014年开始发现这个guide并决定从Manjaro的存储库安装这些软件包.这很好用,直到我想在Emacs中使用haskell-mode.我对此进行了故障排除,发现它是一个包的问题(主要是Stack).
寻找解决方法,我找到了这个Reddit线程,它描述了安装Haskell(不是平台)的方法,以及软件包的问题.我按照其中一条评论进行了操作,最后用here所述的脚本安装了Stack(和GHC):
wget -qO- https://get.haskellstack.org/ | sh stack setup stack update
我的问题与此有关:
>这是2018年在Linux(Manjaro)上安装正常运行的Haskell(平台)的推荐方法吗?如果不是:这样做的方式是什么?
> Haskell平台包含:GHC,Cabal,Stack和一些包.安装了GHC和Stack,如何通过Stack安装Cabal?
>我需要Cabal(堆栈似乎有重叠的功能)?
>查看Haskell Platform的软件包,如上所述,通过安装Stack,我遗漏了什么?查看$HOME / .stack / programs / x86_64-linux / ghc-tinfo6-nopie-8.2.2 / lib / ghc-8.2.2这些似乎已经安装了很多.
解决方法
TL; DR:无论是Haskell平台还是纯粹的Stack安装都可以为您提供所需的一切,而且您不会通过选择其中任何一个来“遗漏”任何东西.您可能会发现使用“通用”Linux安装程序跳过Stack并安装Haskell平台最容易,因为它提供了您需要的所有内容,并且设置将更加符合LYAH书中描述的内容.当您在多个项目上进行更严肃的开发时,可以稍后安装Stack.如果您更喜欢坚持使用纯Stack安装,我建议您从“仅限全局项目”工作流程开始.无论哪种方式,您都可以使用“haskell-mode”以及下面建议的一些配置修复程序(包括如果您在仅限堆栈的安装的全局项目中工作将需要的密钥设置).
这是一个很长的答案……
Stack vs. Platform vs. Cabal
LYAH书预先列出Stack,这肯定是它没有提到它的主要原因.在haskell.org,他们建议使用最小安装程序,Stack或Haskell平台.在2018年,所有这三种方法都是完全合理的方法来建立一个有效的Haskell环境.他们选择将不同版本的编译器和/或库分离为开发工作的“沙箱”以及最初安装的数量方式各不相同,但是其中任何一个都无法“丢失”按需安装.根据您的选择,您的工作流程会有一些差异(见下文).
Stack和Cabal都是组合包管理器和构建工具. (Stack具有实际引导整个Haskell安装的附加功能,这就是为什么它本身也是一种安装方法.)当你在LYAH工作时,你实际上不会直接使用“构建工具”功能在你自己的项目上. (GHC的内置构建工具足以构建小型,多模块项目.)您只需要包管理器功能即可安装其他库.
由于Stack和Cabal分别管理它们的包,如果你正在使用Stack,你将没有特别需要直接使用Cabal.你可以根据需要安装它(实际上,Stack使用Cabal来实现一些深奥的功能,比如“堆栈求解器”,并且需要在这些情况下安装它):
$stack install cabal-install
但是,即使这会将“cabal”放入“$HOME / .local / bin”(并且你想确保它在你的路径中),你会发现你需要跳过箍来运行它:
$stack exec --no-ghc-package-path cabal -- list
就Stack环境而言,它并没有真正做任何有用的事情.
更新:关于“$HOME / .local / bin”路径的注释.如果没有现有安装,默认情况下,https://get.haskellstack.org/的安装脚本可能会默认将堆栈本身安装到/usr/local / bin / stack.但是,它应该显示一个警告,将$HOME / .local / bin放在您的路径中.如果您将来使用堆栈升级升级Stack,它将在那里安装新版本的堆栈,如果您安装包含二进制文件的软件包,也将使用该目录.例如,stack install hlint会将Haskell Lint程序hlint安装到该目录.所以,在/usr/local / bin之前将它放在你的路径和某个地方是个好主意.
什么是堆栈缺失
我认为这涵盖了你的前三个问题.对于你的最后一件事,你安装Stack而不是Haskell平台时遇到的主要问题是,根据设计,Stack并不真正安装除“堆栈”本身以外的任何其他东西.因此,所有Haskell工作包括运行Haskell解释器(“ghci”)或编译器(“ghc”),都需要在Stack环境中完成,或者使用特定的相应Stack命令:
$echo 'main = putStrLn "Hello,world!"' > Hello.hs $stack ghc -- Hello.hs [1 of 1] Compiling Main ( Hello.hs,Hello.o ) Linking Hello ... $./Hello Hello,world! $
或者使用“stack exec”在适当的Stack环境中运行通用程序.例如,在堆栈下运行Bash shell有时会很有帮助,之后事情就像全局安装的Haskell Platform环境一样:
$stack exec bash $ghci GHCi,version 8.2.2: http://www.haskell.org/ghc/ :? for help Prelude> :quit $ghc -O2 Hello.hs [1 of 1] Compiling Main ( Hello.hs,Hello.o ) [flags changed] Linking Hello ... $exit $ghc The program 'ghc' is currently not installed. ... $
您缺少的另一件事是默认情况下Haskell平台安装了一大堆公共库,而新的Stack环境几乎什么也没有(在运行堆栈设置之前,甚至没有编译器).在通过LYAH工作时,您可能会发现需要定期安装其他库.例如,在“输入和输出”一章中,使用随机数的示例(模块System.Random)将要求您运行:
$stack install random
并重新启动您的口译员.
建议使用Haskell平台
因为Stack有点复杂而且您不需要在开始时提供它所提供的功能,所以您可能会发现在开始时Haskell平台更易于使用. (“通用”安装程序应该可以在您的发行版上正常工作.)它随附了所有内容,并且您使用它的方式将更加符合LYAH中描述的内容.与haskell模式一起,你应该有一个相当不错的Haskell环境.
一般来说,堆栈和Haskell平台并排安装应该没有问题(Haskell平台实际上包含Stack的事实证明了这一点). Stack将在“$HOME / .stack”子目录下单独维护所有内容,因此编译器或包之间不会有任何干扰.请注意,在此设置中,您将使用cabal来管理安装在平台端的软件包,并显然可以堆栈以管理堆栈端的软件包.
纯堆栈安装的初级工作流程
如果您想坚持使用纯Stack安装,我可能会在您开始时建议以下工作流程:
您将看到使用“stack new”或“stack init”创建的Stack项目的引用.在开始时避免使用这些,并坚持使用堆栈“全局项目”.这是在没有“stack.yaml”文件(直接或在父目录中)的目录中运行“stack”时将生效的隐式项目:
$cd $stack path --project-root /u/buhr/.stack/global-project $
当您在全局项目中工作时(即,不在stack.yaml文件下的某个位置),您可以使用以下命令调用解释器和编译器:
$stack exec ghci $stack ghc -- -O2 Hello.hs
并且他们都可以使用以下命令访问您安装的任何其他库(包):
$stack install random
更新:关于stack ghci和stack exec ghci之间差异的注释.前者旨在在本地项目的上下文中运行GHCi(即,在stack.yaml文件下工作).它传递一些额外的标志来隐藏全局安装的包,并自动从包中提供可用的模块.在全球项目中工作时,我认为除了堆栈ghci产生警告之外没有任何实际区别;无论你使用哪种,你都需要显式加载你自己的模块:load Whatever.hs.有关this Stack documentation page差异的更多信息,特别是在它试图解释差异的底部.
最终,您可以切换到使用Stack项目的工作流程.这将涉及使用stack new来创建一个新的Stack项目目录,使用堆栈设置将私有编译器版本安装/链接到该目录,然后修改项目的xxx.cabal文件(可能还有其stack.yaml文件)以指示哪个附加包是必需的,而不是使用堆栈安装.当你只是想开始编写代码时,这有点复杂.
您还可以看到Intero的参考,这是专为Stack设计的Emacs模式. Intero非常好,但在处理全局项目中的文件时效果不佳.它倾向于想要在目录“〜/ .stack / global-project”中启动解释器,这是非常没用的. (我使用Intero,但我已修补它在这方面表现得更好.)
配置Haskell模式(适用于平台或堆栈)
最好坚持使用“haskell-mode”,并在开始使用非全局项目时考虑Intero.我建议按照说明从MELPA安装“haskell-mode”,但是将以下内容添加到.emacs文件中,而不是文档中建议的内容:
(require 'haskell) ;; add capability to submit code to interpreter and mark errors (add-hook 'haskell-mode-hook 'interactive-haskell-mode) ;; add missing keybindings for navigating errors (define-key interactive-haskell-mode-map (kbd "M-n") 'haskell-goto-next-error) (define-key interactive-haskell-mode-map (kbd "M-p") 'haskell-goto-prev-error) (define-key interactive-haskell-mode-map (kbd "C-c M-p") 'haskell-goto-first-error) ;; merge this with your existing custom-set-variables (custom-set-variables ;; NOTE: include following line to work around haskell-mode ;; bug if using GHC >= 8.2.1. ;; See: https://github.com/haskell/haskell-mode/issues/1553 '(haskell-process-args-stack-ghci '("--ghci-options=-ferror-spans -fshow-loaded-modules" "--no-build" "--no-load")) ;; some options suggested in the haskell-mode documentation '(haskell-process-auto-import-loaded-modules t) '(haskell-process-log t) '(haskell-process-suggest-remove-import-lines t) ;; make sure "stack ghci" is used,even in the global project '(haskell-process-type 'stack-ghci))
我使用“haskell-mode-20171022.26”进行了纯粹的Stack安装测试,看起来效果很好.我可以在全局项目中加载新的Haskell文件,将其提交到带有“C-c C-l”的交互式会话,并使用“M-n”和“M-p”浏览源文件中突出显示的错误. (错误出现在迷你缓冲区中.)
如果您决定使用Haskell平台,我认为所有这些“haskell-mode”配置仍将适用,除非您应删除最后一个自定义行. (auto的默认haskell-process-type将选择合适的东西.)
希望有所帮助!