FAQ
This FAQ is based on actual frequently-asked questions from #haskell IRC. The goal is simply to collect and edit some common answers. Beginner questions are still welcome on IRC, as always.
This is a wiki, so please edit the text with any improvements you have. And feel free to add new questions, if they are frequently asked.
See also
- Other FAQs
- The introduction to Haskell, and the FAQ at the end of that document.
The real world
Should I learn Haskell?
That depends on your goals. In general, Haskellers will tell you that you should learn Haskell. :)
Learning Haskell is fun. It will expand your mind and make you a better programmer in other languages. These are the immediate benefits.
Haskell is also a great tool for solving real-world problems, but it can take many months of study to get to that point.
Is Haskell hard to learn?
Any competent programmer can learn Haskell, but it will take more time and motivation than you may expect.
Haskell requires learning a new way to think, not just new syntax for old concepts. This can be incredibly frustrating, as simple tasks seem impossibly difficult.
Those with no prior programming experience may actually have an easier time learning Haskell, because they have less to un-learn.
How can I get started with Haskell right now?
Check out Try Haskell.
Also: FP Complete's free online IDE
What should I read for learning Haskell?
The most popular resources are Learn You a Haskell and Real World Haskell. Each is available online for free, or can be purchased in hardcopy.
Many other tutorials, books, and other resources are available.
There's also the School of Haskell which has a set of free online tutorials with runnable examples.
How can I get help with learning Haskell?
Your options include:
- #haskell on Freenode IRC
- Stack Overflow
- The Haskell-Cafe mailing list
Will Haskell get me a job?
There are plenty of companies using Haskell, but it's still a tiny number compared to the software industry as a whole.
There are also many companies which do not use Haskell, but prefer to hire people who know Haskell. It indicates that you learned something hard and obscure just for fun, which employers take as a sign of intelligence.
Is Haskell similar to Language X?
Probably not. It's best if you approach Haskell with a clean slate. Most analogies to another language will break down somewhere, often in a subtle and misleading way. If you first learn the Haskell concepts for what they are, you can then draw useful connections to other languages.
What's the relationship between Haskell and GHC?
Haskell is not a piece of software; it is a specification for a standardized programming language. The latest version of the spec is the Haskell 2010 Report.
GHC is the Glorious Glasgow Haskell Compiler. It is by far the most popular and "production-ready" implementation of the standard Haskell language. It also implements many extension features that go above and beyond standard Haskell. Many programs use these features and so aren't "written in Haskell" in the strictest sense.
You can use the term "Haskell" to refer to the standard language, and "GHC Haskell" when including GHC extensions.
Besides GHC, several other implementations of Haskell are available. Each one provides its own extensions, some of which don't exist in GHC.
What is the Haskell Platform?
The Haskell Platform is a copy of GHC bundled with a "blessed" set of useful libraries. It is the easiest way to get started with Haskell. It's not essential to start with the Platform, because you can install the same libraries as needed.
What is Haskell Prime (Haskell')?
Haskell Prime is a process which produces new versions of the Haskell language spec. It does not refer to a particular present or future version of Haskell.
My textbook uses Haskell 98. Is it very different from Haskell 2010?
No. Haskell 2010 is a very conservative change to Haskell 98. It fixes small syntactic flaws, and standardizes several well-behaved extensions which GHC has supported for years.
The standardization process is very slow because standardizing a flawed language can be a costly mistake. Extensions are accepted only once they are considered mature and well-understood.
How do I get libraries for Haskell?
You can find libraries on Hackage, and install them with cabal-install.
Is Haskell compiled?
Usually. GHC, the most popular Haskell implementation, has an optimizing ahead-of-time native-code compiler, as well as a bytecode compiler and interpreter for interactive use.
Haskell itself is not a "compiled language" because nothing in the Haskell spec requires implementations to be compilers.
Does Haskell have an interpreter?
Yes, but maybe you instead mean "Is there a program where I can type Haskell code and see it run immediately?". GHCi provides such a "read-evaluate-print loop".
Which project can I join?
See Haskell projects needing help.
Paradigms
Is learning Haskell the best way to learn functional programming?
Not necessarily! Haskell is not a typical functional language. It can be overwhelming to learn the basic concepts of functional programming alongside static types, algebraic data, laziness, type classes, first-class IO, etc. For an introduction to FP by itself you might want to learn Scheme, or play with the FP features in your current favorite language.
That said, many people choose Haskell as an introduction to FP and have success with that approach. Haskell has an extremely active community of people teaching, doing research, writing libraries, etc. Haskell is where interesting things happen in the FP space, so it's an exciting place to jump in.
I heard Haskell is pure functional. Does that mean it doesn't have mutable state?
No; see IORef for a simple example. A more sophisticated example is software transactional memory, which provides concurrent state more sophisticated than you'll find in most other imperative languages.
I heard Haskell is pure functional. Does that mean I can't do imperative / OOP / aspect-oriented / logic programming in Haskell?
No, "pure functional" has a specific technical meaning. It doesn't mean that functional is the only supported paradigm.
Paradigms describe the techniques used in a particular program. For example, the Linux kernel is written in C, with pervasive use of functional, object-oriented, and aspect-oriented programming. The most we can say about a language is that it encourages or discourages a particular paradigm. Haskell is very flexible and can comfortably accommodate most paradigms, even when there is no built-in support.
Wait, is Haskell imperative or is it functional?
Both - and it's also referentially transparent. In Haskell, functions are first class, and so are imperative actions.
There is no reason to consider "imperative language" and "functional language" as mutually exclusive. It's only a historical accident that a few of the most popular imperative languages are unusually bad at functional programming. Functional imperative programming is extremely powerful and is supported by many languages.
Math
Was Haskell designed by mathematicians?
Haskell was designed by people studying programming language design. Perhaps programmers would consider them to be mathematicians, while mathematicians would consider them to be programmers.
Designing a programming language is a hard thing to do. There are many non-obvious tradeoffs, and many lessons to be learned from past failures and successes. Yet many of today's most popular languages were designed by people who hadn't done their homework.
Haskell was designed by people who knew what they were doing. It's not perfect, but the contrast to an amateur's design is striking.
Do I need to know advanced math in order to use Haskell?
No. Certain concepts in Haskell are named after concepts in advanced math. But other languages also appropriate math terminology: consider "singleton", not to mention "function" and "variable". The way these programming concepts relate to actual mathematics is not necessarily important or relevant.
In addition, some people write articles about advanced math, using Haskell syntax as their notation. These articles are interesting, but the connection to everyday programming work is usually remote.
Knowing advanced math will enrich your experience using Haskell, but is by no means a prerequisite.
Types
Doesn't a static type system just make it harder to write programs?
Yes. In particular, it makes it much harder to write incorrect programs.
The tradeoff is that correct programs also become somewhat harder to write. In Haskell, features like type inference mitigate this burden to a large extent.
How do I make a list with elements of different types?
Are you sure that's what you want? Consider instead creating a single data type to encompass the alternatives:
data Identifier
= ByNumber Int
| ByName String
doStuff :: [Identifier] -> Whatever
In many dynamically-typed languages you aren't allowed to create "variant types" like this. The type system itself is used as a single ad-hoc global variant type. Keep this in mind if you're translating designs from a dynamically-typed language to Haskell.
No really, how do I make a list of elements of different types?
Well, you can't avoid putting all your values into one type. But sometimes the "variant type" approach above is too restrictive. Maybe you need to let other people add to the set of allowed types, the way Control.Exception allows users to define new exception types.
You can use an existential type, possibly with a type class. Or you can use Data.Dynamic.
I'm making an RPG. Should I define a type for each kind of monster, and a type class for them?
Probably not. Some languages require a new type for each new behavior. In Haskell, behaviors are functions or IO actions, which are first-class values. So you can store behaviors in an ordinary data type:
data MonsterOps = MonsterOps
{ new :: Monster
, move :: Monster -> Monster
, attack :: Monster -> Player -> Player }
data Monster = Monster
{ position :: (Int, Int)
, hitpoints :: Double }
beholder :: MonsterOps
beholder = MonsterOps new move attack where
new = Monster (0,0) 9000
move self = ...
attack self player = ...
This approach is especially nice if you want to generate or transform behaviors on the fly. See the article "Haskell Antipattern: Existential Typeclass" for a longer discussion.
What's the difference between Integer
and Int
?
Integer
and Int
?Integer
can represent arbitrarily large integers, up to using all of the storage on your machine.
Int
can only represent integers in a finite range. The language standard only guarantees a range of -229 to (229 - 1). Most implementations will provide a full machine-size signed integer, i.e. 32 or 64 bits.
Operations on Int
can be much faster than operations on Integer
, but overflow and underflow can cause weird bugs. Using Int
in an initial design could be considered premature optimization. Unfortunately, many standard library functions (e.g. length
, take
) use Int
. There are also generic variants of those.
How do I convert type A to type B?
This is just another way of asking for a function of type A -> B
. For example, you can convert Double
to Int
with round
, ceiling
, or floor
. Haskell does not privilege one of these as the conversion.
Does Haskell have type casts?
The word "cast" can mean a lot of different things.
- You want to convert a value from one type to another, preserving some idea of what it means. For example, you might convert an
Int
to aDouble
which represents the same integer. In this case you'd just use a function of typeInt -> Double
, such asfromIntegral
. Haskell doesn't provide special rules or syntax for these functions. See also the previous question. - You want to pass a value of more specific type to a function expecting a less specific type. There's no syntax for this in Haskell; you just do it. For example you can pass
x :: Int
toshow :: (Show a) => a -> String
, which automatically specializes the type ofshow
toInt -> String
. Note that Haskell does not have subtyping, so this only happens in the context of instantiating type variables. - You want to use a value of less specific type under the assumption of a more specific type, with a checkable runtime error if they do not match. This is rarely the right way to do things in Haskell, and probably indicates a conceptual / design problem instead. If you really do need such a cast, you can use cast from Data.Typeable. In this case the "checkable runtime error" is
cast
returningNothing
. Note that Haskell does not have subtyping, so this only happens in the context of instantiating type variables. - You want to use a value of less specific type under the assumption of a more specific type, and if the assumption is incorrect, the program is allowed to segfault / silently corrupt data / give the attacker a root shell / send illicit photos to your boss. Also known as a "reinterpret cast". GHC Haskell has a way to do this, but I dare not speak its name. It's so dangerous and so unlikely to be what you want that it has no place in a general FAQ. You can ask on IRC or read the docs if you have the right kind of morbid curiosity.
How do I convert from one numeric type to another?
Probably using one of these:
fromIntegral :: (Integral a, Num b ) => a -> b
realToFrac :: (Real a, Fractional b) => a -> b
fromIntegral
converts to a wider range of types, but realToFrac
converts from types which aren't integers.
How do I convert Maybe Int
to Int
?
Maybe Int
to Int
?Use pattern-matching. If mx :: Maybe Int
:
case mx of
Just x -> ...
Nothing -> ...
This forces you to consider the Nothing
case, and is the main advantage of Maybe
, compared to adding a null value to every type.
See also the functions maybe and fromMaybe in the module Data.Maybe.
Do not use fromJust
, because passing Nothing
will crash your program with a supremely unhelpful error message. Even when you want to assume the value is not Nothing
, you can provide a better error message:
let x = fromMaybe (error "custom error message") mx in ...
If you pattern-match without a Nothing
case:
let Just x = mx in ...
you'll at least get a line number in the error message:
*** Exception: foo.hs:2:9-24: Irrefutable pattern failed for pattern Data.Maybe.Just x
How do I convert between String
(or Text
) and ByteString
?
String
(or Text
) and ByteString
?String
represents a sequence of Unicode characters. ByteString
represents a sequence of bytes. There are many different, incompatible ways to represent Unicode characters as bytes. See this article if you're fuzzy on the character / byte distinction.
The module Data.Text.Encoding from the text package provides functions for common Unicode encodings. For more obscure / legacy encodings, see the text-icu package.
How do I catch the error thrown by read
on a parse failure?
read
on a parse failure?Don't. Instead use
import Text.Read (readMaybe)
readMaybe :: Read a => String -> Maybe a
which returns a Nothing in the case of parse failure.
What's the difference between type
, data
, and newtype
?
type
, data
, and newtype
?type
introduces a synonym, which is fully interchangeable with the original type:
type Foo = Int
main = print ((2 :: Int) + (3 :: Foo))
So it provides convenience and documentation, but no additional type checking.
data
is used to define new data types, distinct from any existing type.
newtype
can mostly be understood as a restricted form of data
. You can use newtype
when you have exactly one constructor with exactly one field. In those cases, newtype
can give better performance than data
.
There is, however, a subtle difference between data
and newtype
semantics, which is why the newtype
optimization is not applied automatically.
Making it work
How can I find type errors?
There's no silver bullet, but here are a few useful techniques:
- Comment out type signatures and see what GHC infers, using :t in GHCi.
- Add more type signatures, for example inside
let
. This makes your assumptions clearer, so GHC's error message may better explain how your assumptions are inconsistent. - Replace some subexpressions with
undefined
, which can assume any type. In more recent versions of GHC, you should insert a "type hole", written_
(a single underscore) instead ofundefined
for this purpose. GHC's error message will then indicate the type it's expecting for the expression in the hole.
How can I find bugs that occur at runtime?
With pure functions, correctness is a matter of getting the right output for a given input. If one function gives incorrect results, you test the functions it calls, and so on until the bad code is located. You can perform these tests directly in GHCi, or with the help of a tool like QuickCheck.
You can trace evaluation using Debug.Trace. You'll get a printout when the expression is evaluated. Due to lazy evaluation, this might be at an unexpected time. But this property is useful when debugging problems related to excessive laziness.
GHCi also implements a "simple imperative-style debugger".
Haskell is a natural fit for novel "declarative debugging" tools but to our knowledge, no such tool is production-ready.
Why do I get an "undefined symbol" linker error when compiling?
If you're using GHC 6, you should pass --make so that GHC will automatically link the appropriate Haskell libraries.
How can I get a stack backtrace when my program throws an exception?
The standard stack in GHC Haskell doesn't represent nested function calls. The more informative stack is the profiling cost-center stack, which only exists if your code is built for profiling.
With GHC 7 you can do something like this:
$ ghc -fforce-recomp -prof -auto-all -rtsopts foo.hs
For GHC 6 you should leave off -rtsopts, and you'll probably want --make.
You can then run your program with the -xc RTS option`:
$ ./foo +RTS -xc
How can I do automated unit testing?
See the testing chapter in Real World Haskell.
How can I find and fix performance problems?
See the profiling and optimization chapter in Real World Haskell.
Modules
How do I deal with name clashes between modules?
You can disambiguate by prefixing a module name:
import Data.List
import Data.Map
f = Data.List.lookup 7
g = Data.Map.lookup 7
The import syntax gives you additional control:
- With
import qualified Foo
the names fromFoo
can only be used qualified, and won't clash with unqualified names.
- With
import Foo as M
you'd writeM.x
instead ofFoo.x
.
You can combine these two features. A more common way to write the above example is:
import qualified Data.Map as M
f = lookup 7 -- unqualified, from Prelude
g = M.lookup 7
In general, most combinations of import
features are allowed. You
can combine as
and qualified
with import and
hiding
lists. You can import two modules as
the same
name, or one module as
two names, with different import and
hiding
lists, qualified
or unqualified, etc.
How do I control the Prelude
import?
Prelude
import?Haskell modules implicitly import Prelude
, unless an explicit import is given. So you can write
import Prelude as P hiding (length, head)
How do I qualify the name of an infix operator?
You prefix the module name, as usual:
x = 2 + 3
y = 2 Prelude.+ 3
f = (+) 7
g = (Prelude.+) 7
This looks weird but works fine. The syntax does clash a bit:
xs = [False..True] -- wrong, parses as qualified name
xs = [False .. True] -- ok
How do I mention an infix operator in an export / import / hiding
list?
hiding
list?The same way as elsewhere: enclose it in parentheses.
import Prelude ( succ, (+), length, (*) )
I listed a data type in my import list but its data constructors aren't in scope. How do I fix it?
You have to import data constructors explicitly:
import Prelude ( Maybe ) -- the type only
import Prelude ( Maybe(Nothing) ) -- type and specific constructor(s)
import Prelude ( Maybe(..) ) -- type and all its constructors
How can I import and re-export a whole module?
module Bar ( module Foo ) where
import Foo
How can I export another module and everything defined in this module?
module Bar ( module Bar, module Foo ) where
import Foo
Input/Output
I heard Haskell is pure functional. Does that mean it can't do IO?
No; IO in Haskell is straightforward.
Do I need to understand monads in order to do IO?
Not really. "Monad" is the name of a generic API that applies to many different types, including the IO
type. If you're only thinking about IO, you don't need to worry about how this API generalizes.
See the Introduction to IO.
How do I convert IO Int
to Int
?
IO Int
to Int
?Assuming the type mismatch is occurring in an Haskell definition which already relies on I/O:
g :: IO Int
g = do ...
f x y = do ...
n = g
...
v <- h n
...
then you have two options:
- the simplest option is to use some extra
do
notation:
f x y = do ...
n <- g
...
v <- h n
...
- but occasionally a monadic-binding operator such as
(=<<)
can also be used:
f x y = do ...
n = g
...
v <- h =<< n
...
How do I convert IO Int
to Int
inside a pure definition?
You can't; if you could then the definition would stop being pure no matter what its type is. More importantly, if you could do that then so could others! Now imagine you're the one trying to find an error in a library full of pure
definitions; an error that only occurs when the library is used in parallel programs. As libraries can depend on other libraries, which can depend on yet more libraries...where would you even begin to look?
So much trouble, and all because someone could convert an IO Int
to Int
inside a pure
definition, one that's supposed to work in parallel...perhaps no-one should be allowed to do that.
Now please read the Introduction to IO.
I have another question...
- It could be in Stack Overflow's list of questions about I/O in Haskell.
The M-word
See also "What a Monad is not".
I heard Haskell is about monads. I heard that the core feature of Haskell is monads. Is that true?
Absolutely not.
What should I know before trying to understand monads?
Let's look at part of the definition of Monad
:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
This uses a lot of features:
- first-class functions: the second argument to
(>>=)
is a function
- type constructors (here
m
)
- type class polymorphism
- type class polymorphism over type constructors (which few other languages have)
- parametric (not type class) polymorphism, over
a
andb
Each of these features is more fundamental than the specific idea of monads. If you understand each feature, then Monad
is a small example of how they fit together. Functor
is a slightly simpler example, and you can start there instead (see Typeclassopedia).
Aren't monads just a hack for handling impure things in a pure language?
No. This is wrong in several ways.
First, Monad
isn't special.Monad
is an ordinary Haskell type class. You can define it yourself in a few lines of pure Haskell code, so it's definitely not adding magical new capabilities to the language. Besides that, Monad
is an API, not an implementation.
(The do
syntax is special, but it's only syntactic sugar. There's a straightforward translation to ordinary function calls, lambdas, etc.)
Second, most monads have nothing to do with effects or "impurity". The Monad
API is implemented by many different type constructors, including Maybe
and []
. Lists and Maybe
values are straightforward, familiar data values. There's nothing "impure" about them.
Third, IO
is not an exception to purity.
In short, Haskell programs are pure-functional programs which compute imperative programs.
It's true that IO
implements the Monad
API, but that's not fundamental. You could instead use non-overloaded functions like
returnIO :: a -> IO a
bindIO :: IO a -> (a -> IO b) -> IO b
to glue together IO actions, and it would all work out basically the same. We use the generic Monad
API for IO
not because we have to, but because it lets us reuse convenient syntax and libraries. Indeed, you can introduce IO without mentioning Monad
at all.
I heard monads are like burritos or space suits full of nuclear waste. Is that true?
These analogies are not helpful. See "Abstraction, intuition, and the 'monad tutorial fallacy"'.
I can use monads but I feel like I still don't "get" them. What am I missing?
You're not necessarily missing anything. "Monad" is just the name of a generic API that applies to many different types. The types implementing the Monad API don't have a lot in common.
You might want to read "Typeclassopedia" to see how Monad fits in with other similar APIs.
What's the difference between State s
and ST s
monads?
State s
and ST s
monads?State s a is just a wrapper for the function type s -> (a, s)
: a function that takes an "old state" and returns a "new state" along with its result. You can implement State
in a few lines of standard Haskell, without any special help from the compiler.
ST
gives you true mutable variables with in-place update. You can't implement it yourself in standard Haskell. In GHC, STRef
and IORef
will behave the same way at runtime. The difference is the extra compile-time safety checking associated with runST
.
Concurrency and parallelism
See also notes on parallel and concurrent programming.
How can I do X without resorting to threads?
That's usually the wrong attitude. Threads are useful for solving problems. The attitude comes from other languages where some combination of the following holds:
- Per-thread overhead consumes a lot of memory or CPU
- Thread APIs are cumbersome, sometimes due to lacking first-class functions or IO actions
- The thread implementation is fundamentally broken, e.g. a global interpreter lock
- Threads break easily because programs constantly mutate implicitly-shared state
None of these is true in GHC Haskell. Threads have disadvantages and are not always the right tool. But avoiding them at all costs is counterproductive.
What's the difference between concurrency and parallelism?
Briefly: concurrency describes semantics; parallelism describes an implementation property.
Concurrent programs are written with explicit threads of control. Concurrent semantics fit naturally with certain real-world problems, like a network server talking to many simultaneous clients. This is still a nice model for writing a network server, even if you only intend to run it on one CPU core — concurrency without parallelism.
Parallel programs are those which run on multiple CPU cores simultaneously, regardless of how they were implemented.
Concurrency is a popular way to obtain parallel performance, but converting a pure computation to use concurrent semantics is difficult and error-prone. GHC Haskell provides "semi-implicit parallelism" as an alternative. Adding these "annotations" to a program cannot change its behavior.
There's a longer discussion on the GHC blog.
How do par
, pseq
, and seq
relate?
par
, pseq
, and seq
relate?The expression par x y
is semantically equivalent to y
, but suggests to the runtime system that evaluating x
in parallel might be a good idea. Usually x
would be a variable referring to a thunk (unevaluated expression) that will later be needed.
Now consider par x (x+y)
. Evaluating this expression suggests evaluating x
in parallel. But before the runtime system can act on that suggestion, we evaluate (x+y)
, which will evaluate both x
and y
in sequence. It would be better to work on y
for a while, and only demand x
later, after perhaps some parallel work has occurred. We can use pseq
to force this evaluation order, as in par x (pseq y (x+y))
.
The Strategies module provides a nicer interface to these par
/ pseq
tricks.
seq
is similar to pseq
but provides a weaker guarantee. The details are subtle; suffice to say that if you're controlling evaluation order, you want pseq
.
How do I do event-based IO in GHC Haskell? Should I call select, epoll, etc?
No; just do blocking IO from multiple threads, and GHC's runtime system will make these calls for you. GHC Haskell gives you the performance benefits of event-based IO without making you turn your code inside-out.
Threads in GHC are lightweight — both in performance and in the mental effort of using them. You can handle ten thousand concurrent requests at high throughput with a naive "one thread per client" model.
What's the difference between forkIO
and forkOS
?
forkIO
and forkOS
?It only matters if you're calling into a C library that cares about thread-local state. In that case, forkOS
guarantees that the C library will see the same OS thread each time. Any difference beyond that is an implementation detail and subject to change.
How can I wait for a thread to finish and produce a result?
There's a few libraries for this on Hackage, like async, spawn, and threads.
It's not hard to implement this yourself using MVar, though it's harder to get the exception handling right.
IRC
What does lambdabot's "info" command do?
At first, it seems like it just echoes whatever you type:
<user> ?info foo bar baz <lambdabot> foo bar baz
What is actually happening is that it autocorrects to the "undo" command, which desugars do blocks according to the Report's rules. So, a more interesting example might look like this:
<user> ?info do { foo; x <- bar; baz } <lambdabot> foo >> bar >>= \ x -> baz
Error messages and warnings
Not in scope: `catch'
The function "catch" is removed from Prelude, add the line:
import Control.Exception
(Note, that this might lead to an error if you compile the same code with an older GHC.)