How does the workflow with Haskell Stack work? - haskell

I don't get the point about Stack.
I used to write my Haskell code in my favourite environment, ran or compiled using GHC(i), and if necessary, installed packages using Cabal. Now, that apparently is not the way to go any more, but I don't understand how to work with Stack. So far, I have only understood that I need to write stack exec ghci instead ghci to start a repl.
Apart from that, the docs always talk about 'projects' for which I have to write some yaml files. But I probably don't have any project -- I just want to launch a GHCi repl and experiment a bit with my ideas. At the moment, this fails with the unability to get the packages that I want to work with installed.
How is working with Stack meant? Is there any explanation of their use cases? Where do I find my use case in there?
Edit. My confusion comes from the fact that I want to work with some software (IHaskell) whose installation guide explains the installation via stack. Assuming I already have a GHCi installed whose package base I maintain e.g. using Cabal. How would I have to set up stack.yaml to make stack use my global GHCi for that project?

First, notice that stack will use its own package base independent from cabal. AFAIK they can't be shared... hence, if you run stack build it'll download packages (including the compiler) on its own package database.
Nevertheless stack allows to use a system compiler (but not other libraries). To do so, in the stack.yaml you must have the following two lines
resolver: lts-XX.XX -- keep reading below
system-ghc: True
The version of the stackage snapshot can be found in: https://www.stackage.org/. Each snapshot works with a different version of the compiler. Be sure to use a snapshot with the same compiler version you have in you system. If it happens your system ghc is greater than any lts, then you can set allow-newer: true in stack.yaml.
Now, if getting a different database from stack feels wrong to you, notice that you can build the project with cabal too, since stack at the end of the day spits out a cabal file. Probably, It wont work out of the box if you build with cabal. You can modify the cabal file to match exactly the version of the packages of the snapshot you are using
In summary:
You can use your system-wide ghc
you can not share libraries installed with cabal.
you can use cabal to build the project, probably modifying the ihaskell.cabal file to match versions of the stackage's snapshot.

Related

What is the suggested way of setting up Haskell on Archlinux?

Long story short, I'd like some guidance on what's the (best) way to have Haskell work on Archlinux.
By work I mean all, in terms of the ghci command line tool, installing packages I don't have - such as vector-space, which this answer to a question of mine refers to -, and any other thing that could be necessary to a Haskell obstinate learner.
Archlinux wikipage on Haskell lists three (alternative?) packages for making Haskell work on the system, namely ghc, cabal-install, and stack. I have the first and the third installed on my system, but I think I must have installed the latter later (unless it's a dependency to ghc) while tampering around (probably in relation to Vim as a Haskell IDE). Furthermore, I have a huge amount of haskell-* packages installed (why? Who knows? As a learner I must have come multiple times to the point of say uh, let's try this!).
Are there any pros and cons ("cons", ahah) about each of those packages?
Can they all be used with/without conflicts?
Does any of them make any other superfluous?
Is there anything else I should be aware of which I seem apparently ignorant about based of what I've written?
Arch Linux's choice of providing dynamically linked libraries in their packages tends to get in the way if you are looking to develop Haskell code. As an Arch user myself, my default advice would be to not use Arch's Haskell packages at all, and instead to install whatever you need through ghcup or Stack, starting from the guidance in their respective project pages.
You are basically there. Try the following:
ghci: If you get the Haskell REPL then it works.
stack ghci: Again you should get the Haskell REPL. There are a lot of versions of GHC, and stack manages these along with the libraries. Whenever you use a new version of GHC stack will download it and create a local installation for you.
stack is independent of your Linux package manager. The trouble is that your distro will only have the Haskell libraries it actually needs for any applications it has integrated, and once you step outside of those you are in dependency hell with no support. So I recommend that you avoid your distro Haskell packages. stack does everything you need.
If you installed stack from your Linux package manager then you might want to uninstall it and use a personal copy (i.e. in your ~/.local directory) instead. Then you can always say stack update to check you have the latest version.
Once you have stack going, create a project by saying stack new my-project simple. Then go into the project folder and start editing. You can work with just a .hs file and GHC if you really want, but its painful; you will do much better with stack, even if you are just messing around.
You'll also need an editor. Basic functionality like syntax highlighting is available in pretty much everything, but once you get past Towers of Hanoi you are going to want something better. I use Atom with ide-haskell-ghcide. This uses the Haskell Language Server under the hood, so you will need to install that too. I know a bunch of other editors have HLS support, but I don't have experience with them.

Broken dependency in haskell stack?

