Haskell Learners' Group (Week 1)
By Walker Malling and Richard Cook, 2018/4/4
A recap of what we talked about during the first meeting of the all-new Haskell Learners’ Group meetings in Seattle
We went round the room to introduce ourselves and gauge the level of experience of each attendee.
What is Stack?
- In the world of Haskell compilers, we only really care about GHC, the Glasgow Haskell Compiler. And once you choose a compiler, your concern narrows to which version of the compiler.
- Haskell has undergone a lot of changes in the past 6 years, so this is not a trivial matter.
- Libraries and packages are dependent on certain versions of GHC.
- Cabal is Haskell’s common architecture for packaging libraries and programs.
- Hackage is Haskell’s most well-known repository for open-source packages.
- Stackage is “stable” Hackage. The idea is to take LTS (long-term support) snapshots of all stable packages on Hackage that build on certain versions of GHC.
- Stack is a build tool/manager, which lets you manage (sandbox) versions of GHC for your projects, and resolve packages that work with that version of GHC.
- Currently, LTS 11.3 is the latest snapshot, and we can configure our project (or our global environment) to use that LTS snapshot to resolve a version of GHC and packages that build on it.
- For our purposes, any reasonably recent version of Stack will be sufficient: most people in attendance had at 1.6.x.
- You can check the version of Stack on your system with
Modify your global Stack configuration
UPDATE: It turns out that this is not true (see
this issue in GitHub). It is not currently possible to
specify a default resolver globally. Instead, you’ll need to explicitly pass
--resolver=lts-11.3 on the command line or edit your project-level
Create a new project
stack new hello-seattle simple
UPDATE: Again, you’ll need to explicitly specifier a resolver if the default is not appropriate. Since LTS 11.3 is the current default, this is OK for the time being. To lock to this version in the future:
stack new hello-seattle simple --resolver=lts-11.3
Build the project
This builds your project and creates the resulting binary in a subdirectory
.stack-work directory in your project’s root. Typically, you’ll
want to add
.stack-work to your
.gitignore file if you’re using Git version
control for your project since you won’t want to check binaries in.
AWS Lambda and native binaries
Rambling aside by Richard
Note that, while AWS Lambda doesn’t directly advertise runtime support for Haskell programs, you can distribute native binaries. By default, Stack generates statically-linked binaries which can easily be bundled up and deployed to Lambda.
I (Richard) have written a series of blog posts on using Haskell to interact with AWS services (built on the really cool Amazonka family of Haskell packages. Note that Amazonka makes pretty heavy use of lenses which we’ll learn about later.
stack exec hello-seattle
To install a copy of your executable to a location on your system search path,
i.e. somewhere on the
PATH environment variable, for example at
~/.local/bin/hello-seattle in this case:
stack install hello-seattle
Build and run in one step
stack build --exec hello-seattle
View Stack paths
List all of Stack’s special paths:
Launch GHCi REPL
||Returns the type signature of the given expression|
||Shows the kind of a given type|
||Returns general info about a given name|
||Shell out to execute a command|
||If you have a source file loaded, this will open your system default editor to the referenced line|
This command will determine the appropriate version of GHC/GHCi to use based on
stack.yaml or the global configuration file in effect. When
run as part of a project, all the packages referenced in your
will also be available to import functions from.
Other Stack commands mentioned but not demonstrated
stack test: to run test targets
stack bench: to run benchmark targets
stack haddock: to generate documentation
stack templates: to list available project templates
stack upgrade: to upgrade to latest version of Stack tool
stack uninstallis a no-op
A brief look at our
module Main where main :: IO () main = do putStrLn "hello world"
IOis a generic type and unit
()is its argument
- Unit is (roughly) analogous to
voidin languages such as Java/C/C++/C#
dois syntactic sugar for
>>(“then”), and is used to sequence actions
Discussion of course materials and formats
We rounded out the evening by talking about what form future meetings of the learners’ group should take.