在 nix 上的 haskell 开发环境中使用 hoogle
Posted
技术标签:
【中文标题】在 nix 上的 haskell 开发环境中使用 hoogle【英文标题】:Using hoogle in a haskell development environment on nix 【发布时间】:2015-02-27 23:58:02 【问题描述】:我正在尝试在 Haskell 开发环境中使用 hoogle 就像O'Charles' wiki描述的那样:
为了使用hoogleLocal
,我已经像下面这样修改了shell.nix
,但它似乎没有为我安装hoogle 二进制文件。
let
pkgs = import <nixpkgs> ;
# I'm attempting to use hoogle here, but it is not working.
haskellPackages =
let callPackage = pkgs.lib.callPackageWith haskellPackages;
in pkgs.recurseIntoAttrs (pkgs.haskellPackages.override
extension = self: super:
thiscurrentpackage = self.callPackage ./. ;
hoogleLocal = pkgs.haskellPackages.hoogleLocal.override
packages = self.thiscurrentpackage;
;
;
);
in pkgs.myEnvFun
name = haskellPackages.thiscurrentpackage.name;
buildInputs = [
(haskellPackages.ghcWithPackages (hs: ([
hs.cabalInstall
hs.ghcMod
hs.yesodBin
# This doesn't appear to install the hoogle binary?
hs.hoogleLocal
] ++ hs.thiscurrentpackage.propagatedNativeBuildInputs)))
];
在生成的 shell 中,hoogle
二进制文件不可用。
如果我在buildInputs
中包含hs.hoogle
,则会安装hoogle
二进制文件,但它找不到数据库。以下是我尝试使用它时发生的情况。
$ nix-shell
......
$ hoogle Monad
Could not find some databases: default
Searching in:
.
/nix/store/91y9q2y5a2ws8xgcsx1gkhfagc0f2qz6-haskell-hoogle-ghc7.8.3-4.2.36-shared/share/x86_64-linux-ghc-7.8.3/hoogle-4.2.36/databases
There are no available databases, generate them with: hoogle data
$ hoogle data
hoogle: /nix/store/91y9q2y5a2ws8xgcsx1gkhfagc0f2qz6-haskell-hoogle-ghc7.8.3-4.2.36-shared/share/x86_64-linux-ghc-7.8.3/hoogle-4.2.36/databases:
changeWorkingDirectory: does not exist (No such file or directory)
$
对于 O'Charles 所描述的设置,我如何才能使其正常工作?
编辑:原来的shell.nix与this answer中的相同。
【问题讨论】:
【参考方案1】:这是我的 Nix Haskell 开发环境的样子
在~/.nixpkgs/config.nix
:
环境辅助函数
首先,定义一个 haskellEnvFun 函数来构建 Haskell 环境:
packageOverrides = super: rec
haskellEnvFun = withHoogle ? false, compiler ? null, name :
let hp = if compiler != null
then super.haskell.packages.$compiler
else haskellPackages;
ghcWith = if withHoogle
then hp.ghcWithHoogle
else hp.ghcWithPackages;
in super.buildEnv
name = name;
paths = [(ghcWith myHaskellPackages)];
;
定义一些环境
调用此函数来定义两种环境:一种用于在更改时运行 Hoogle 构建器,一种不用于:
haskellEnvHoogle = haskellEnvFun
name = "haskellEnvHoogle";
withHoogle = true;
;
haskellEnv = haskellEnvFun
name = "haskellEnv";
withHoogle = false;
;
包
定义你想在本地 Haskell 开发环境中使用的所有包:
myHaskellPackages = hp: with hp; [
Boolean
HTTP
HUnit
MissingH
QuickCheck
SafeSemaphore
Spock
aeson
async
attoparsec
bifunctors
blaze-builder
blaze-builder-conduit
blaze-builder-enumerator
blaze-html
blaze-markup
blaze-textual
cased
cassava
cereal
comonad
comonad-transformers
directory_1_2_4_0
dlist
dlist-instances
doctest
exceptions
fingertree
foldl
free
hamlet
hashable
hspec
hspec-expectations
html
http-client
http-date
http-types
io-memoize
keys
language-c
language-javascript
language-bash
lens
lens-action
lens-aeson
lens-datetime
lens-family
lens-family-core
lifted-async
lifted-base
linear
list-extras
list-t
logict
mime-mail
mime-types
mmorph
monad-control
monad-coroutine
monad-loops
monad-par
monad-par-extras
monad-stm
monadloc
mongoDB
monoid-extras
network
newtype
numbers
optparse-applicative
parsec
parsers
pcg-random
persistent
persistent-mongoDB
persistent-template
pipes
pipes-async
pipes-attoparsec
pipes-binary
pipes-bytestring
pipes-concurrency
pipes-csv
pipes-extras
pipes-group
pipes-http
pipes-mongodb
pipes-network
pipes-parse
pipes-safe
pipes-shell
pipes-text
posix-paths
postgresql-simple
pretty-show
profunctors
random
reducers
reflection
regex-applicative
regex-base
regex-compat
regex-posix
regular
relational-record
resourcet
retry
rex
safe
sbv
scotty
semigroupoids
semigroups
shake
shakespeare
shelly
simple-reflect
speculation
split
spoon
stm
stm-chans
stm-stats
streaming
streaming-bytestring
streaming-wai
strict
stringsearch
strptime
syb
system-fileio
system-filepath
tagged
taggy
taggy-lens
tar
tardis
tasty
tasty-hspec
tasty-hunit
tasty-quickcheck
tasty-smallcheck
temporary
test-framework
test-framework-hunit
text
text-format
time
tinytemplate
transformers
transformers-base
turtle
uniplate
unix-compat
unordered-containers
uuid
vector
void
wai
wai-conduit
warp
wreq
xhtml
yaml
zippers
zlib
];
外壳助手
在您的 ~/.profile
中定义几个 bash 函数以方便加载这些环境:
胡歌
在你的 shell 中调用haskell-env-hoogle
。这将构建您所有的包 + 文档并将您加载到具有hoogle
范围的环境中。此时我通常会输入:
hoogle server --local -p 8080 &> /tmp/hoogle.log & disown
在后台启动一个hoogle server。最终我想为此提供一个 systemd 服务,以便我可以通过 nixos-rebuild 重新生成文档并自动启动服务器。
Emacs
对于 emacs,我将 haskell-hoogle-url
设置为 http://localhost:8080/?hoogle=%s
,这样我就可以获取光标下关键字的本地 hoogle 文档。我使用 spacemacs,所以我只需键入 , h h
即可获得此功能。
您可以在此处查看我的完整 nixpkgs 配置:https://github.com/jb55/nix-files/blob/659798f2ca81fb7ad0cb5a29de576024ee16eef8/nixpkgs/config.nix#L20
希望对您有所帮助。
【讨论】:
【参考方案2】:haskellPackages.hoogleLocal
似乎已过时;它已经不存在了。
William Casarin 的回答似乎是假设您将使用一个单一的“haskell 开发环境”,而不是使用 nix-shell 为不同的项目提供不同的开发环境。
我刚刚想出的办法是编写我的 shell.nix 以覆盖 ghc.withPackages
和 ghcWithPackages
为 ghc.withHoogle
,这样当 nix-shell 创建一个带有 GHC 的环境时,它知道关于所有必要的包,它还会创建一个知道相同包的 hoogle 数据库。
这是我的 shell.nix1:
nixpkgs ? import <nixpkgs> , compiler ? "default", withHoogle ? true :
let
inherit (nixpkgs) pkgs;
f = import ./default.nix;
packageSet = (
if compiler == "default"
then pkgs.haskellPackages
else pkgs.haskell.packages.$compiler
);
haskellPackages = (
if withHoogle
then packageSet.override
overrides = (self: super:
ghc = super.ghc // withPackages = super.ghc.withHoogle; ;
ghcWithPackages = self.ghc.withPackages;
);
else packageSet
);
drv = haskellPackages.callPackage f ;
in
if pkgs.lib.inNixShell then drv.env else drv
我对 nix 很陌生,但我相信这应该是“独立于项目”的;当我更改它时,我可以使用cabal2nix . > default.nix
从我的 cabal 文件中生成一个 nix 包,而无需触摸 shell.nix。
我还没有真正在实际开发中使用它,只是我用来尝试弄清楚如何让 hoogle 在 nix-shell 中工作的一个虚拟项目。
1这是cabal2nix --shell
吐出的骨架,删除了项目特定的内脏并用f = import ./default.nix
替换,而不是再次嵌入nixified cabal 包。
【讨论】:
是的!我曾经这样做过。在编写大量 Haskell 代码时,我发现将所有内容都放在一个 shell 中以进行快速开发更容易。但是,如果您只有一个正在从事的项目,这将非常有用。【参考方案3】:使用@Ben 的答案作为参考,这里是我需要对cabal2nix --shell
文件进行必要更改的差异:
diff --git a/shell.nix b/shell.nix
index 540ade3..e207d6e 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,4 +1,4 @@
- nixpkgs ? import <nixpkgs> , compiler ? "default", doBenchmark ? false :
+ nixpkgs ? import <nixpkgs> , compiler ? "default", doBenchmark ? false , withHoogle ? true:
let
@@ -21,10 +21,23 @@ let
license = stdenv.lib.licenses.bsd3;
;
- haskellPackages = if compiler == "default"
+ haskellPackages' = if compiler == "default"
then pkgs.haskellPackages
else pkgs.haskell.packages.$compiler;
+ haskellPackages = (
+ if withHoogle
+ then haskellPackages'.override
+ overrides = (self: super:
+
+ ghc = super.ghc // withPackages = super.ghc.withHoogle; ;
+ ghcWithPackages = self.ghc.withPackages;
+
+ );
+
+ else haskellPackages'
+ );
+
variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;
drv = variant (haskellPackages.callPackage f );```
【讨论】:
以上是关于在 nix 上的 haskell 开发环境中使用 hoogle的主要内容,如果未能解决你的问题,请参考以下文章
您在 *nix 服务器上的 ASP.NET Core 生产环境中使用哪个 Web 服务器?