I am relatively new to haskell, stack, ghc, etc.
Have been trying a few projects with ghcjs and haven't been able to build any of them, including reflex-dom-stack-demo. I am getting the following error:
In the dependencies for semigroupoids-5.0.0.4:
tagged-0.8.1 from stack configuration does not match >=0.8.5 && <1 (latest matching version is 0.8.5)
needed due to ghcjs-0.2.0 -> semigroupoids-5.0.0.4
Now I cannot understand whether I misconfigured something or there is truly a broken dependency. Deleted ~/.stack multiple times throughout my experiments.
I found this bug in stackage but am unsure whether this is what affects me, and whether it would be fixed once the fix moves through.
Using Ubuntu 17.10..
Any insight is welcome.
The recomended way to create a development environnement for reflex-dom is to use try-reflex.
It is tricky to build reflex-dom with stack, because some needed changes have not yet been added to the upstream libraries.
If you really want to build a reflex-dom environnement with stack, please consider these hints:
Do not use a GHC compiler with a version higher than 8.0.2
Do not use the reflex /reflex-dom versions from Hackage, they are outdated.
Use versions of reflex / reflex-dom from Github.
This repo contains a stack.yaml file, that used to work.
You may also try the stack.yaml file from the answer to this SO question.

Cabal + Stack: specifying the packages version in the cabal file

Normally when adding a new dependency to a .cabal file I specify the version of the new library I'm depending on. However stack works with a curated set of libraries, and I'm wondering whether it makes sense to specify the package versions in the .cabal file. My guess would be that specifying the lts version in the stack.yaml is enough.
I'm wondering whether it makes sense to specify the package versions in the .cabal file.
That depends completely upon you. If you specify a package version
which is not in that particular stackage resolver, then Stack will
throw an error saying you to adjust the versioning.
My guess would be that specifying the lts version in the stack.yaml is enough.
For private packages, it doesn't matter and I prefer not putting any version bounds there. But if it's something I ultimately plan to publish on Hackage, I usually use a CI system like Travis and get the bounds right for it with some testing. In fact, I think the Stack guide recommends something like that.

How do I ensure that my Haskell packages match LTS Haskell?

I'd like to have a simple way of ensuring that the packages in my system, whether they are in the global or the user package database, correspond to the versions in the current LTS Haskell.
I gather that there are fairly simple ways to do something like this for a specific project. But it's not clear to me how to achieve this for my Haskell system as a whole. I have Stack installed already (using Cabal), and use Homebrew where I can (e.g., for Haskell, just for cabal-install). I'm tempted by haskell-stack, but it's unclear what exactly that does.
Is there a simple way to ensure that my system's Haskell packages (wherever they reside) match LTS Haskell?
If you're using cabal-install, your best bet is to append the contents of https://www.stackage.org/lts-3.8/cabal.config?global=true (adjust the LTS snapshot slug to your preference) to your ~/.cabal/config. I'd caution against doing this, though, since you may well want to use different snapshots for different projects. Use of sandboxes with cabal-install is highly recommended (in fact, I set require-sandbox: true in my cabal config to make sure I don't forget).
For Stack, the LTS snapshot is always project-specific; there is no global setting. But setting the resolver: value in ~/.stack/global/stack.yaml sets it for when you run stack outside of a specific project, and also influences the choice of resolver for new projects (when you use stack init or stack new).
BTW, it looks like the Homebrew haskell-stack formula is just an alternate way to install Stack, so if you already have Stack there's no need to use it.

How to use two different compilers for different targets in a .cabal file?

When I run cabal build it uses some Haskell compiler to build the executables and/or test-suites in my .cabal file.
Can I control which compiler is used for the different targets? Ideally, I would like to have separate build targets that use ghc and ghcjs in the same .cabal file. It seems to me that someone might want to use ghc and hugs or two version of ghc in the same project. Is this currently possible?
Also, how does cabal decide what compiler to use when running cabal build? I saw there is a compiler option in my ~/.cabal/config file but changing it from ghc to ghcjs and uncommenting it, did not seem to change what cabal build does.
The compiler to use is determined during the configure step (or during an install step's implicit configure step, which does not share configuration options with a previous configure step). It is also determined by the entity building the package and cannot be influenced by the person writing the package. Probably what happened to you is that a previous cabal build implicitly invoked the configure step and chose a compiler; future builds will keep a previous choice of compiler over one stuck in your global configuration file. You can countermand that by simply manually running cabal configure again.
It is possible to cause a build to fail with the wrong implementation, e.g.
library
if impl(ghc)
buildable: False
will prevent cabal from trying to build the package using GHC. However, this isn't really useful for building separate parts of a package with separate compilers, as cabal will refuse to install a package unless it can build the whole thing with a single compiler.
Probably the best way forward is to make separate packages for things that should be built by separate compilers.

Resources