https://wiki.haskell.org/api.php?action=feedcontributions&user=Henk-Jan+van+Tuyl&feedformat=atomHaskellWiki - User contributions [en]2020-11-27T15:18:27ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=All_About_Monads&diff=63505All About Monads2020-11-16T20:03:39Z<p>Henk-Jan van Tuyl: updated some links.</p>
<hr />
<div>''All About Monads'' is a tutorial on monads and monad transformers and a walk-through of common monad instances. You can download a PDF version [https://www.cs.rit.edu/~swm/cs561/All_About_Monads.pdf here]. And [https://web.archive.org/web/20061211101052/https://www.nomaware.com/monads/html/index.html here] is a version of the article which includes [https://web.archive.org/web/20061210172052/https://www.nomaware.com/monads/html/examples.html source code].<br />
<br />
= Understanding Monads =<br />
<br />
== Introduction ==<br />
<br />
=== What is a monad? ===<br />
<br />
A monad is a way to structure computations in terms of values and sequences of computations using those values. Monads allow the programmer to build up computations using sequential building blocks, which can themselves be sequences of computations. The monad determines how combined computations form a new computation and frees the programmer from having to code the combination manually each time it is required.<br />
<br />
''It is useful to think of a monad as a strategy for combining computations into more complex computations.'' For example, you should be familiar with the <code>Maybe</code> type in Haskell:<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
</haskell><br />
which represents the type of computations which may fail to return a result. The <code>Maybe</code> type suggests a strategy for combining computations which return <code>Maybe</code> values: if a combined computation consists of one computation <code>B</code> that depends on the result of another computation <code>A</code>, then the combined computation should yield <code>Nothing</code> whenever either <code>A</code> or <code>B</code> yield <code>Nothing</code> and the combined computation should yield the result of <code>B</code> applied to the result of <code>A</code> when both computations succeed.<br />
<br />
Other monads exist for building computations that perform I/O, have state, may return multiple results, etc. There are as many different type of monads as there are strategies for combining computations, but there are certain monads that are especially useful and are common enough that they are part of the standard [https://www.haskell.org/onlinereport/haskell2010/ Haskell 2010 libraries]. These monads are each described in [[introII.html|Part II]].<br />
<br />
=== Why should I make the effort to understand monads? ===<br />
<br />
The sheer number of different [https://www.haskell.org/haskellwiki/Monad_tutorials_timeline monad tutorials] on the internet is a good indication of the difficulty many people have understanding the concept. This is due to the abstract nature of monads and to the fact that they are used in several different capacities, which can confuse the picture of exactly what a monad is and what it is good for.<br />
<br />
In Haskell, monads play a central role in the I/O system. It is not essential to understand monads to do I/O in Haskell, but understanding the I/O monad will improve your code and extend your capabilities.<br />
<br />
For the programmer, monads are useful tools for structuring functional programs. They have three properties that make them especially useful:<br />
<br />
# Modularity - They allow computations to be composed from simpler computations and separate the combination strategy from the actual computations being performed.<br />
# Flexibility - They allow functional programs to be much more adaptable than equivalent programs written without monads. This is because the monad distills the computational strategy into a single place instead of requiring it be distributed throughout the entire program.<br />
# Isolation - They can be used to create imperative-style computational structures which remain safely isolated from the main body of the functional program. This is useful for incorporating side-effects (such as I/O) and state (which violates referential transparency) into a pure functional language like Haskell.<br />
<br />
Each of these features will be revisited later in the tutorial in the context of specific monads.<br />
<br />
== Meet the Monads ==<br />
<br />
We will use the <code>Maybe</code> type constructor throughout this chapter, so you should familiarize yourself with the definition and usage of [https://www.haskell.org/onlinelibrary/maybe.html <code>Maybe</code>] before continuing.<br />
<br />
=== Type constructors ===<br />
<br />
To understand monads in Haskell, you need to be comfortable dealing with type constructors. A ''type constructor'' is a parameterized type definition used with polymorphic types. By supplying a type constructor with one or more concrete types, you can construct a new concrete type in Haskell. In the definition of <code>Maybe</code>:<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
</haskell><br />
<code>Maybe</code> is a type constructor and <code>Nothing</code> and <code>Just</code> are data constructors. You can construct a data value by applying the <code>Just</code> data constructor to a value:<br />
<br />
<haskell><br />
country = Just "China"<br />
</haskell><br />
In the same way, you can construct a type by applying the <code>Maybe</code> type constructor to a type:<br />
<br />
<haskell><br />
lookupAge :: DB -> String -> Maybe Int<br />
</haskell><br />
Polymorphic types are like containers that are capable of holding values of many different types. So <code>Maybe Int</code> can be thought of as a <code>Maybe</code> container holding an <code>Int</code> value (or <code>Nothing</code>) and <code>Maybe String</code> would be a <code>Maybe</code> container holding a <code>String</code> value (or <code>Nothing</code>). In Haskell, we can also make the type of the container polymorphic, so we could write &quot;<code>m a</code>&quot; to represent a container of some type holding a value of some type!<br />
<br />
We often use type variables with type constructors to describe abstract features of a computation. For example, the polymorphic type <code>Maybe a</code> is the type of all computations that may return a value or <code>Nothing</code>. In this way, we can talk about the properties of the container apart from any details of what the container might hold.<br />
<br />
[[Image:info.png]] If you get messages about &quot;kind errors&quot; from the compiler when working with monads, it means that you are not using the type constructors correctly. <br /><br />
<br />
=== Maybe a monad ===<br />
<br />
In Haskell a monad is represented as a type constructor (call it <code>m</code>), a function that builds values of that type (<code>a -> m a</code>), and a function that combines values of that type with computations that produce values of that type to produce a new computation for values of that type (<code>m a -> (a -> m b) -> m b</code>). Note that the container is the same, but the type of the contents of the container can change. It is customary to call the monad type constructor &quot;<code>m</code>&quot; when discussing monads in general. The function that builds values of that type is traditionally called &quot;<code>return</code>&quot; and the third function is known as &quot;bind&quot; but is written &quot;<code>>>=</code>&quot;. The signatures of the functions are:<br />
<br />
<haskell><br />
-- the type of monad m<br />
data m a = ...<br />
<br />
-- return takes a value and embeds it in the monad.<br />
return :: a -> m a<br />
<br />
-- bind is a function that combines a monad instance m a with a computation<br />
-- that produces another monad instance m b from a's to produce a new<br />
-- monad instance m b<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
</haskell><br />
Roughly speaking, the monad type constructor defines a type of computation, the <code>return</code> function creates primitive values of that computation type and <code>>>=</code> combines computations of that type together to make more complex computations of that type. Using the container analogy, the type constructor <code>m</code> is a container that can hold different values. <code>m a</code> is a container holding a value of type <code>a</code>. The <code>return</code> function puts a value into a monad container. The <code>>>=</code> function takes the value from a monad container and passes it to a function to produce a monad container containing a new value, possibly of a different type. The <code>>>=</code> function is known as &quot;bind&quot; because it binds the value in a monad container to the first argument of a function. By adding logic to the binding function, a monad can implement a specific strategy for combining computations in the monad.<br />
<br />
This will all become clearer after the example below, but if you feel particularly confused at this point you might try looking at this [https://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html#monads picture of monads] before continuing.<br />
<br />
=== An example ===<br />
<br />
Suppose that we are writing a program to keep track of sheep cloning experiments. We would certainly want to know the genetic history of all of our sheep, so we would need <code>mother</code> and <code>father</code> functions. But since these are cloned sheep, they may not always have both a mother and a father!<br />
<br />
We would represent the possibility of not having a mother or father using the <code>Maybe</code> type constructor in our Haskell code:<br />
<br />
<haskell><br />
type Sheep = ...<br />
<br />
father :: Sheep -> Maybe Sheep<br />
father = ...<br />
<br />
mother :: Sheep -> Maybe Sheep<br />
mother = ...<br />
</haskell><br />
Then, defining functions to find grandparents is a little more complicated, because we have to handle the possibility of not having a parent:<br />
<br />
<haskell><br />
maternalGrandfather :: Sheep -> Maybe Sheep<br />
maternalGrandfather s = case (mother s) of<br />
Nothing -> Nothing<br />
Just m -> father m<br />
</haskell><br />
and so on for the other grandparent combinations.<br />
<br />
It gets even worse if we want to find great grandparents:<br />
<br />
<haskell><br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = case (mother s) of<br />
Nothing -> Nothing<br />
Just m -> case (father m) of<br />
Nothing -> Nothing<br />
Just gf -> father gf<br />
</haskell><br />
Aside from being ugly, unclear, and difficult to maintain, this is just too much work. It is clear that a <code>Nothing</code> value at any point in the computation will cause <code>Nothing</code> to be the final result, and it would be much nicer to implement this notion once in a single place and remove all of the explicit <code>case</code> testing scattered all over the code. This will make the code easier to write, easier to read and easier to change. So good programming style would have us create a combinator that captures the behavior we want:<br />
<br />
=== Example 1 ===<br />
<br />
<haskell><br />
-- comb is a combinator for sequencing operations that return Maybe<br />
comb :: Maybe a -> (a -> Maybe b) -> Maybe b<br />
comb Nothing _ = Nothing<br />
comb (Just x) f = f x<br />
<br />
-- now we can use `comb` to build complicated sequences<br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = (Just s) `comb` mother `comb` father `comb` father<br />
</haskell><br />
The combinator is a huge success! The code is much cleaner and easier to write, understand and modify. Notice also that the <code>comb</code> function is entirely polymorphic — it is not specialized for <code>Sheep</code> in any way. In fact, ''the combinator captures a general strategy for combining computations that may fail to return a value.'' Thus, we can apply the same combinator to other computations that may fail to return a value, such as database queries or dictionary lookups.<br />
<br />
The happy outcome is that common sense programming practice has led us to create a monad without even realizing it. The <code>Maybe</code> type constructor along with the <code>Just</code> function (acts like <code>return</code>) and our combinator (acts like <code>>>=</code>) together form a simple monad for building computations which may not return a value. All that remains to make this monad truly useful is to make it conform to the monad framework built into the Haskell language. That is the subject of the next chapter.<br />
<br />
=== List is also a monad ===<br />
<br />
We have seen that the <code>Maybe</code> type constructor is a monad for building computations which may fail to return a value. You may be surprised to know that another common Haskell type constructor, <code>[]</code> (for building lists), is also a monad. The List monad allows us to build computations which can return 0, 1, or more values.<br />
<br />
The <code>return</code> function for lists simply creates a singleton list (<code>return x = [x]</code>). The binding operation for lists creates a new list containing the results of applying the function to all of the values in the original list (<code>l >>= f = concatMap f l</code>).<br />
<br />
One use of functions which return lists is to represent ''ambiguous'' computations — that is computations which may have 0, 1, or more allowed outcomes. In a computation composed from ambigous subcomputations, the ambiguity may compound, or it may eventually resolve into a single allowed outcome or no allowed outcome at all. During this process, the set of possible computational states is represented as a list. The List monad thus embodies a strategy for performing simultaneous computations along all allowed paths of an ambiguous computation.<br />
<br />
Examples of this use of the List monad, and contrasting examples using the Maybe monad will be presented shortly. But first, we must see how useful monads are defined in Haskell.<br />
<br />
=== Summary ===<br />
<br />
We have seen that a monad is a type constructor, a function called <code>return</code>, and a combinator function called <code>bind</code> or <code>>>=</code>. These three elements work together to encapsulate a strategy for combining computations to produce more complex computations.<br />
<br />
Using the <code>Maybe</code> type constructor, we saw how good programming practice led us to define a simple monad that could be used to build complex computations out of sequences of computations that could each fail to return a value. The resulting <code>Maybe</code> monad encapsulates a strategy for combining computations that may not return values. By codifying the strategy in a monad, we have achieved a degree of modularity and flexibility that is not present when the computations are combined in an ad hoc manner.<br />
<br />
We have also seen that another common Haskell type constructor, <code>[]</code>, is a monad. The List monad encapsulates a strategy for combining computations that can return 0, 1, or multiple values.<br />
<br />
== Doing it with class ==<br />
<br />
=== Haskell type classes ===<br />
<br />
The discussion in this chapter involves the Haskell type class system. If you are not familiar with type classes in Haskell, you should [https://www.haskell.org/tutorial/classes.html review them] before continuing.<br />
<br />
=== The Monad class ===<br />
<br />
In Haskell, there is a standard <code>Monad</code> class that defines the names and signatures of the two monad functions <code>return</code> and <code>>>=</code>. It is not strictly necessary to make your monads instances of the <code>Monad</code> class, but it is a good idea. Haskell has special support for <code>Monad</code> instances built into the language and making your monads instances of the <code>Monad</code> class will allow you to use these features to write cleaner and more elegant code. Also, making your monads instances of the <code>Monad</code> class communicates important information to others who read the code and failing to do so can cause you to use confusing and non-standard function names. It's easy to do and it has many benefits, so just do it!<br />
<br />
The standard <code>Monad</code> class definition in Haskell looks something like this:<br />
<br />
<haskell><br />
class Monad m where<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
return :: a -> m a<br />
</haskell><br />
=== Example continued ===<br />
<br />
Continuing the [[meet.html#example1|previous example]], we will now see how the <code>Maybe</code> type constructor fits into the Haskell monad framework as an instance of the <code>Monad</code> class.<br />
<br />
Recall that our <code>Maybe</code> monad used the <code>Just</code> data constructor to fill the role of the monad <code>return</code> function and we built a simple combinator to fill the role of the monad <code>>>=</code> binding function. We can make its role as a monad explicit by declaring <code>Maybe</code> as an instance of the <code>Monad</code> class:<br />
<br />
<haskell><br />
instance Monad Maybe where<br />
Nothing >>= f = Nothing<br />
(Just x) >>= f = f x<br />
return = Just<br />
</haskell><br />
Once we have defined <code>Maybe</code> as an instance of the Monad class, we can use the standard monad operators to build the complex computations:<br />
<br />
<haskell><br />
-- we can use monadic operations to build complicated sequences<br />
maternalGrandfather :: Sheep -> Maybe Sheep<br />
maternalGrandfather s = (return s) >>= mother >>= father<br />
<br />
fathersMaternalGrandmother :: Sheep -> Maybe Sheep<br />
fathersMaternalGrandmother s = (return s) >>= father >>= mother >>= mother<br />
</haskell><br />
In Haskell, <code>Maybe</code> is defined as an instance of the <code>Monad</code> class in the standard prelude, so you don't need to do it yourself. The other monad we have seen so far, the list constructor, is also defined as an instance of the <code>Monad</code> class in the standard prelude.<br />
<br />
[[Image:info.png]] When writing functions that work with monads, try to make use of the <code>Monad</code> class instead of using a specific monad instance. A function of the type<br />
<br />
<haskell><br />
doSomething :: (Monad m) ==> a -> m b<br />
</haskell><br />
is much more flexible than one of the type<br />
<br />
<haskell><br />
doSomething :: a -> Maybe b<br />
</haskell><br />
The former function can be used with many types of monads to get different behavior depending on the strategy embodied in the monad, whereas the latter function is restricted to the strategy of the <code>Maybe</code> monad.<br />
<br />
=== Do notation ===<br />
<br />
Using the standard monadic function names is good, but another advantage of membership in the <code>Monad</code> class is the Haskell support for &quot;do&quot; notation. Do notation is an expressive shorthand for building up monadic computations, similar to the way that list comprehensions are an expressive shorthand for building computations on lists. Any instance of the <code>Monad</code> class can be used in a do-block in Haskell.<br />
<br />
In short, the do notation allows you to write monadic computations using a pseudo-imperative style with named variables. The result of a monadic computation can be &quot;assigned&quot; to a variable using a left arrow <code><-</code> operator. Then using that variable in a subsequent monadic computation automatically performs the binding. The type of the expression to the right of the arrow is a monadic type <code>m a</code>. The expression to the left of the arrow is a pattern to be matched against the value ''inside'' the monad. <code>(x:xs)</code> would match against <code>Maybe [1,2,3]</code>, for example.<br />
<br />
Here is a sample of do notation using the <code>Maybe</code> monad:<br />
<br />
=== Example 2 ===<br />
<br />
<haskell><br />
-- we can also use do-notation to build complicated sequences<br />
mothersPaternalGrandfather :: Sheep -> Maybe Sheep<br />
mothersPaternalGrandfather s = do m <- mother s<br />
gf <- father m<br />
father gf<br />
</haskell><br />
Compare this to <code>fathersMaternalGrandmother</code> written above without using do notation.<br />
<br />
The do block shown above is written using the layout rule to define the extent of the block. Haskell also allows you to use braces and semicolons when defining a do block:<br />
<br />
<haskell><br />
mothersPaternalGrandfather s = do { m <- mother s; gf <- father m; father gf }<br />
</haskell><br />
Notice that do notation resembles an imperative programming language, in which a computation is built up from an explicit sequence of simpler computations. In this respect, monads offer the possibility to create imperative-style computations within a larger functional program. This theme will be expanded upon when we deal with side-effects and the I/O monad later.<br />
<br />
Do notation is simply syntactic sugar. There is nothing that can be done using do notation that cannot be done using only the standard monadic operators. But do notation is cleaner and more convenient in some cases, especially when the sequence of monadic computations is long. You should understand both the standard monadic binding notation and do notation and be able to apply each where they are appropriate.<br />
<br />
The actual translation from do notation to standard monadic operators is roughly that every expression matched to a pattern, <code>x <- expr1</code>, becomes<br />
<br />
<haskell><br />
expr1 >>= \x -><br />
</haskell><br />
and every expression without a variable assignment, <code>expr2</code> becomes<br />
<br />
<haskell><br />
expr2 >>= \_ -><br />
</haskell><br />
All do blocks must end with a monadic expression, and a let clause is allowed at the beginning of a do block (but let clauses in do blocks do not use the &quot;in&quot; keyword). The definition of <code>mothersPaternalGrandfather</code> above would be translated to:<br />
<br />
<haskell><br />
mothersPaternalGrandfather s = mother s >>= (\m -><br />
father m >>= (\gf -><br />
father gf))<br />
</haskell><br />
<br />
(The parentheses are for clarity and aren't actually required.)<br />
<br />
It now becomes clear why the binding operator is so named. It is literally used to bind the value in the monad to the argument in the following lambda expression.<br />
<br />
=== Summary ===<br />
<br />
Haskell provides built-in support for monads. To take advantage of Haskell's monad support, you must declare the monad type constructor to be an instance of the <code>Monad</code> class and supply definitions of the <code>return</code> and <code>>>=</code> (pronounced &quot;bind&quot;) functions for the monad.<br />
<br />
A monad that is an instance of the <code>Monad</code> class can be used with do-notation, which is syntactic sugar that provides a simple, imperative-style notation for describing computations with monads.<br />
<br />
== The monad laws ==<br />
<br />
The tutorial up to now has avoided technical discussions, but there are a few technical points that must be made concerning monads. Monadic operations must obey a set of laws, known as &quot;the monad axioms&quot;. These laws aren't enforced by the Haskell compiler, so it is up to the programmer to ensure that any <code>Monad</code> instances they declare obey the laws. Haskell's <code>Monad</code> class also includes some functions beyond the minimal complete definition that we have not seen yet. Finally, many monads obey additional laws beyond the standard monad laws, and there is an additional Haskell class to support these extended monads.<br />
<br />
=== The three fundamental laws ===<br />
<br />
The concept of a monad comes from a branch of mathematics called category theory. While it is not necessary to know category theory to create and use monads, we do need to obey a small bit of mathematical formalism. To create a monad, it is not enough just to declare a Haskell instance of the <code>Monad</code> class with the correct type signatures. To be a proper monad, the <code>return</code> and <code>>>=</code> functions must work together according to three laws:<br />
<br />
# <code>(return x) >>= f ==== f x</code><br />
# <code>m >>= return ==== m</code><br />
# <code>(m >>= f) >>= g ==== m >>= (\x -> f x >>= g)</code><br />
<br />
The first law requires that <code>return</code> is a left-identity with respect to <code>>>=</code>. The second law requires that <code>return</code> is a right-identity with respect to <code>>>=</code>. The third law is a kind of associativity law for <code>>>=</code>. Obeying the three laws ensures that the semantics of the do-notation using the monad will be consistent.<br />
<br />
Any type constructor with return and bind operators that satisfy the three monad laws is a monad. In Haskell, the compiler does not check that the laws hold for every instance of the <code>Monad</code> class. It is up to the programmer to ensure that any <code>Monad</code> instance they create satisfies the monad laws.<br />
<br />
=== Failure IS an option ===<br />
<br />
The definition of the <code>Monad</code> class given [[class.html#monad|earlier]] showed only the minimal complete definition. The full definition of the <code>Monad</code> class actually includes two additional functions: <code>fail</code> and <code>>></code>.<br />
<br />
The default implementation of the <code>fail</code> function is:<br />
<br />
<haskell><br />
fail s = error s<br />
</haskell><br />
You do not need to change this for your monad unless you want to provide different behavior for failure or to incorporate failure into the computational strategy of your monad. The <code>Maybe</code> monad, for instance, defines <code>fail</code> as:<br />
<br />
<haskell><br />
fail _ = Nothing<br />
</haskell><br />
so that <code>fail</code> returns an instance of the <code>Maybe</code> monad with meaningful behavior when it is bound with other functions in the <code>Maybe</code> monad.<br />
<br />
The <code>fail</code> function is not a required part of the mathematical definition of a monad, but it is included in the standard <code>Monad</code> class definition because of the role it plays in Haskell's do notation. The <code>fail</code> function is called whenever a pattern matching failure occurs in a do block:<br />
<br />
<haskell><br />
fn :: Int -> Maybe [Int]<br />
fn idx = do let l = [Just [1,2,3], Nothing, Just [], Just [7..20]]<br />
(x:xs) <- l!!idx -- a pattern match failure will call "fail"<br />
return xs<br />
</haskell><br />
So in the code above, <code>fn 0</code> has the value <code>Just [2,3]</code>, but <code>fn 1</code> and <code>fn 2</code> both have the value <code>Nothing</code>.<br />
<br />
The <code>>></code> function is a convenience operator that is used to bind a monadic computation that does not require input from the previous computation in the sequence. It is defined in terms of <code>>>=</code>:<br />
<br />
<haskell><br />
(>>) :: m a -> m b -> m b<br />
m >> k = m >>= (\_ -> k)<br />
</haskell><br />
=== No way out ===<br />
<br />
You might have noticed that there is no way to get values out of a monad as defined in the standard <code>Monad</code> class. That is not an accident. Nothing prevents the monad author from allowing it using functions specific to the monad. For instance, values can be extracted from the <code>Maybe</code> monad by pattern matching on <code>Just x</code> or using the <code>fromJust</code> function.<br />
<br />
By not requiring such a function, the Haskell <code>Monad</code> class allows the creation of one-way monads. One-way monads allow values to enter the monad through the <code>return</code> function (and sometimes the <code>fail</code> function) and they allow computations to be performed within the monad using the bind functions <code>>>=</code> and <code>>></code>, but they do not allow values back out of the monad.<br />
<br />
The <code>IO</code> monad is a familiar example of a one-way monad in Haskell. Because you can't escape from the <code>IO</code> monad, it is impossible to write a function that does a computation in the <code>IO</code> monad but whose result type does not include the <code>IO</code> type constructor. This means that ''any'' function whose result type does not contain the <code>IO</code> type constructor is guaranteed not to use the <code>IO</code> monad. Other monads, such as <code>List</code> and <code>Maybe</code>, do allow values out of the monad. So it is possible to write functions which use these monads internally but return non-monadic values.<br />
<br />
''The wonderful feature of a one-way monad is that it can support side-effects in its monadic operations but prevent them from destroying the functional properties of the non-monadic portions of the program.''<br />
<br />
Consider the simple issue of reading a character from the user. We cannot simply have a function <code>readChar :: Char</code>, because it needs to return a different character each time it is called, depending on the input from the user. It is an essential property of Haskell as a pure functional language that all functions return the same value when called twice with the same arguments. But it ''is'' ok to have an I/O function <code>getChar :: IO Char</code> in the <code>IO</code> monad, because it can only be used in a sequence within the one-way monad. There is no way to get rid of the <code>IO</code> type constructor in the signature of any function that uses it, so the <code>IO</code> type constructor acts as a kind of tag that identifies all functions that do I/O. Furthermore, such functions are only useful within the <code>IO</code> monad. So a one-way monad effectively creates an isolated computational domain in which the rules of a pure functional language can be relaxed. Functional computations can move into the domain, but dangerous side-effects and non-referentially-transparent functions cannot escape from it.<br />
<br />
Another common pattern when defining monads is to represent monadic values as functions. Then when the value of a monadic computation is required, the resulting monad is &quot;run&quot; to provide the answer.<br />
<br />
=== Zero and Plus ===<br />
<br />
Beyond the three monad laws stated above, some monads obey additional laws. These monads have a special value <code>mzero</code> and an operator <code>mplus</code> that obey four additional laws:<br />
<br />
# <code>mzero >>= f == mzero</code><br />
# <code>m >>= (\x -> mzero) == mzero</code><br />
# <code>mzero `mplus` m == m</code><br />
# <code>m `mplus` mzero == m</code><br />
<br />
It is easy to remember the laws for <code>mzero</code> and <code>mplus</code> if you associate <code>mzero</code> with 0, <code>mplus</code> with +, and <code>>>=</code> with × in ordinary arithmetic.<br />
<br />
Monads which have a zero and a plus can be declared as instances of the <code>MonadPlus</code> class in Haskell:<br />
<br />
<haskell><br />
class (Monad m) ==> MonadPlus m where<br />
mzero :: m a<br />
mplus :: m a -> m a -> m a<br />
</haskell><br />
Continuing to use the <code>Maybe</code> monad as an example, we see that the <code>Maybe</code> monad is an instance of <code>MonadPlus</code>:<br />
<br />
<haskell><br />
instance MonadPlus Maybe where<br />
mzero = Nothing<br />
Nothing `mplus` x = x<br />
x `mplus` _ = x<br />
</haskell><br />
This identifies <code>Nothing</code> as the zero value and says that adding two <code>Maybe</code> values together gives the first value that is not <code>Nothing</code>. If both input values are <code>Nothing</code>, then the result of <code>mplus</code> is also <code>Nothing</code>.<br />
<br />
The List monad also has a zero and a plus. <code>mzero</code> is the empty list and <code>mplus</code> is the <code>++</code> operator.<br />
<br />
The <code>mplus</code> operator is used to combine monadic values from separate computations into a single monadic value. Within the context of our sheep-cloning example, we could use <code>Maybe</code>'s <code>mplus</code> to define a function, <code>parent s = (mother s) `mplus` (father s)</code>, which would return a parent if there is one, and <code>Nothing</code> is the sheep has no parents at all. For a sheep with both parents, the function would return one or the other, depending on the exact definition of <code>mplus</code> in the <code>Maybe</code> monad.<br />
<br />
=== Summary ===<br />
<br />
Instances of the <code>Monad</code> class should conform to the so-called monad laws, which describe algebraic properties of monads. There are three of these laws which state that the <code>return</code> function is both a left and a right identity and that the binding operator is associative. Failure to satisfy these laws will result in monads that do not behave properly and may cause subtle problems when using do-notation.<br />
<br />
In addition to the <code>return</code> and <code>>>=</code> functions, the <code>Monad</code> class defines another function, <code>fail</code>. The <code>fail</code> function is not a technical requirement for inclusion as a monad, but it is often useful in practice and it is included in the <code>Monad</code> class because it is used in Haskell's do-notation.<br />
<br />
Some monads obey laws beyond the three basic monad laws. An important class of such monads are ones which have a notion of a zero element and a plus operator. Haskell provides a <code>MonadPlus</code> class for such monads which define the <code>mzero</code> value and the <code>mplus</code> operator.<br />
<br />
== Exercises ==<br />
<br />
# [[#exercise1|Do notation]]<br />
# [[#exercise2|Combining monadic values]]<br />
# [[#exercise3|Using the List monad]]<br />
# [[#exercise4|Using the Monad class constraint]]<br />
<br />
This section contains a few simple exercises to hone the reader's monadic reasoning skills and to provide a solid comprehension of the function and use of the Maybe and List monads before looking at monadic programming in more depth. The exercises will build on the previous sheep-cloning [[../examples/example2.hs|example]], with which the reader should already be familiar.<br />
<br />
=== Exercise 1: Do notation ===<br />
<br />
Rewrite the <code>maternalGrandfather</code>, <code>fathersMaternalGrandmother</code>, and <code>mothersPaternalGrandfather</code> functions in [[../examples/example2.hs|Example 2]] using the monadic operators <code>return</code> and <code>>>=</code>, without using any do-notation syntactic sugar.<br />
<br />
<br />
<br />
Click [[solution1.html|here]] to see the solution.<br />
<br />
=== Exercise 2: Combining monadic values ===<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>Sheep -> Maybe Sheep</code>. They should return one sheep selected from all sheep matching the description, or <code>Nothing</code> if there is no such sheep. Hint: the <code>mplus</code> operator is useful here.<br />
<br />
Click [[solution2.html|here]] to see the solution.<br />
<br />
=== Exercise 3: Using the List monad ===<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>Sheep -> [Sheep]</code>. They should return all sheep matching the description, or the empty list if there is no such sheep. Hint: the <code>mplus</code> operator in the List monad is useful here. Also the <code>maybeToList</code> function in the <code>Maybe</code> module can be used to convert a value from the Maybe monad to the List monad.<br />
<br />
Click [[solution3.html|here]] to see the solution.<br />
<br />
=== Exercise 4: Using the Monad class constraint ===<br />
<br />
Monads promote modularity and code reuse by encapsulating often-used computational strategies into single blocks of code that can be used to construct many different computations. Less obviously, monads also promote modularity by allowing you to vary the monad in which a computation is done to achieve different variations of the computation. This is achieved by writing functions which are polymorphic in the monad type constructor, using the <code>(Monad m) ==></code>, <code>(MonadPlus m) ==></code>, etc. class constraints.<br />
<br />
Write functions <code>parent</code> and <code>grandparent</code> with signature <code>(MonadPlus m) ==> Sheep -> m Sheep</code>. They should be useful in both the Maybe and List monads. How does the functions' behavior differ when used with the List monad versus the Maybe monad? If you need to review the use of type classes and class constraints in Haskell, look [https://www.haskell.org/tutorial/classes.html here].<br />
<br />
Click [[solution4.html|here]] to see the solution.<br />
<br />
== Monad support in Haskell ==<br />
<br />
Haskell's built in support for monads is split among the standard prelude, which exports the most common monad functions, and the Monad module, which contains less-commonly used monad functions. The individual monad types are each in their own libraries and are the subject of [[introII.html|Part II]] of this tutorial.<br />
<br />
=== In the standard prelude ===<br />
<br />
The Haskell 2010 [https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-1110005.6 standard prelude] includes the definition of the <code>Monad</code> class as well as a few auxilliary functions for working with monadic data types.<br />
<br />
==== The <code>Monad</code> class ====<br />
<br />
We have seen the <code>Monad</code> class before:<br />
<br />
<haskell><br />
class Monad m where<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
(>>) :: m a -> m b -> m b<br />
return :: a -> m a<br />
fail :: String -> m a<br />
<br />
-- Minimal complete definition:<br />
-- (>>=), return<br />
m >> k = m >>= \_ -> k<br />
fail s = error s<br />
</haskell><br />
==== The sequencing functions ====<br />
<br />
The <code>sequence</code> function takes a list of monadic computations, executes each one in turn and returns a list of the results. If any of the computations fail, then the whole function fails:<br />
<br />
<haskell><br />
sequence :: Monad m ==> [m a] -> m [a]<br />
sequence = foldr mcons (return [])<br />
where mcons p q = p >>= \x -> q >>= \y -> return (x:y)<br />
</haskell><br />
The <code>sequence_</code> function (notice the underscore) has the same behavior as <code>sequence</code> but does not return a list of results. It is useful when only the side-effects of the monadic computations are important.<br />
<br />
<haskell><br />
sequence_ :: Monad m ==> [m a] -> m ()<br />
sequence_ = foldr (>>) (return ())<br />
</haskell><br />
==== The mapping functions ====<br />
<br />
The <code>mapM</code> function maps a monadic computation over a list of values and returns a list of the results. It is defined in terms of the list <code>map</code> function and the <code>sequence</code> function above:<br />
<br />
<haskell><br />
mapM :: Monad m ==> (a -> m b) -> [a] -> m [b]<br />
mapM f as = sequence (map f as)<br />
</haskell><br />
There is also a version with an underscore, <code>mapM_</code> which is defined using sequence_. <code>mapM_</code> operates the same as <code>mapM</code>, but it doesn't return the list of values. It is useful when only the side-effects of the monadic computation are important.<br />
<br />
<haskell><br />
mapM_ :: Monad m ==> (a -> m b) -> [a] -> m ()<br />
mapM_ f as = sequence_ (map f as)<br />
</haskell><br />
As a simple example of the use the mapping functions, a <code>putString</code> function for the <code>IO</code> monad could be defined as:<br />
<br />
<haskell><br />
putString :: [Char] -> IO ()<br />
putString s = mapM_ putChar s<br />
</haskell><br />
<code>mapM</code> can be used within a do block in a manner similar to the way the <code>map</code> function is normally used on lists. This is a common pattern with monads — a version of a function for use within a monad (i.e., intended for binding) will have a signature similar to the non-monadic version but the function outputs will be within the monad:<br />
<br />
<haskell><br />
-- compare the non-monadic and monadic signatures<br />
map :: (a -> b) -> [a] -> [b]<br />
mapM :: Monad m ==> (a -> m b) -> [a] -> m [b]<br />
</haskell><br />
==== The reverse binder function (<code>=<<</code>) ====<br />
<br />
The prelude also defines a binding function that takes it arguments in the opposite order to the standard binding function. Since the standard binding function is called &quot;<code>>>=</code>&quot;, the reverse binding function is called &quot;<code>=<<</code>&quot;. It is useful in circumstances where the binding operator is used as a higher-order term and it is more convenient to have the arguments in the reversed order. Its definition is simply:<br />
<br />
<haskell><br />
(=<<) :: Monad m ==> (a -> m b) -> m a -> m b<br />
f =<< x = x >>= f<br />
</haskell><br />
=== In the Monad module ===<br />
<br />
The <code>Monad</code> module in the standard Haskell 2010 libraries exports a number of facilities for more advanced monadic operations. To access these facilities, simply <code>import Monad</code> in your Haskell program.<br />
<br />
Not all of the function in the <code>Monad</code> module are discussed here, but you are encouraged to [https://www.haskell.org/onlinereport/haskell2010/haskellch13.html#x21-19300013 explore the module for yourself] when you feel you are ready to see some of the more esoteric monad functions.<br />
<br />
==== The <code>MonadPlus</code> class ====<br />
<br />
The <code>Monad</code> module defines the <code>MonadPlus</code> class for monads with a zero element and a plus operator:<br />
<br />
<haskell><br />
class Monad m ==> MonadPlus m where<br />
mzero :: m a<br />
mplus :: m a -> m a -> m a<br />
</haskell><br />
==== Monadic versions of list functions ====<br />
<br />
Several functions are provided which generalize standard list-processing functions to monads. The <code>mapM</code> functions are exported in the standard prelude and were described above.<br />
<br />
<code>foldM</code> is a monadic version of <code>foldl</code> in which monadic computations built from a list are bound left-to-right. The definition is:<br />
<br />
<haskell><br />
foldM :: (Monad m) ==> (a -> b -> m a) -> a -> [b] -> m a<br />
foldM f a [] = return a<br />
foldM f a (x:xs) = f a x >>= \y -> foldM f y xs<br />
</haskell><br />
but it is easier to understand the operation of <code>foldM</code> if you consider its effect in terms of a do block:<br />
<br />
<haskell><br />
-- this is not valid Haskell code, it is just for illustration<br />
foldM f a1 [x1,x2,...,xn] = do a2 <- f a1 x1<br />
a3 <- f a2 x2<br />
...<br />
f an xn<br />
</haskell><br />
Right-to-left binding is achieved by reversing the input list before calling <code>foldM</code>.<br />
<br />
We can use <code>foldM</code> to create a more poweful query function in our sheep cloning example:<br />
<br />
=== Example 3 ===<br />
<br />
<haskell><br />
-- traceFamily is a generic function to find an ancestor<br />
traceFamily :: Sheep -> [ (Sheep -> Maybe Sheep) ] -> Maybe Sheep<br />
traceFamily s l = foldM getParent s l<br />
where getParent s f = f s<br />
<br />
-- we can define complex queries using traceFamily in an easy, clear way<br />
mothersPaternalGrandfather s = traceFamily s [mother, father, father]<br />
paternalGrandmother s = traceFamily s [father, mother]<br />
</haskell><br />
The <code>traceFamily</code> function uses <code>foldM</code> to create a simple way to trace back in the family tree to any depth and in any pattern. In fact, it is probably clearer to write &quot;<code>traceFamily s [father, mother]</code>&quot; than it is to use the <code>paternalGrandmother</code> function!<br />
<br />
A more typical use of <code>foldM</code> is within a do block:<br />
<br />
=== Example 4 ===<br />
<br />
<haskell><br />
-- a Dict is just a finite map from strings to strings<br />
type Dict = FiniteMap String String<br />
<br />
-- this an auxilliary function used with foldl<br />
addEntry :: Dict -> Entry -> Dict<br />
addEntry d e = addToFM d (key e) (value e)<br />
<br />
-- this is an auxiliiary function used with foldM inside the IO monad<br />
addDataFromFile :: Dict -> Handle -> IO Dict<br />
addDataFromFile dict hdl = do contents <- hGetContents hdl<br />
entries <- return (map read (lines contents))<br />
return (foldl (addEntry) dict entries)<br />
<br />
-- this program builds a dictionary from the entries in all files named on the<br />
-- command line and then prints it out as an association list<br />
main :: IO ()<br />
main = do files <- getArgs<br />
handles <- mapM openForReading files<br />
dict <- foldM addDataFromFile emptyFM handles<br />
print (fmToList dict)<br />
</haskell><br />
The <code>filterM</code> function works like the list <code>filter</code> function inside of a monad. It takes a predicate function which returns a Boolean value in the monad and a list of values. It returns, inside the monad, a list of those values for which the predicate was True.<br />
<br />
<haskell><br />
filterM :: Monad m ==> (a -> m Bool) -> [a] -> m [a]<br />
filterM p [] = return []<br />
filterM p (x:xs) = do b <- p x<br />
ys <- filterM p xs<br />
return (if b then (x:ys) else ys)<br />
</haskell><br />
Here is an example showing how <code>filterM</code> can be used within the <code>IO</code> monad to select only the directories from a list:<br />
<br />
=== Example 5 ===<br />
<br />
<haskell><br />
import Monad<br />
import Directory<br />
import System<br />
<br />
-- NOTE: doesDirectoryExist has type FilePath -> IO Bool<br />
<br />
-- this program prints only the directories named on the command line<br />
main :: IO ()<br />
main = do names <- getArgs<br />
dirs <- filterM doesDirectoryExist names<br />
mapM_ putStrLn dirs<br />
</haskell><br />
<code>zipWithM</code> is a monadic version of the <code>zipWith</code> function on lists. <code>zipWithM_</code> behaves the same but discards the output of the function. It is useful when only the side-effects of the monadic computation matter.<br />
<br />
<haskell><br />
zipWithM ::(Monad m) ==> (a -> b -> m c) -> [a] -> [b] -> m [c]<br />
zipWithM f xs ys = sequence (zipWith f xs ys)<br />
<br />
zipWithM_ ::(Monad m) ==> (a -> b -> m c) -> [a] -> [b] -> m ()<br />
zipWithM_ f xs ys = sequence_ (zipWith f xs ys)<br />
</haskell><br />
==== Conditional monadic computations ====<br />
<br />
There are two functions provided for conditionally executing monadic computations. The <code>when</code> function takes a boolean argument and a monadic computation with unit &quot;()&quot; type and performs the computation only when the boolean argument is <code>True</code>. The <code>unless</code> function does the same, except that it performs the computation ''unless'' the boolean argument is <code>True</code>.<br />
<br />
<haskell><br />
when :: (Monad m) ==> Bool -> m () -> m ()<br />
when p s = if p then s else return ()<br />
<br />
unless :: (Monad m) ==> Bool -> m () -> m ()<br />
unless p s = when (not p) s<br />
</haskell><br />
==== <code>ap</code> and the lifting functions ====<br />
<br />
''Lifting'' is a monadic operation that converts a non-monadic function into an equivalent function that operates on monadic values. We say that a function is &quot;lifted into the monad&quot; by the lifting operators. A lifted function is useful for operating on monad values outside of a do block and can also allow for cleaner code within a do block.<br />
<br />
The simplest lifting operator is <code>liftM</code>, which lifts a function of a single argument into a monad.<br />
<br />
<haskell><br />
liftM :: (Monad m) ==> (a -> b) -> (m a -> m b)<br />
liftM f = \a -> do { a' <- a; return (f a') }<br />
</haskell><br />
Lifting operators are also provided for functions with more arguments. <code>liftM2</code> lifts functions of two arguments:<br />
<br />
<haskell><br />
liftM2 :: (Monad m) ==> (a -> b -> c) -> (m a -> m b -> m c)<br />
liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') }<br />
</haskell><br />
The same pattern is applied to give the definitions to lift functions of more arguments. Functions up to <code>liftM5</code> are defined in the <code>Monad</code> module.<br />
<br />
To see how the lifting operators allow more concise code, consider a computation in the <code>Maybe</code> monad in which you want to use a function <code>swapNames::String -> String</code>. You could do:<br />
<br />
<haskell><br />
getName :: String -> Maybe String<br />
getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]<br />
tempName <- lookup name db<br />
return (swapNames tempName)<br />
</haskell><br />
But making use of the <code>liftM</code> function, we can use <code>liftM swapNames</code> as a function of type <code>Maybe String -> Maybe String</code>:<br />
<br />
=== Example 6 ===<br />
<br />
<haskell><br />
getName :: String -> Maybe String<br />
getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]<br />
liftM swapNames (lookup name db)<br />
</haskell><br />
The difference is even greater when lifting functions with more arguments.<br />
<br />
The lifting functions also enable very concise constructions using higher-order functions. To understand this example code, you might need to review the definition of the monad functions for the [[listmonad.html#definition|List monad]] (particularly <code>>>=</code>). Imagine how you might implement this function without lifting the operator:<br />
<br />
=== Example 7 ===<br />
<br />
<haskell><br />
-- allCombinations returns a list containing the result of<br />
-- folding the binary operator through all combinations<br />
-- of elements of the given lists<br />
-- For example, allCombinations (+) [[0,1],[1,2,3]] would be<br />
-- [0+1,0+2,0+3,1+1,1+2,1+3], or [1,2,3,2,3,4]<br />
-- and allCombinations (*) [[0,1],[1,2],[3,5]] would be<br />
-- [0*1*3,0*1*5,0*2*3,0*2*5,1*1*3,1*1*5,1*2*3,1*2*5], or [0,0,0,0,3,5,6,10]<br />
allCombinations :: (a -> a -> a) -> [[a]] -> [a]<br />
allCombinations fn [] = []<br />
allCombinations fn (l:ls) = foldl (liftM2 fn) l ls<br />
</haskell><br />
There is a related function called <code>ap</code> that is sometimes more convenient to use than the lifting functions. <code>ap</code> is simply the function application operator (<code>$</code>) lifted into the monad:<br />
<br />
<haskell><br />
ap :: (Monad m) ==> m (a -> b) -> m a -> m b<br />
ap = liftM2 ($)<br />
</haskell><br />
Note that <code>liftM2 f x y</code> is equivalent to <code>return f `ap` x `ap` y</code>, and so on for functions of more arguments. <code>ap</code> is useful when working with higher-order functions and monads.<br />
<br />
The effect of <code>ap</code> depends on the strategy of the monad in which it is used. So for example <code>[(*2),(+3)] `ap` [0,1,2]</code> is equal to <code>[0,2,4,3,4,5]</code> and <code>(Just (*2)) `ap` (Just 3)</code> is <code>Just 6</code>. Here is a simple example that shows how <code>ap</code> can be useful when doing higher-order computations:<br />
<br />
=== Example 8 ===<br />
<br />
<haskell><br />
-- lookup the commands and fold ap into the command list to<br />
-- compute a result.<br />
main :: IO ()<br />
main = do let fns = [("double",(2*)), ("halve",(`div`2)),<br />
("square",(\x->x*x)), ("negate", negate),<br />
("incr",(+1)), ("decr",(+(-1)))<br />
]<br />
args <- getArgs<br />
let val = read (args!!0)<br />
cmds = map ((flip lookup) fns) (words (args!!1))<br />
print $ foldl (flip ap) (Just val) cmds<br />
</haskell><br />
==== Functions for use with <code>MonadPlus</code> ====<br />
<br />
There are two functions in the <code>Monad</code> module that are used with monads that have a zero and a plus. The first function is <code>msum</code>, which is analogous to the <code>sum</code> function on lists of integers. <code>msum</code> operates on lists of monadic values and folds the <code>mplus</code> operator into the list using the <code>mzero</code> element as the initial value:<br />
<br />
<haskell><br />
msum :: MonadPlus m ==> [m a] -> m a<br />
msum xs = foldr mplus mzero xs<br />
</haskell><br />
In the List monad, <code>msum</code> is equivalent to <code>concat</code>. In the <code>Maybe</code> monad, <code>msum</code> returns the first non-<code>Nothing</code> value from a list. Likewise, the behavior in other monads will depend on the exact nature of their <code>mzero</code> and <code>mplus</code> definitions.<br />
<br />
<code>msum</code> allows many recursive functions and folds to be expressed more concisely. In the <code>Maybe</code> monad, for example, we can write:<br />
<br />
=== Example 9 ===<br />
<br />
<haskell><br />
type Variable = String<br />
type Value = String<br />
type EnvironmentStack = [[(Variable,Value)]]<br />
<br />
-- lookupVar retrieves a variable's value from the environment stack<br />
-- It uses msum in the Maybe monad to return the first non-Nothing value.<br />
lookupVar :: Variable -> EnvironmentStack -> Maybe Value<br />
lookupVar var stack = msum $ map (lookup var) stack<br />
</haskell><br />
instead of:<br />
<br />
<haskell><br />
lookupVar :: Variable -> EnvironmentStack -> Maybe Value<br />
lookupVar var [] = Nothing<br />
lookupVar var (e:es) = let val = lookup var e<br />
in maybe (lookupVar var es) Just val<br />
</haskell><br />
The second function for use with monads with a zero and a plus is the <code>guard</code> function:<br />
<br />
<haskell><br />
guard :: MonadPlus m ==> Bool -> m ()<br />
guard p = if p then return () else mzero<br />
</haskell><br />
The trick to understanding this function is to recall the law for monads with zero and plus that states <code>mzero >>= f ==== mzero</code>. So, placing a <code>guard</code> function in a sequence of monadic operations will force any execution in which the guard is <code>False</code> to be <code>mzero</code>. This is similar to the way that guard predicates in a list comprehension cause values that fail the predicate to become <code>[]</code>.<br />
<br />
Here is an example demonstrating the use of the <code>guard</code> function in the <code>Maybe</code> monad.<br />
<br />
=== Example 10 ===<br />
<br />
<haskell><br />
data Record = Rec {name::String, age::Int} deriving Show<br />
type DB = [Record]<br />
<br />
-- getYoungerThan returns all records for people younger than a specified age.<br />
-- It uses the guard function to eliminate records for ages at or over the limit.<br />
-- This is just for demonstration purposes. In real life, it would be<br />
-- clearer to simply use filter. When the filter criteria are more complex,<br />
-- guard becomes more useful.<br />
getYoungerThan :: Int -> DB -> [Record]<br />
getYoungerThan limit db = mapMaybe (\r -> do { guard (age r < limit); return r }) db<br />
</haskell><br />
<br />
=== Summary ===<br />
<br />
Haskell provides a number of functions which are useful for working with monads in the standard libraries. The <code>Monad</code> class and most common monad functions are in the standard prelude. The <code>MonadPlus</code> class and less commonly-used (but still very useful!) functions are defined in the <code>Monad</code> module. Many other types in the Haskell libraries are declared as instances of <code>Monad</code> and <code>MonadPlus</code> in their respective modules.<br />
<br />
= A Catalog of Standard Monads =<br />
<br />
== Introduction ==<br />
<br />
The monads covered in Part II include a mixture of standard Haskell types that are monads as well as monad classes from Andy Gill's Monad Template Library. The Monad Template Library is included in the Glasgow Haskell Compiler's hierarchical libraries under [https://hackage.haskell.org/package/base/docs/Control-Monad.html Control.Monad]<br />
<br />
Some of the documentation for these monads comes from the excellent [https://www.haskell.org/haskellwiki/Haskell Haskell Wiki]. In addition to the monads covered here, monads appear many other places in Haskell, such as the [[Parsec]] monadic combinator parsing library. These monads are beyond the scope of this reference, but they are thoroughly documented on their own. You can get a taste of the Parsec library by looking in the [[../examples/example16.hs|source code]] for [[readermonad.html#example|example 16]].<br />
<br />
<br />
{| border="1"<br />
|-<br />
!Monad<br />
!Type of computation<br />
!Combination strategy for &gt;&gt;=<br />
|-<br />
|[[identitymonad.html|Identity]]<br />
|''N/A — Used with monad transformers''<br />
|The bound function is applied to the input value.<br />
|-<br />
|[[maybemonad.html|Maybe]]<br />
|Computations which may not return a result<br />
|<code>Nothing</code> input gives <code>Nothing</code> output<br> <code>Just x</code> input uses <code>x</code> as input to the bound function.<br />
|-<br />
|[[errormonad.html|Error]]<br />
|Computations which can fail or throw exceptions<br />
|Failure records information describing the failure. Binding passes failure information on without executing the bound function, or uses successful values as input to the bound function.<br />
|-<br />
|[[listmonad.html|[] (List)]]<br />
|Non-deterministic computations which can return multiple possible results<br />
|Maps the bound function onto the input list and concatenates the resulting lists to get a list of all possible results from all possible inputs.<br />
|-<br />
|[[iomonad.html|IO]]<br />
|Computations which perform I/O<br />
|Sequential execution of I/O actions in the order of binding.<br />
|-<br />
|[[statemonad.html|State]]<br />
|Computations which maintain state<br />
|The bound function is applied to the input value to produce a state transition function which is applied to the input state.<br />
|-<br />
|[[readermonad.html|Reader]]<br />
|Computations which read from a shared environment<br />
|The bound function is applied to the value of the input using the same environment.<br />
|-<br />
|[[writermonad.html|Writer]]<br />
|Computations which write data in addition to computing values<br />
|Written data is maintained separately from values. The bound function is applied to the input value and anything it writes is appended to the write data stream.<br />
|-<br />
|[[contmonad.html|Cont]]<br />
|Computations which can be interrupted and restarted<br />
|The bound function is inserted into the continuation chain.<br />
|}<br />
<br />
== The Identity monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Simple function application<br />
<br />
* '''Binding strategy''': The bound function is applied to the input value. <code>Identity x >>= f ==== f x</code><br />
<br />
* '''Useful for''': Monads can be derived from monad transformers applied to the Identity monad.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Identity.html Identity a]<br />
<br />
=== Motivation ===<br />
<br />
The Identity monad is a monad that does not embody any computational strategy. It simply applies the bound function to its input without any modification. Computationally, there is no reason to use the Identity monad instead of the much simpler act of simply applying functions to their arguments. The purpose of the Identity monad is its fundamental role in the theory of monad transformers (covered in Part III). Any monad transformer applied to the Identity monad yields a non-transformer version of that monad.<br />
<br />
=== Definition ===<br />
<br />
<haskell><br />
newtype Identity a = Identity { runIdentity :: a }<br />
<br />
instance Monad Identity where<br />
return a = Identity a -- i.e. return = id<br />
(Identity x) >>= f = f x -- i.e. x >>= f = f x<br />
</haskell><br />
The <code>runIdentity</code> label is used in the type definition because it follows a style of monad definition that explicitly represents monad values as computations. In this style, a monadic computation is built up using the monadic operators and then the value of the computation is extracted using the <code>run******</code> function. Because the Identity monad does not do any computation, its definition is trivial. For a better example of this style of monad, see the [[statemonad.html|State]] monad.<br />
<br />
<br />
A typical use of the Identity monad is to derive a monad from a monad transformer.<br />
<br />
<haskell><br />
-- derive the State monad using the StateT monad transformer<br />
type State s a = StateT s Identity a<br />
</haskell><br />
<br />
== The Maybe monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which may return <code>Nothing</code><br />
<br />
* '''Binding strategy''': <code>Nothing</code> values bypass the bound function, other values are used as inputs to the bound function.<br />
<br />
* '''Useful for''': Building computations from sequences of functions that may return <code>Nothing</code>. Complex database queries or dictionary lookups are good examples.<br />
<br />
* '''Zero and plus''': <code>Nothing</code> is the zero. The plus operation returns the first non-<code>Nothing</code> value or <code>Nothing</code> if both inputs are <code>Nothing</code>.<br />
<br />
* '''Example type''': [https://www.haskell.org/onlinereport/haskell2010/haskellch21.html#x29-25500021 Maybe a]<br />
<br />
=== Motivation ===<br />
<br />
The Maybe monad embodies the strategy of combining a chain of computations that may each return <code>Nothing</code> by ending the chain early if any step produces <code>Nothing</code> as output. It is useful when a computation entails a sequence of steps that depend on one another, and in which some steps may fail to return a value.<br />
<br />
[[Image:info.png]] If you ever find yourself writing code like this:<br /><br />
<br />
<haskell><br />
case ... of<br />
Nothing -> Nothing<br />
Just x -> case ... of<br />
Nothing -> Nothing<br />
Just y -> ...<br />
</haskell><br />
you should consider using the monadic properties of <code>Maybe</code> to improve the code.<br />
<br />
=== Definition ===<br />
<br />
<haskell><br />
data Maybe a = Nothing | Just a<br />
<br />
instance Monad Maybe where<br />
return = Just<br />
fail = Nothing<br />
Nothing >>= f = Nothing<br />
(Just x) >>= f = f x<br />
<br />
instance MonadPlus Maybe where<br />
mzero = Nothing<br />
Nothing `mplus` x = x<br />
x `mplus` _ = x<br />
</haskell><br />
<br />
A common example is in combining dictionary lookups. Given a dictionary that maps full names to email addresses, another that maps nicknames to email addresses, and a third that maps email addresses to email preferences, you could create a function that finds a person's email preferences based on either a full name or a nickname.<br />
<br />
=== Example 11 ===<br />
<br />
<haskell><br />
data MailPref = HTML | Plain<br />
data MailSystem = ...<br />
<br />
getMailPrefs :: MailSystem -> String -> Maybe MailPref<br />
getMailPrefs sys name ==<br />
do let nameDB = fullNameDB sys<br />
nickDB = nickNameDB sys<br />
prefDB = prefsDB sys<br />
addr <- (lookup name nameDB) `mplus` (lookup name nickDB)<br />
lookup addr prefDB<br />
</haskell><br />
<br />
== The Error monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which may fail or throw exceptions<br />
<br />
* '''Binding strategy''': Failure records information about the cause/location of the failure. Failure values bypass the bound function, other values are used as inputs to the bound function.<br />
<br />
* '''Useful for''': Building computations from sequences of functions that may fail or using exception handling to structure error handling.<br />
<br />
* '''Zero and plus''': Zero is represented by an empty error and the plus operation executes its second argument if the first fails.<br />
<br />
* '''Example type''': [https://www.stackage.org/haddock/lts-16.22/base-4.13.0.0/src/Data-Either.html#line-125 Either String a]<br />
<br />
=== Motivation ===<br />
<br />
The Error monad (also called the Exception monad) embodies the strategy of combining computations that can throw exceptions by bypassing bound functions from the point an exception is thrown to the point that it is handled.<br />
<br />
The [https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Error.html <code>MonadError</code>] class is parameterized over the type of error information and the monad type constructor. It is common to use <code>Either String</code> as the monad type constructor for an error monad in which error descriptions take the form of strings. In that case and many other common cases the resulting monad is already defined as an instance of the <code>MonadError</code> class. You can also define your own error type and/or use a monad type constructor other than <code>Either String</code> or <code>Either IOError</code>. In these cases you will have to explicitly define instances of the <code>Error</code> and/or <code>MonadError</code> classes.<br />
<br />
=== Definition ===<br />
<br />
The definition of the <code>MonadError</code> class below uses multi-parameter type classes and funDeps, which are language extensions not found in standard Haskell 2010. You don't need to understand them to take advantage of the <code>MonadError</code> class.<br />
<br />
<haskell><br />
class Error a where<br />
noMsg :: a<br />
strMsg :: String -> a<br />
<br />
class (Monad m) ==> MonadError e m | m -> e where<br />
throwError :: e -> m a<br />
catchError :: m a -> (e -> m a) -> m a<br />
</haskell><br />
<code>throwError</code> is used within a monadic computation to begin exception processing. <code>catchError</code> provides a handler function to handle previous errors and return to normal execution. A common idiom is:<br />
<br />
<haskell><br />
do { action1; action2; action3 } `catchError` handler<br />
</haskell><br />
where the <code>action</code> functions can call <code>throwError</code>. Note that <code>handler</code> and the do-block must have the same return type.<br />
<br />
The definition of the <code>Either e</code> type constructor as an instance of the <code>MonadError</code> class is straightforward. Following convention, <code>Left</code> is used for error values and <code>Right</code> is used for non-error (right) values.<br />
<br />
<haskell><br />
instance MonadError (Either e) where<br />
throwError = Left<br />
(Left e) `catchError` handler = handler e<br />
a `catchError` _ = a<br />
</haskell><br />
<br />
Here is an example that demonstrates the use of a custom <code>Error</code> data type with the <code>ErrorMonad</code>'s <code>throwError</code> and <code>catchError</code> exception mechanism. The example attempts to parse hexadecimal numbers and throws an exception if an invalid character is encountered. We use a custom <code>Error</code> data type to record the location of the parse error. The exception is caught by a calling function and handled by printing an informative error message.<br />
<br />
=== Example 12 ===<br />
<br />
<haskell><br />
-- This is the type of our parse error representation.<br />
data ParseError = Err {location::Int, reason::String}<br />
<br />
-- We make it an instance of the Error class<br />
instance Error ParseError where<br />
noMsg = Err 0 "Parse Error"<br />
strMsg s = Err 0 s<br />
<br />
-- For our monad type constructor, we use Either ParseError<br />
-- which represents failure using Left ParseError or a<br />
-- successful result of type a using Right a.<br />
type ParseMonad = Either ParseError<br />
<br />
-- parseHexDigit attempts to convert a single hex digit into<br />
-- an Integer in the ParseMonad monad and throws an error on an<br />
-- invalid character<br />
parseHexDigit :: Char -> Int -> ParseMonad Integer<br />
parseHexDigit c idx = if isHexDigit c then<br />
return (toInteger (digitToInt c))<br />
else<br />
throwError (Err idx ("Invalid character '" ++ [c] ++ "'"))<br />
<br />
-- parseHex parses a string containing a hexadecimal number into<br />
-- an Integer in the ParseMonad monad. A parse error from parseHexDigit<br />
-- will cause an exceptional return from parseHex.<br />
parseHex :: String -> ParseMonad Integer<br />
parseHex s = parseHex' s 0 1<br />
where parseHex' [] val _ = return val<br />
parseHex' (c:cs) val idx = do d <- parseHexDigit c idx<br />
parseHex' cs ((val * 16) + d) (idx + 1)<br />
<br />
-- toString converts an Integer into a String in the ParseMonad monad<br />
toString :: Integer -> ParseMonad String<br />
toString n = return $ show n<br />
<br />
-- convert takes a String containing a hexadecimal representation of<br />
-- a number to a String containing a decimal representation of that<br />
-- number. A parse error on the input String will generate a<br />
-- descriptive error message as the output String.<br />
convert :: String -> String<br />
convert s = let (Right str) = do {n <- parseHex s; toString n} `catchError` printError<br />
in str<br />
where printError e = return $ "At index " ++ (show (location e)) ++ ":" ++ (reason e)<br />
</haskell><br />
<br />
== The List monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which may return 0, 1, or more possible results.<br />
<br />
* '''Binding strategy''': The bound function is applied to all possible values in the input list and the resulting lists are concatenated to produce a list of all possible results.<br />
<br />
* '''Useful for''': Building computations from sequences of non-deterministic operations. Parsing ambiguous grammars is a common example.<br />
<br />
* '''Zero and plus''': <code>[]</code> is the zero and <code>++</code> is the plus operation.<br />
<br />
* '''Example type''': <code>[a]</code><br />
<br />
=== Motivation ===<br />
<br />
The List monad embodies the strategy of combining a chain of non-deterministic computations by applying the operations to all possible values at each step. It is useful when computations must deal with ambiguity. In that case it allows all possibilities to be explored until the ambiguity is resolved.<br />
<br />
=== Definition ===<br />
<br />
<haskell><br />
instance Monad [] where<br />
m >>= f = concatMap f m<br />
return x = [x]<br />
fail s = []<br />
<br />
instance MonadPlus [] where<br />
mzero = []<br />
mplus = (++)<br />
</haskell><br />
<br />
The canonical example of using the List monad is for parsing ambiguous grammars. The example below shows just a small example of parsing data into hex values, decimal values and words containing only alpha-numeric characters. Note that hexadecimal digits overlap both decimal digits and alphanumeric characters, leading to an ambiguous grammar. &quot;dead&quot; is both a valid hex value and a word, for example, and &quot;10&quot; is both a decimal value of 10 and a hex value of 16.<br />
<br />
=== Example 13 ===<br />
<br />
<haskell><br />
-- we can parse three different types of terms<br />
data Parsed = Digit Integer | Hex Integer | Word String deriving Show<br />
<br />
-- attempts to add a character to the parsed representation of a hex digit<br />
parseHexDigit :: Parsed -> Char -> [Parsed]<br />
parseHexDigit (Hex n) c = if isHexDigit c then<br />
return (Hex ((n*16) + (toInteger (digitToInt c))))<br />
else<br />
mzero<br />
parseHexDigit _ _ = mzero<br />
<br />
-- attempts to add a character to the parsed representation of a decimal digit<br />
parseDigit :: Parsed -> Char -> [Parsed]<br />
parseDigit (Digit n) c = if isDigit c then<br />
return (Digit ((n*10) + (toInteger (digitToInt c))))<br />
else<br />
mzero<br />
parseDigit _ _ = mzero<br />
<br />
-- attempts to add a character to the parsed representation of a word<br />
parseWord :: Parsed -> Char -> [Parsed]<br />
parseWord (Word s) c = if isAlpha c then<br />
return (Word (s ++ [c]))<br />
else<br />
mzero<br />
parseWord _ _ = mzero<br />
<br />
-- tries to parse the digit as a hex value, a decimal value and a word<br />
-- the result is a list of possible parses<br />
parse :: Parsed -> Char -> [Parsed]<br />
parse p c = (parseHexDigit p c) `mplus` (parseDigit p c) `mplus` (parseWord p c)<br />
<br />
-- parse an entire String and return a list of the possible parsed values<br />
parseArg :: String -> [Parsed]<br />
parseArg s = do init <- (return (Hex 0)) `mplus` (return (Digit 0)) `mplus` (return (Word ""))<br />
foldM parse init s<br />
</haskell><br />
<br />
== The IO monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which perform I/O<br />
<br />
* '''Binding strategy''': I/O actions are executed in the order in which they are bound. Failures throw I/O errors which can be caught and handled.<br />
<br />
* '''Useful for''': Performing I/O within a Haskell program.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://hackage.haskell.org/package/base/docs/System-IO.html IO a]<br />
<br />
=== Motivation ===<br />
<br />
Input/Output is incompatible with a pure functional language because it is not referentially transparent and side-effect free. The IO monad solves this problem by confining computations that perform I/O within the IO monad.<br />
<br />
=== Definition ===<br />
<br />
The definition of the IO monad is platform-specific. No data constructors are exported and no functions are provided to remove data from the IO monad. This makes the IO monad a one-way monad and is essential to ensuring safety of functional programs by isolating side-effects and non-referentially transparent actions within the imperative-style computations of the IO monad.<br />
<br />
Throughout this tutorial, we have referred to monadic values as computations. However, values in the IO monad are often called I/O actions and we will use that terminology here.<br />
<br />
In Haskell, the top-level <code>main</code> function must have type <code>IO ()</code>, so that programs are typically structured at the top level as an imperative-style sequence of I/O actions and calls to functional-style code. The functions exported from the <code>IO</code> module do not perform I/O themselves. They return I/O actions, which describe an I/O operation to be performed. The I/O actions are combined within the IO monad (in a purely functional manner) to create more complex I/O actions, resulting in the final I/O action that is the <code>main</code> value of the program.<br />
<br />
The standard prelude and the [https://www.haskell.org/onlinelibrary/io.html <code>IO</code> module] define many functions that can be used within the IO monad and any Haskell programmer will undoubtedly be familiar with some of them. This tutorial will only discuss the monadic aspects of the IO monad, not the full range of functions available to perform I/O.<br />
<br />
The <code>IO</code> type constructor is a member of the <code>Monad</code> class and the <code>MonadError</code> class, where errors are of the type <code>IOError</code>. <code>fail</code> is defined to throw an error built from the string argument. Within the <code>IO</code> monad you can use the exception mechanisms from the <code>Control.Monad.Error</code> module in the Monad Template Library if you import the module. The same mechanisms have alternative names exported by the <code>IO</code> module: <code>ioError</code> and <code>catch</code>.<br />
<br />
<haskell><br />
instance Monad IO where<br />
return a = ... -- function from a -> IO a<br />
m >>= k = ... -- executes the I/O action m and binds the value to k's input<br />
fail s = ioError (userError s)<br />
<br />
data IOError = ...<br />
<br />
ioError :: IOError -> IO a<br />
ioError = ...<br />
<br />
userError :: String -> IOError<br />
userError = ...<br />
<br />
catch :: IO a -> (IOError -> IO a) -> IO a<br />
catch = ...<br />
<br />
try :: IO a -> IO (Either IOError a)<br />
try f = catch (do r <- f<br />
return (Right r))<br />
(return . Left)<br />
</haskell><br />
The <code>IO</code> monad is incorporated into the Monad Template Library framework as an instance of the <code>MonadError</code> class.<br />
<br />
<haskell><br />
instance Error IOError where<br />
...<br />
<br />
instance MonadError IO where<br />
throwError = ioError<br />
catchError = catch<br />
</haskell><br />
The <code>IO</code> module exports a convenience function called <code>try</code> that executes an I/O action and returns <code>Right result</code> if the action succeeded or <code>Left IOError</code> if an I/O error was caught.<br />
<br />
<br />
This example shows a partial implementation of the &quot;tr&quot; command that copies the standard input stream to the standard output stream with character translations controlled by command-line arguments. It demonstrates the use of the exception handling mechanisms of the <code>MonadError</code> class with the <code>IO</code> monad.<br />
<br />
=== Example 14 ===<br />
<br />
<haskell><br />
import Monad<br />
import System<br />
import IO<br />
import Control.Monad.Error<br />
<br />
-- translate char in set1 to corresponding char in set2<br />
translate :: String -> String -> Char -> Char<br />
translate [] _ c = c<br />
translate (x:xs) [] c = if x == c then ' ' else translate xs [] c<br />
translate (x:xs) [y] c = if x == c then y else translate xs [y] c<br />
translate (x:xs) (y:ys) c = if x == c then y else translate xs ys c<br />
<br />
-- translate an entire string<br />
translateString :: String -> String -> String -> String<br />
translateString set1 set2 str = map (translate set1 set2) str<br />
<br />
usage :: IOError -> IO ()<br />
usage e = do putStrLn "Usage: ex14 set1 set2"<br />
putStrLn "Translates characters in set1 on stdin to the corresponding"<br />
putStrLn "characters from set2 and writes the translation to stdout."<br />
<br />
-- translates stdin to stdout based on commandline arguments<br />
main :: IO ()<br />
main = (do [set1,set2] <- getArgs<br />
contents <- hGetContents stdin<br />
putStr $ translateString set1 set2 contents)<br />
`catchError` usage<br />
</haskell><br />
<br />
== The State monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which maintain state.<br />
<br />
* '''Binding strategy''': Binding threads a state parameter through the sequence of bound functions so that the same state value is never used twice, giving the illusion of in-place update.<br />
<br />
* '''Useful for''': Building computations from sequences of operations that require a shared state.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://hackage.haskell.org/package/mtl/docs/Control-Monad-State-Lazy.html State st a]<br />
<br />
=== Motivation ===<br />
<br />
A pure functional language cannot update values in place because it violates referential transparency. A common idiom to simulate such stateful computations is to &quot;thread&quot; a state parameter through a sequence of functions:<br />
<br />
<haskell><br />
data MyType = MT Int Bool Char Int deriving Show<br />
<br />
makeRandomValue :: StdGen -> (MyType, StdGen)<br />
makeRandomValue g = let (n,g1) = randomR (1,100) g<br />
(b,g2) = random g1<br />
(c,g3) = randomR ('a','z') g2<br />
(m,g4) = randomR (-n,n) g3<br />
in (MT n b c m, g4)<br />
</haskell><br />
This approach works, but such code can be error-prone, messy and difficult to maintain. The State monad hides the threading of the state parameter inside the binding operation, simultaneously making the code easier to write, easier to read and easier to modify.<br />
<br />
=== Definition ===<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 2010. It is not necessary to fully understand these details to make use of the State monad.<br />
<br />
<haskell><br />
newtype State s a = State { runState :: (s -> (a,s)) }<br />
<br />
instance Monad (State s) where<br />
return a = State $ \s -> (a,s)<br />
(State x) >>= f = State $ \s -> let (v,s') = x s in runState (f v) s'<br />
</haskell><br />
Values in the State monad are represented as transition functions from an initial state to a (value,newState) pair and a new type definition is provided to describe this construct: <code>State s a</code> is the type of a value of type <code>a</code> inside the State monad with state of type <code>s</code>.<br />
<br />
The type constructor <code>State s</code> is an instance of the <code>Monad</code> class. The <code>return</code> function simply creates a state transition function which sets the value but leaves the state unchanged. The binding operator creates a state transition function that applies its right-hand argument to the value and new state from its left-hand argument.<br />
<br />
<haskell><br />
class MonadState m s | m -> s where<br />
get :: m s<br />
put :: s -> m ()<br />
<br />
instance MonadState (State s) s where<br />
get = State $ \s -> (s,s)<br />
put s = State $ \_ -> ((),s)<br />
</haskell><br />
The <code>MonadState</code> class provides a standard but very simple interface for State monads. The <code>get</code> function retrieves the state by copying it as the value. The <code>put</code> function sets the state of the monad and does not yield a value.<br />
<br />
There are many additional functions provide which perform more complex computations built on top of <code>get</code> and put. The most useful one is <code>gets</code> which retrieves a function of the state. The others are listed in the [https://downloads.haskell.org/~ghc/latest/docs/html/libraries/mtl-2.2.2/Control-Monad-State.html documentation] for the State monad library.<br />
<br />
<br />
A simple application of the State monad is to thread the random generator state through multiple calls to the generation function.<br />
<br />
=== Example 15 ===<br />
<br />
<haskell><br />
data MyType = MT Int Bool Char Int deriving Show<br />
<br />
{- Using the State monad, we can define a function that returns<br />
a random value and updates the random generator state at<br />
the same time.<br />
-}<br />
getAny :: (Random a) ==> State StdGen a<br />
getAny = do g <- get<br />
(x,g') <- return $ random g<br />
put g'<br />
return x<br />
<br />
-- similar to getAny, but it bounds the random value returned<br />
getOne :: (Random a) ==> (a,a) -> State StdGen a<br />
getOne bounds = do g <- get<br />
(x,g') <- return $ randomR bounds g<br />
put g'<br />
return x<br />
<br />
{- Using the State monad with StdGen as the state, we can build<br />
random complex types without manually threading the<br />
random generator states through the code.<br />
-}<br />
makeRandomValueST :: StdGen -> (MyType, StdGen)<br />
makeRandomValueST = runState (do n <- getOne (1,100)<br />
b <- getAny<br />
c <- getOne ('a','z')<br />
m <- getOne (-n,n)<br />
return (MT n b c m))<br />
</haskell><br />
<br />
== The Reader monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which read values from a shared environment.<br />
<br />
* '''Binding strategy''': Monad values are functions from the environment to a value. The bound function is applied to the bound value, and both have access to the shared environment.<br />
<br />
* '''Useful for''': Maintaining variable bindings, or other shared environment.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://hackage.haskell.org/package/mtl/docs/Control-Monad-Reader.html Reader <nowiki>[(String,Value)]</nowiki> a]<br />
<br />
=== Motivation ===<br />
<br />
Some programming problems require computations within a shared environment (such as a set of variable bindings). These computations typically read values from the environment and sometimes execute sub-computations in a modified environment (with new or shadowing bindings, for example), but they do not require the full generality of the State monad.<br />
<br />
The Reader monad is specifically designed for these types of computations and is often a clearer and easier mechanism than using the State monad.<br />
<br />
=== Definition ===<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 2010. It is not necessary to fully understand these details to make use of the Reader monad.<br />
<br />
<haskell><br />
newtype Reader e a = Reader { runReader :: (e -> a) }<br />
<br />
instance Monad (Reader e) where<br />
return a = Reader $ \e -> a<br />
(Reader r) >>= f = Reader $ \e -> runReader (f (r e)) e<br />
</haskell><br />
Values in the Reader monad are functions from an environment to a value. To extract the final value from a computation in the Reader monad, you simply apply <code>(runReader reader)</code> to an environment value.<br />
<br />
The <code>return</code> function creates a <code>Reader</code> that ignores the environment and produces the given value. The binding operator produces a <code>Reader</code> that uses the environment to extract the value its left-hand side and then applies the bound function to that value in the same environment.<br />
<br />
<haskell><br />
class MonadReader e m | m -> e where<br />
ask :: m e<br />
local :: (e -> e) -> m a -> m a<br />
<br />
instance MonadReader e (Reader e) where<br />
ask = Reader id<br />
local f c = Reader $ \e -> runReader c (f e)<br />
<br />
asks :: (MonadReader e m) ==> (e -> a) -> m a<br />
asks sel = ask >>= return . sel<br />
</haskell><br />
The <code>MonadReader</code> class provides a number of convenience functions that are very useful when working with a Reader monad. The <code>ask</code> function retrieves the environment and the <code>local</code> function executes a computation in a modified environment. The <code>asks</code> function is a convenience function that retrieves a function of the current environment, and is typically used with a selector or lookup function.<br />
<br />
<br />
Consider the problem of instantiating templates which contain variable substitutions and included templates. Using the Reader monad, we can maintain an environment of all known templates and all known variable bindings. Then, when a variable substitution is encountered, we can use the <code>asks</code> function to lookup the value of the variable. When a template is included with new variable definitions, we can use the <code>local</code> function to resolve the template in a modified environment that contains the additional variable bindings.<br />
<br />
=== Example 16 ===<br />
<br />
<haskell><br />
-- This the abstract syntax representation of a template<br />
-- Text Variable Quote Include Compound<br />
data Template = T String | V Template | Q Template | I Template [Definition] | C [Template]<br />
data Definition = D Template Template<br />
<br />
-- Our environment consists of an association list of named templates and<br />
-- an association list of named variable values.<br />
data Environment = Env {templates::[(String,Template)],<br />
variables::[(String,String)]}<br />
<br />
-- lookup a variable from the environment<br />
lookupVar :: String -> Environment -> Maybe String<br />
lookupVar name env = lookup name (variables env)<br />
<br />
-- lookup a template from the environment<br />
lookupTemplate :: String -> Environment -> Maybe Template<br />
lookupTemplate name env = lookup name (templates env)<br />
<br />
-- add a list of resolved definitions to the environment<br />
addDefs :: [(String,String)] -> Environment -> Environment<br />
addDefs defs env = env {variables = defs ++ (variables env)}<br />
<br />
-- resolve a Definition and produce a (name,value) pair<br />
resolveDef :: Definition -> Reader Environment (String,String)<br />
resolveDef (D t d) = do name <- resolve t<br />
value <- resolve d<br />
return (name,value)<br />
<br />
-- resolve a template into a string<br />
resolve :: Template -> Reader Environment (String)<br />
resolve (T s) = return s<br />
resolve (V t) = do varName <- resolve t<br />
varValue <- asks (lookupVar varName)<br />
return $ maybe "" id varValue<br />
resolve (Q t) = do tmplName <- resolve t<br />
body <- asks (lookupTemplate tmplName)<br />
return $ maybe "" show body<br />
resolve (I t ds) = do tmplName <- resolve t<br />
body <- asks (lookupTemplate tmplName)<br />
case body of<br />
Just t' -> do defs <- mapM resolveDef ds<br />
local (addDefs defs) (resolve t')<br />
Nothing -> return ""<br />
resolve (C ts) = (liftM concat) (mapM resolve ts)<br />
</haskell><br />
To use the Reader monad to resolve a template <code>t</code> into a <code>String</code>, you simply need to do <code>runReader (resolve t) env</code>.<br />
<br />
== The Writer monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which produce a stream of data in addition to the computed values.<br />
<br />
* '''Binding strategy''': A Writer monad value is a (computation value, log value) pair. Binding replaces the computation value with the result of applying the bound function to the previous value and appends any log data from the computation to the existing log data.<br />
<br />
* '''Useful for''': Logging, or other computations that produce output &quot;on the side&quot;.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://hackage.haskell.org/package/mtl/docs/Control-Monad-Writer.html Writer <nowiki>[String]</nowiki> a]<br />
<br />
=== Motivation ===<br />
<br />
It is often desirable for a computation to generate output &quot;on the side&quot;. Logging and tracing are the most common examples in which data is generated during a computation that we want to retain but is not the primary result of the computation.<br />
<br />
Explicitly managing the logging or tracing data can clutter up the code and invite subtle bugs such as missed log entries. The Writer monad provides a cleaner way to manage the output without cluttering the main computation.<br />
<br />
=== Definition ===<br />
<br />
The definition shown here uses multi-parameter type classes and funDeps, which are not standard Haskell 2010. It is not necessary to fully understand these details to make use of the Writer monad.<br />
<br />
[[Image:info.png]] To fully understand this definition, you need to know about Haskell's <code>Monoid</code> class, which represents a mathematical structure called a monoid in the same way that the <code>Monad</code> class represents the monad structure.<br />
<br />
The good news is that monoids are simpler than monads. A monoid is a set of objects, a single identity element, and an associative binary operator over the set of objects. A monoid must obey some mathematical laws, such that applying the operator to any values from the set gives another value in the set, and whenever one operand of the operator is the identity element the result is equal to the other operand. You may notice that these laws are the same as the laws governing <code>mzero</code> and <code>mplus</code> for instances of <code>MonadPlus</code>. That is because monads with a zero and plus are monads that are also monoids!<br />
<br />
Some examples of mathematical monoids are the natural numbers with identity element 0 and binary operator for addition, and also the natural numbers with identity element 1 and binary operator for multiplication.<br />
<br />
In Haskell, a monoid consists of a type, an identity element, and a binary operator. Haskell defines the <code>Monoid</code> class (in Data.Monoid) to provide a standard convention for working with monoids: the identity element is named <code>mempty</code> and the operator is named <code>mappend</code>.<br />
<br />
The most commonly used standard monoid in Haskell is the list, but functions of type <code>(a -> a)</code> also form a monoid.<br />
<br />
[[Image:warn.png]] Care should be taken when using a list as the monoid for a Writer, as there may be a performance penalty associated with the <code>mappend</code> operation as the output grows. In that case, a data structure that supports fast append operations would be a more appropriate choice.<br />
<br />
<haskell><br />
newtype Writer w a = Writer { runWriter :: (a,w) }<br />
<br />
instance (Monoid w) ==> Monad (Writer w) where<br />
return a = Writer (a,mempty)<br />
(Writer (a,w)) >>= f = let (a',w') = runWriter $ f a in Writer (a',w `mappend` w')<br />
</haskell><br />
The Writer monad maintains a (value,log) pair, where the log type must be a monoid. The <code>return</code> function simply returns the value along with an empty log. Binding executes the bound function using the current value as input, and appends any log output to the existing log.<br />
<br />
<haskell><br />
class (Monoid w, Monad m) ==> MonadWriter w m | m -> w where<br />
pass :: m (a,w -> w) -> m a<br />
listen :: m a -> m (a,w)<br />
tell :: w -> m ()<br />
<br />
instance (Monoid w) ==> MonadWriter w (Writer w) where<br />
pass (Writer ((a,f),w)) = Writer (a,f w)<br />
listen (Writer (a,w)) = Writer ((a,w),w)<br />
tell s = Writer ((),s)<br />
<br />
listens :: (MonadWriter w m) ==> (w -> b) -> m a -> m (a,b)<br />
listens f m = do (a,w) <- listen m; return (a,f w)<br />
<br />
censor :: (MonadWriter w m) ==> (w -> w) -> m a -> m a<br />
censor f m = pass $ do a <- m; return (a,f)<br />
</haskell><br />
The <code>MonadWriter</code> class provides a number of convenience functions for working with Writer monads. The simplest and most useful is <code>tell</code>, which adds one or more entries to the log. The <code>listen</code> function turns a Writer that returns a value <code>a</code> and produces output <code>w</code> into a Writer that produces a value <code>(a,w)</code> and still produces output <code>w</code>. This allows the computation to &quot;listen&quot; to the log output generated by a Writer.<br />
<br />
The <code>pass</code> function is slightly more complicated. It converts a Writer that produces a value <code>(a,f)</code> and output <code>w</code> into a Writer that produces a value <code>a</code> and output <code>f w</code>. This is somewhat cumbersome, so the helper function <code>censor</code> is normally used. The <code>censor</code> function takes a function and a Writer and produces a new Writer whose output is the same but whose log entry has been modified by the function.<br />
<br />
The <code>listens</code> function operates just like <code>listen</code> except that the log part of the value is modified by the supplied function.<br />
<br />
<br />
In this example, we imagine a very simple firewall that filters packets based on a rulebase of rules matching the source and destination hosts and the payload of the packet. The firewall's primary job is packet filtering, but we would also like it to produce a log of its activity.<br />
<br />
=== Example 17 ===<br />
<br />
<haskell><br />
-- this is the format of our log entries<br />
data Entry = Log {count::Int, msg::String} deriving Eq<br />
<br />
-- add a message to the log<br />
logMsg :: String -> Writer [Entry] ()<br />
logMsg s = tell [Log 1 s]<br />
<br />
-- this handles one packet<br />
filterOne :: [Rule] -> Packet -> Writer [Entry] (Maybe Packet)<br />
filterOne rules packet = do<br />
rule <- return (match rules packet)<br />
case rule of<br />
Nothing -> do<br />
logMsg $ "DROPPING UNMATCHED PACKET: " ++ (show packet)<br />
return Nothing<br />
(Just r) -> do<br />
when (logIt r) $ logMsg ("MATCH: " ++ (show r) ++ " <=> " ++ (show packet))<br />
case r of (Rule Accept _ _) -> return $ Just packet<br />
(Rule Reject _ _) -> return Nothing<br />
</haskell><br />
<br />
That was pretty simple, but what if we want to merge duplicate consecutive log entries? None of the existing functions allow us to modify the output from previous stages of the computation, but we can use a &quot;delayed logging&quot; trick to only add a log entry only after we get a new entry that doesn't match the ones before it.<br />
<br />
<haskell><br />
-- merge identical entries at the end of the log<br />
-- This function uses [Entry] as both the log type and the result type.<br />
-- When two identical messages are merged, the result is just the message<br />
-- with an incremented count. When two different messages are merged,<br />
-- the first message is logged and the second is returned as the result.<br />
mergeEntries :: [Entry] -> [Entry] -> Writer [Entry] [Entry]<br />
mergeEntries [] x = return x<br />
mergeEntries x [] = return x<br />
mergeEntries [e1] [e2] = let (Log n msg) = e1<br />
(Log n' msg') = e2<br />
in if msg == msg' then<br />
return [(Log (n+n') msg)]<br />
else<br />
do tell [e1]<br />
return [e2]<br />
<br />
-- This is a complex-looking function but it is actually pretty simple.<br />
-- It maps a function over a list of values to get a list of Writers,<br />
-- then runs each writer and combines the results. The result of the function<br />
-- is a writer whose value is a list of all the values from the writers and whose<br />
-- log output is the result of folding the merge operator into the individual<br />
-- log entries (using 'initial' as the initial log value).<br />
groupSame :: (Monoid a) ==> a -> (a -> a -> Writer a a) -> [b] -> (b -> Writer a c) -> Writer a [c]<br />
groupSame initial merge [] _ = do tell initial<br />
return []<br />
groupSame initial merge (x:xs) fn = do (result,output) <- return (runWriter (fn x))<br />
new <- merge initial output<br />
rest <- groupSame new merge xs fn<br />
return (result:rest)<br />
<br />
-- this filters a list of packets, producing a filtered packet list and a log of<br />
-- the activity in which consecutive messages are merged<br />
filterAll :: [Rule] -> [Packet] -> Writer [Entry] [Packet]<br />
filterAll rules packets = do tell [Log 1 "STARTING PACKET FILTER"]<br />
out <- groupSame [] mergeEntries packets (filterOne rules)<br />
tell [Log 1 "STOPPING PACKET FILTER"]<br />
return (catMaybes out)<br />
</haskell><br />
<br />
== The Continuation monad ==<br />
<br />
=== Overview ===<br />
<br />
* '''Computation type''': Computations which can be interrupted and resumed.<br />
<br />
* '''Binding strategy''': Binding a function to a monadic value creates a new continuation which uses the function as the continuation of the monadic computation.<br />
<br />
* '''Useful for''': Complex control structures, error handling and creating co-routines.<br />
<br />
* '''Zero and plus''': None.<br />
<br />
* '''Example type''': [https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html Cont r a]<br />
<br />
=== Motivation ===<br />
<br />
[[Image:warn.png]] Abuse of the Continuation monad can produce code that is impossible to understand and maintain.<br />
<br />
Before using the Continuation monad, be sure that you have a firm understanding of continuation-passing style (CPS) and that continuations represent the best solution to your particular design problem. Many algorithms which require continuations in other languages do not require them in Haskell, due to Haskell's lazy semantics.<br />
<br />
Continuations represent the ''future'' of a computation, as a function from an intermediate result to the final result. In continuation-passing style, computations are built up from sequences of nested continuations, terminated by a final continuation (often <code>id</code>) which produces the final result. Since continuations are functions which represent the future of a computation, manipulation of the continuation functions can achieve complex manipulations of the future of the computation, such as interrupting a computation in the middle, aborting a portion of a computation, restarting a computation and interleaving execution of computations. The Continuation monad adapts CPS to the structure of a monad.<br />
<br />
=== Definition ===<br />
<br />
<haskell><br />
newtype Cont r a = Cont { runCont :: ((a -> r) -> r) } -- r is the final result type of the whole computation<br />
<br />
instance Monad (Cont r) where<br />
return a = Cont $ \k -> k a -- i.e. return a = \k -> k a<br />
(Cont c) >>= f = Cont $ \k -> c (\a -> runCont (f a) k) -- i.e. c >>= f = \k -> c (\a -> f a k)<br />
</haskell><br />
The Continuation monad represents computations in continuation-passing style. <code>Cont r a</code> is a CPS computation that produces an intermediate result of type <code>a</code> within a CPS computation whose final result type is <code>r</code>.<br />
<br />
The <code>return</code> function simply creates a continuation which passes the value on. The <code>>>=</code> operator adds the bound function into the continuation chain.<br />
<br />
<haskell><br />
class (Monad m) ==> MonadCont m where<br />
callCC :: ((a -> m b) -> m a) -> m a<br />
<br />
instance MonadCont (Cont r) where<br />
callCC f = Cont $ \k -> runCont (f (\a -> Cont $ \_ -> k a)) k<br />
</haskell><br />
The <code>MonadCont</code> class provides the <code>callCC</code> function, which provides an escape continuation mechanism for use with Continuation monads. Escape continuations allow you to abort the current computation and return a value immediately. They achieve a similar effect to <code>throwError</code> and catchError within an <code>Error</code> monad.<br />
<br />
<code>callCC</code> calls a function with the current continuation as its argument (hence the name). The standard idiom used with <code>callCC</code> is to provide a lambda-expression to name the continuation. Then calling the named continuation anywhere within its scope will escape from the computation, even if it is many layers deep within nested computations.<br />
<br />
In addition to the escape mechanism provided by <code>callCC</code>, the Continuation monad can be used to implement other, more powerful continuation manipulations. These other mechanisms have fairly specialized uses, however — and abuse of them can easily create fiendishly obfuscated code — so they will not be covered here.<br />
<br />
<br />
This example gives a taste of how escape continuations work. The example function uses escape continuations to perform a complicated transformation on an integer.<br />
<br />
=== Example 18 ===<br />
<br />
<haskell><br />
{- We use the continuation monad to perform "escapes" from code blocks.<br />
This function implements a complicated control structure to process<br />
numbers:<br />
<br />
Input (n) Output List Shown<br />
========= ====== =========<br />
0-9 n none<br />
10-199 number of digits in (n/2) digits of (n/2)<br />
200-19999 n digits of (n/2)<br />
20000-1999999 (n/2) backwards none<br />
>== 2000000 sum of digits of (n/2) digits of (n/2)<br />
-}<br />
fun :: Int -> String<br />
fun n = (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do -- define "exit1"<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- define "exit2"<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns') --escape 2 levels<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
= Monads in the Real World =<br />
<br />
== Introduction ==<br />
<br />
Part I has introduced the monad concept and Part II has provided an understanding of a number of common, useful monads in the standard Haskell libraries. This is not enough to put monads into heavy practice, however, because in the real world you often want computations which combine aspects of more than one monad at the same time, such as stateful, non-determistic computations or computations which make use of continuations and perform I/O. When one computation is a strict subset of the other, it is possible to perform the monad computations separately, unless the sub-computation is performed in a one-way monad.<br />
<br />
Often, the computations can't be performed in isolation. In this case, what is needed is a monad that combines the features of the two monads into a single computation. It is inefficient and poor practice to write a new monad instance with the required characteristics each time a new combination is desired. Instead, we would prefer to develop a way to combine the standard monads to produce the needed hybrids. The technique that lets us do exactly that is called monad transformers.<br />
<br />
Monad transformers are the topic of Part III, and they are explained by revisiting earlier examples to see how monad transformers can be used to add more realistic capabilities to them. It may be helpful to review the earlier examples as they are re-examined.<br />
<br />
Combining monads the hard way<br />
<br />
== Combining monads the hard way ==<br />
<br />
Before we investigate the use of monad transformers, we will see how monads can be combined without using transformers. This is a useful excercise to develop insights into the issues that arise when combining monads and provides a baseline from which the advantages of the transformer approach can be measured. We use the code from [[contmonad.html#example|example 18]] (the Continuation monad) to illustrate these issues, so you may want to review it before continuing.<br />
<br />
=== Nested Monads ===<br />
<br />
Some computations have a simple enough structure that the monadic computations can be nested, avoiding the need for a combined monad altogether. In Haskell, all computations occur in the IO monad at the top level, so the monad examples we have seen so far all actually use the technique of nested monadic computations. To do this, the computations perform all of their input at the beginning — usually by reading arguments from the command line — then pass the values on to the monadic computations to produce results, and finally perform their output at the end. This structure avoids the issues of combining monads but makes the examples seem contrived at times.<br />
<br />
The code introduced in example 18 followed the nesting pattern: reading a number from the command line in the IO monad, passing that number to a computation in the Continuation monad to produce a string, and then writing the string back in the IO monad. The computations in the IO monad aren't restricted to reading from the command line and writing strings; they can be arbitrarily complex. Likewise, the inner computation can be arbitrarily complex as well. As long as the inner computation does not depend on the functionality of the outer monad, it can be safely nested within the outer monad, as illustrated in this variation on example 18 which reads the value from stdin instead of using a command line argument:<br />
<br />
=== Example 19 ===<br />
<br />
<haskell><br />
fun :: IO String<br />
fun = do n <- (readLn::IO Int) -- this is an IO monad block<br />
return $ (`runCont` id) $ do -- this is a Cont monad block<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
=== Combined Monads ===<br />
<br />
What about computations with more complicated structure? If the nesting pattern cannot be used, we need a way to combine the attributes of two or more monads in a single computation. This is accomplished by doing computations within a monad in which the values are themselves monadic values in another monad. For example, we might perform computations in the Continuation monad of type <code>Cont (IO String) a</code> if we need to perform I/O within the computation in the Continuation monad. We could use a monad of type <code>State (Either Err a) a</code> to combine the features of the State and Error monads in a single computation.<br />
<br />
Consider a slight modification to our example in which we perform the same I/O at the beginning, but we may require additional input in the middle of the computation in the Continuation monad. In this case, we will allow the user to specify part of the output value when the input value is within a certain range. Because the I/O depends on part of the computation in the Continuation monad and part of the computation in the Continuation monad depends on the result of the I/O, we cannot use the nested monad pattern.<br />
<br />
Instead, we make the computation in the Continuation monad use values from the IO monad. What used to be <code>Int</code> and <code>String</code> values are now of type <code>IO Int</code> and <code>IO String</code>. We can't extract values from the IO monad — it's a one-way monad — so we may need to nest little do-blocks of the IO monad within the Continuation monad to manipulate the values. We use a helper function <code>toIO</code> to make it clearer when we are creating values in the IO monad nested within the Continuation monad.<br />
<br />
=== Example 20 ===<br />
<br />
<haskell><br />
toIO :: a -> IO a<br />
toIO x = return x<br />
<br />
fun :: IO String<br />
fun = do n <- (readLn::IO Int) -- this is an IO monad block<br />
convert n<br />
<br />
convert :: Int -> IO String<br />
convert n = (`runCont` id) $ do -- this is a Cont monad block<br />
str <- callCC $ \exit1 -> do -- str has type IO String<br />
when (n < 10) (exit1 $ toIO (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- n' has type IO Int<br />
when ((length ns) < 3) (exit2 (toIO (length ns)))<br />
when ((length ns) < 5) (exit2 $ do putStrLn "Enter a number:"<br />
x <- (readLn::IO Int)<br />
return x)<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 $ toIO (dropWhile (=='0') ns')<br />
return (toIO (sum ns))<br />
return $ do num <- n' -- this is an IO monad block<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show num)<br />
return $ do s <- str -- this is an IO monad block<br />
return $ "Answer: " ++ s<br />
</haskell><br />
<br />
Even this trivial example has gotten confusing and ugly when we tried to combine different monads in the same computation. It works, but it isn't pretty. Comparing the code side-by-side shows the degree to which the manual monad combination strategy pollutes the code.<br />
<br />
Nested monads from example 19<br />
<br />
<haskell><br />
fun = do n <- (readLn::IO Int)<br />
return $ (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
Manually combined monads from example 20<br />
<br />
<haskell><br />
convert n = (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 $ toIO (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (toIO (length ns)))<br />
when ((length ns) < 5) (exit2 $ do<br />
putStrLn "Enter a number:"<br />
x <- (readLn::IO Int)<br />
return x)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 $ toIO (dropWhile (=='0') ns')<br />
return (toIO (sum ns))<br />
return $ do num <- n'<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show num)<br />
return $ do s <- str<br />
return $ "Answer: " ++ s<br />
</haskell><br />
<br />
== Monad transformers ==<br />
<br />
Monad transformers are special variants of standard monads that facilitate the combining of monads. Their type constructors are parameterized over a monad type constructor, and they produce combined monadic types.<br />
<br />
=== Transformer type constructors ===<br />
<br />
Type constructors play a fundamental role in Haskell's monad support. Recall that <code>Reader r a</code> is the type of values of type <code>a</code> within a Reader monad with environment of type <code>r</code>. The type constructor <code>Reader r</code> is an instance of the <code>Monad</code> class, and the <code>runReader::(r->a)</code> function performs a computation in the Reader monad and returns the result of type <code>a</code>.<br />
<br />
A transformer version of the Reader monad, called <code>ReaderT</code>, exists which adds a monad type constructor as an addition parameter. <code>ReaderT r m a</code> is the type of values of the combined monad in which Reader is the base monad and <code>m</code> is the inner monad. <code>ReaderT r m</code> is an instance of the monad class, and the <code>runReaderT::(r -> m a)</code> function performs a computation in the combined monad and returns a result of type <code>m a</code>.<br />
<br />
Using the transformer versions of the monads, we can produce combined monads very simply. <code>ReaderT r IO</code> is a combined Reader+IO monad. We can also generate the non-transformer version of a monad from the transformer version by applying it to the Identity monad. So <code>ReaderT r Identity</code> is the same monad as <code>Reader r</code>.<br />
<br />
[[Image:info.png]] If your code produces kind errors during compilation, it means that you are not using the type cosntructors properly. Make sure that you have supplied the correct number of parameters to the type constructors and that you have not left out any parenthesis in complex type expressions.<br />
<br />
=== Lifting ===<br />
<br />
When using combined monads created by the monad transformers, we avoid having to explicitly manage the inner monad types, resulting in clearer, simpler code. Instead of creating additional do-blocks within the computation to manipulate values in the inner monad type, we can use lifting operations to bring functions from the inner monad into the combined monad.<br />
<br />
Recall the <code>liftM</code> family of functions which are used to lift non-monadic functions into a monad. Each monad transformer provides a <code>lift</code> function that is used to lift a monadic computation into a combined monad. Many transformers also provide a <code>liftIO</code> function, which is a version of <code>lift</code> that is optimized for lifting computations in the <code>IO</code> monad. To see this in action, we will continue to develop our previous example in the Continuation monad.<br />
<br />
=== Example 21 ===<br />
<br />
<haskell><br />
fun :: IO String<br />
fun = (`runContT` return) $ do<br />
n <- liftIO (readLn::IO Int)<br />
str <- callCC $ \exit1 -> do -- define "exit1"<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do -- define "exit2"<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) $ do liftIO $ putStrLn "Enter a number:"<br />
x <- liftIO (readLn::IO Int)<br />
exit2 x<br />
when ((length ns) < 7) $ do let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns') --escape 2 levels<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
Compare this function using <code>ContT</code>, the transformer version of <code>Cont</code>, with the original version to see how unobtrusive the changes become when using the monad transformer.<br />
<br />
Nested monads from example 19<br />
<br />
<haskell><br />
fun = do n <- (readLn::IO Int)<br />
return $ (`runCont` id) $ do<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) (exit2 n)<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
Monads combined with a transformer from example 21<br />
<br />
<haskell><br />
fun = (`runContT` return) $ do<br />
n <- liftIO (readLn::IO Int)<br />
str <- callCC $ \exit1 -> do<br />
when (n < 10) (exit1 (show n))<br />
let ns = map digitToInt (show (n `div` 2))<br />
n' <- callCC $ \exit2 -> do<br />
when ((length ns) < 3) (exit2 (length ns))<br />
when ((length ns) < 5) $ do<br />
liftIO $ putStrLn "Enter a number:"<br />
x <- liftIO (readLn::IO Int)<br />
exit2 x<br />
when ((length ns) < 7) $ do<br />
let ns' = map intToDigit (reverse ns)<br />
exit1 (dropWhile (=='0') ns')<br />
return $ sum ns<br />
return $ "(ns = " ++ (show ns) ++ ") " ++ (show n')<br />
return $ "Answer: " ++ str<br />
</haskell><br />
<br />
The impact of adding the I/O in the middle of the computation is narrowly confined when using the monad transformer. Contrast this with the [[hardway.html#comparison|changes]] required to achieve the same result using a manually combined monad.<br />
<br />
== Standard monad transformers ==<br />
<br />
Haskell's base libraries provide support for monad transformers in the form of classes which represent monad transformers and special transformer versions of standard monads.<br />
<br />
=== The MonadTrans and MonadIO classes ===<br />
<br />
The <code>MonadTrans</code> class is defined in [https://hackage.haskell.org/package/mtl/docs/Control-Monad-Trans-Class.html Control.Monad.Trans] and provides the single function <code>lift</code>. The <code>lift</code> function lifts a monadic computation in the inner monad into the combined monad.<br />
<br />
<haskell><br />
class MonadTrans t where<br />
lift :: (Monad m) ==> m a -> t m a<br />
</haskell><br />
Monads which provide optimized support for lifting IO operations are defined as members of the <code>MonadIO</code> class, which defines the <code>liftIO</code> function.<br />
<br />
<haskell><br />
class (Monad m) ==> MonadIO m where<br />
liftIO :: IO a -> m a<br />
</haskell><br />
=== Transformer versions of standard monads ===<br />
<br />
The standard monads of the monad template library all have transformer versions which are defined consistently with their non-transformer versions. However, it is not the case the all monad transformers apply the same transformation. We have seen that the <code>ContT</code> transformer turns continuations of the form <code>(a->r)->r</code> into continuations of the form <code>(a->m r)->m r</code>. The <code>StateT</code> transformer is different. It turns state transformer functions of the form <code>s->(a,s)</code> into state transformer functions of the form <code>s->m (a,s)</code>. In general, there is no magic formula to create a transformer version of a monad — the form of each transformer depends on what makes sense in the context of its non-transformer type.<br />
<br />
<table><br />
<tr class="header"><br />
<th align="left">Standard Monad</th><br />
<th align="left">Transformer Version</th><br />
<th align="left">Original Type</th><br />
<th align="left">Combined Type</th><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[errormonad.html|Error]]</td><br />
<td align="left">[https://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Error.html#ErrorT ErrorT]</td><br />
<td align="left"><code>Either e a</code></td><br />
<td align="left"><code>m (Either e a)</code></td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[statemonad.html|State]]</td><br />
<td align="left">[https://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.State.html#StateT StateT]</td><br />
<td align="left"><code>s -> (a,s)</code></td><br />
<td align="left"><code>s -> m (a,s)</code></td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[readermonad.html|Reader]]</td><br />
<td align="left">[https://www.stackage.org/haddock/lts-16.22/mtl-2.2.2/Control-Monad-Reader.html#g:3 ReaderT]</td><br />
<td align="left"><code>r -> a</code></td><br />
<td align="left"><code>r -> m a</code></td><br />
</tr><br />
<tr class="even"><br />
<td align="left">[[writermonad.html|Writer]]</td><br />
<td align="left">[https://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Writer.html#WriterT WriterT]</td><br />
<td align="left"><code>(a,w)</code></td><br />
<td align="left"><code>m (a,w)</code></td><br />
</tr><br />
<tr class="odd"><br />
<td align="left">[[contmonad.html|Cont]]</td><br />
<td align="left">[https://www.haskell.org/ghc/docs/latest/html/base/Control.Monad.Cont.html#ContT ContT]</td><br />
<td align="left"><code>(a -> r) -> r</code></td><br />
<td align="left"><code>(a -> m r) -> m r</code></td><br />
</tr><br />
</table><br />
<br />
[[Image:info.png]] Order is important when combining monads. <code>StateT s (Error e)</code> is different than <code>ErrorT e (State s)</code>. The first produces a combined type of <code>s -> Error e (a,s)</code>, in which the computation can either return a new state or generate an error. The second combination produces a combined type of <code>s -> (Error e a,s)</code>, in which the computation always returns a new state, and the value can be an error or a normal value.<br /><br />
<br />
== Anatomy of a monad transformer ==<br />
<br />
In this section, we will take a detailed look at the implementation of one of the more interesting transformers in the standard library, <code>StateT</code>. Studying this transformer will build insight into the transformer mechanism that you can call upon when using monad transformers in your code. You might want to review the section on the [[statemonad.html|State monad]] before continuing.<br />
<br />
=== Combined monad definition ===<br />
<br />
Just as the State monad was built upon the definition<br />
<br />
<haskell><br />
newtype State s a = State { runState :: (s -> (a,s)) }<br />
</haskell><br />
the StateT transformer is built upon the definition<br />
<br />
<haskell><br />
newtype StateT s m a = StateT { runStateT :: (s -> m (a,s)) }<br />
</haskell><br />
<code>State s</code> is an instance of both the <code>Monad</code> class and the <code>MonadState s</code> class, so <code>StateT s m</code> should also be members of the <code>Monad</code> and <code>MonadState s</code> classes. Furthermore, if <code>m</code> is an instance of <code>MonadPlus</code>, <code>StateT s m</code> should also be a member of <code>MonadPlus</code>.<br />
<br />
To define <code>StateT s m</code> as a <code>Monad</code> instance:<br />
<br />
<haskell><br />
newtype StateT s m a = StateT { runStateT :: (s -> m (a,s)) }<br />
<br />
instance (Monad m) ==> Monad (StateT s m) where<br />
return a = StateT $ \s -> return (a,s)<br />
(StateT x) >>= f = StateT $ \s -> do (v,s') <- x s -- get new value, state<br />
(StateT x') <- return $ f v -- apply bound function to get new state transformation fn<br />
x' s' -- apply the state transformation fn to the new state<br />
</haskell><br />
Compare this to the definition for [[statemonad.html#definition|<code>State s</code>]]. Our definition of <code>return</code> makes use of the <code>return</code> function of the inner monad, and the binding operator uses a do-block to perform a computation in the inner monad.<br />
<br />
We also want to declare all combined monads that use the <code>StateT</code> transformer to be instaces of the <code>MonadState</code> class, so we will have to give definitions for <code>get</code> and <code>put</code>:<br />
<br />
<haskell><br />
instance (Monad m) ==> MonadState s (StateT s m) where<br />
get = StateT $ \s -> return (s,s)<br />
put s = StateT $ \_ -> return ((),s)<br />
</haskell><br />
Finally, we want to declare all combined monads in which <code>StateT</code> is used with an instance of <code>MonadPlus</code> to be instances of <code>MonadPlus</code>:<br />
<br />
<haskell><br />
instance (MonadPlus m) ==> MonadPlus (StateT s m) where<br />
mzero = StateT $ \s -> mzero<br />
(StateT x1) `mplus` (StateT x2) = StateT $ \s -> (x1 s) `mplus` (x2 s)<br />
</haskell><br />
=== Defining the lifting function ===<br />
<br />
The final step to make our monad transformer fully integrated with Haskell's monad classes is to make <code>StateT s</code> an instance of the <code>MonadTrans</code> class by providing a <code>lift</code> function:<br />
<br />
<haskell><br />
instance MonadTrans (StateT s) where<br />
lift c = StateT $ \s -> c >>= (\x -> return (x,s))<br />
</haskell><br />
The <code>lift</code> function creates a <code>StateT</code> state transformation function that binds the computation in the inner monad to a function that packages the result with the input state. The result is that a function that returns a list (i.e., a computation in the List monad) can be lifted into <code>StateT s []</code>, where it becomes a function that returns a <code>StateT (s -> [(a,s)])</code>. That is, the lifted computation produces ''multiple'' (value,state) pairs from its input state. The effect of this is to &quot;fork&quot; the computation in StateT, creating a different branch of the computation for each value in the list returned by the lifted function. Of course, applying <code>StateT</code> to a different monad will produce different semantics for the <code>lift</code> function.<br />
<br />
=== Functors ===<br />
<br />
We have examined the implementation of one monad transformer above, and it was stated earlier that there was no magic formula to produce transformer versions of monads. Each transformer's implementation will depend on the nature of the computational effects it is adding to the inner monad.<br />
<br />
Despite this, there is some theoretical foundation to the theory of monad transformers. Certain transformers can be grouped according to how they use the inner monad, and the transformers within each group can be derived using monadic functions and functors. Functors, roughly, are types which support a mapping operation <code>fmap :: (a->b) -> f a -> f b</code>. To learn more about it, check out Mark Jones' influential [https://web.cecs.pdx.edu/~mpj/pubs/springschool95.pdf paper] that inspired the Haskell monad template library.<br />
<br />
== More examples with monad transformers ==<br />
<br />
At this point, you should know everything you need to begin using monads and monad transformers in your programs. The best way to build proficiency is to work on actual code. As your monadic programs become more abitious, you may find it awkward to mix additional transformers into your combined monads. This will be addressed in the next section, but first you should master the basic process of applying a single transformer to a base monad.<br />
<br />
=== WriterT with IO ===<br />
<br />
Try adapting the [[writermonad.html#example|firewall simulator]] of example 17 to include a timestamp on each log entry (don't worry about merging entries). The necessary changes should look something like this:<br />
<br />
=== Example 22 ===<br />
<br />
<haskell><br />
-- this is the format of our log entries<br />
data Entry = Log {timestamp::ClockTime, msg::String} deriving Eq<br />
<br />
instance Show Entry where<br />
show (Log t s) = (show t) ++ " | " ++ s<br />
<br />
-- this is the combined monad type<br />
type LogWriter a = WriterT [Entry] IO a<br />
<br />
-- add a message to the log<br />
logMsg :: String -> LogWriter ()<br />
logMsg s = do t <- liftIO getClockTime<br />
tell [Log t s]<br />
<br />
-- this handles one packet<br />
filterOne :: [Rule] -> Packet -> LogWriter (Maybe Packet)<br />
filterOne rules packet = do rule <- return (match rules packet)<br />
case rule of<br />
Nothing -> do logMsg ("DROPPING UNMATCHED PACKET: " ++ (show packet))<br />
return Nothing<br />
(Just r) -> do when (logIt r) (logMsg ("MATCH: " ++ (show r) ++ " <=> " ++ (show packet)))<br />
case r of<br />
(Rule Accept _ _) -> return (Just packet)<br />
(Rule Reject _ _) -> return Nothing<br />
<br />
-- this filters a list of packets, producing a filtered packet list<br />
-- and a log of the activity<br />
filterAll :: [Rule] -> [Packet] -> LogWriter [Packet]<br />
filterAll rules packets = do logMsg "STARTING PACKET FILTER"<br />
out <- mapM (filterOne rules) packets<br />
logMsg "STOPPING PACKET FILTER"<br />
return (catMaybes out)<br />
<br />
-- read the rule data from the file named in the first argument, and the packet data from<br />
-- the file named in the second argument, and then print the accepted packets followed by<br />
-- a log generated during the computation.<br />
main :: IO ()<br />
main = do args <- getArgs<br />
ruleData <- readFile (args!!0)<br />
packetData <- readFile (args!!1)<br />
let rules = (read ruleData)::[Rule]<br />
packets = (read packetData)::[Packet]<br />
(out,log) <- runWriterT (filterAll rules packets)<br />
putStrLn "ACCEPTED PACKETS"<br />
putStr (unlines (map show out))<br />
putStrLn "\n\nFIREWALL LOG"<br />
putStr (unlines (map show log))<br />
</haskell><br />
<br />
=== ReaderT with IO ===<br />
<br />
If you found that one too easy, move on to a slightly more complex example: convert the [[readermonad.html#example|template system]] in example 16 from using a single template file with named templates to treating individual files as templates. One possible solution is shown in [[../examples/example23.hs|example 23]], but try to do it without looking first.<br />
<br />
=== Example 23 ===<br />
<br />
<haskell><br />
{- We use the Parsec monadic parser combinator library to parse<br />
template files -}<br />
import Text.ParserCombinators.Parsec<br />
import Text.ParserCombinators.Parsec.Token<br />
<br />
import IO hiding (try) -- "try" is also defined in the Parsec libraries<br />
import qualified IO (try)<br />
import Monad<br />
import System<br />
import List (intersperse)<br />
import Control.Monad.Reader<br />
<br />
-- This the abstract syntax representation of a template<br />
-- Text Variable Quote Include Compound<br />
data Template = T String | V Template | Q Template | I Template [Definition] | C [Template]<br />
data Definition = D Template Template<br />
<br />
-- Templates are members of the Show class<br />
instance Show Template where<br />
show (T s) = s<br />
show (V t) = "${" ++ (show t) ++ "}"<br />
show (Q t) = "$\"" ++ (show t) ++ "\""<br />
show (I t ds) = let name = (show t)<br />
definitions = concat (intersperse ", " (map show ds))<br />
in case definitions of<br />
[] -> "$<" ++ name ++ ">"<br />
otherwise -> "$<" ++ name ++ "|" ++ definitions ++ ">"<br />
show (C ts) = concatMap show ts<br />
<br />
instance Show Definition where<br />
show (D t d) = (show t) ++ "=" ++ (show d)<br />
<br />
{- Here we define a parser for templates. -}<br />
<br />
-- parse a (possibly compound) template.<br />
-- the [Char] argument is a list of characters not allowed in the template.<br />
template :: [Char] -> Parser Template<br />
template except = do ts <- many1 (simpleTemplate except)<br />
case ts of<br />
[t] -> return t<br />
otherwise -> return (C ts)<br />
<br />
-- parse a simple template: text, a variable pattern, a quote pattern, or a include pattern<br />
-- the [Char] argument is a list of characters not allowed in the template.<br />
simpleTemplate :: [Char] -> Parser Template<br />
simpleTemplate except = (text except)<br />
<|> (try variable)<br />
<|> (try quote)<br />
<|> include<br />
<br />
-- parse a dollar-sign that doesn't begin a variable, quote, or include pattern<br />
dollar :: Parser Char<br />
dollar = try (do c <- char '$'<br />
notFollowedBy (oneOf "{<\"")<br />
return c)<br />
<?> ""<br />
<br />
-- parse a character that isn't part of a pattern and<br />
-- isn't in the list of excluded characters.<br />
textChar :: [Char] -> Parser Char<br />
textChar except = noneOf ("$" ++ except) <|> dollar<br />
<br />
-- parse a string of allowed characters<br />
-- the [Char] argument is a list of characters not allowed in the text.<br />
text :: [Char] -> Parser Template<br />
text except = do str <- many1 (textChar except)<br />
return (T str)<br />
<?> "text"<br />
<br />
-- parse a variable pattern<br />
variable :: Parser Template<br />
variable = do t <- between (string "${") (char '}') (template "}")<br />
return (V t)<br />
<?> "variable pattern"<br />
<br />
-- parse a quoted-inclusion pattern<br />
quote :: Parser Template<br />
quote = do t <- between (string "$\"") (char '\"') (template "\"")<br />
return (Q t)<br />
<?> "quoted include pattern"<br />
<br />
-- parse a resolved-inclusion pattern<br />
include :: Parser Template<br />
include = between (string "$<") (char '>') includeBody<br />
<?> "include pattern"<br />
<br />
-- parse the body of an inclusion pattern<br />
includeBody :: Parser Template<br />
includeBody = do t <- (template "|>")<br />
ds <- option [] definitions<br />
return (I t ds)<br />
<br />
-- parse a list of definitions<br />
definitions :: Parser [Definition]<br />
definitions = do char '|'<br />
ds <- definition `sepBy1` (char ',')<br />
return ds<br />
<br />
-- parse a single definition<br />
definition :: Parser Definition<br />
definition = do t1 <- (template "=,>")<br />
char '='<br />
t2 <- (template ",>")<br />
return (D t1 t2)<br />
<?> "variable definition"<br />
<br />
-- Our environment consists of an association list of named variable values<br />
-- an association list of named variable values.<br />
type Environment = [(String,String)]<br />
<br />
-- lookup a variable from the environment<br />
lookupVar :: String -> Environment -> Maybe String<br />
lookupVar = lookup<br />
<br />
-- add a list of resolved definitions to the environment<br />
addDefs :: [(String,String)] -> Environment -> Environment<br />
addDefs = (++)<br />
<br />
-- this is the type of our monad<br />
type TemplateReader a = ReaderT Environment IO a<br />
<br />
-- resolve a Definition and produce a (name,value) pair<br />
resolveDef :: Definition -> TemplateReader (String,String)<br />
resolveDef (D t d) = do name <- resolve t<br />
value <- resolve d<br />
return (name,value)<br />
<br />
-- resolve a template into a string<br />
resolve :: Template -> TemplateReader String<br />
resolve (T s) = return s<br />
resolve (V t) = do varName <- resolve t<br />
varValue <- asks (lookupVar varName)<br />
case varValue of<br />
Just s -> return s<br />
Nothing -> return ""<br />
resolve (Q t) = do tmplName <- resolve t<br />
body <- liftIO $ IO.try (readFile tmplName)<br />
case body of<br />
Left err -> do liftIO $ hPutStrLn stderr (show err)<br />
return ""<br />
Right s -> return s<br />
resolve (I t ds) = do tmplName <- resolve t<br />
body <- liftIO $ IO.try (parseFromFile (template []) tmplName)<br />
case body of<br />
Left err -> do liftIO $ hPutStrLn stderr (show err)<br />
return ""<br />
Right (Left err') -> do liftIO $ hPutStrLn stderr (show err')<br />
return ""<br />
Right (Right t') -> do defs <- mapM resolveDef ds<br />
local (addDefs defs) (resolve t')<br />
resolve (C ts) = (liftM concat) (mapM resolve ts)<br />
<br />
-- Read the command line arguments, parse the template file, the user template, and any<br />
-- variable definitions. Then construct the environment and print the resolved user template.<br />
main :: IO ()<br />
main = do args <- getArgs<br />
let pattern = args!!0<br />
defs = map (break (=='=')) (drop 1 args) -- split into ("var","=value")<br />
env = map (\ (x,y) -> (x,tail y)) defs -- get rid of '='<br />
case parse (template []) "template" pattern of<br />
Left err -> hPutStrLn stderr (show err)<br />
Right t -> (runReaderT (resolve t) env) >>= putStr<br />
<br />
-- END OF FILE<br />
</haskell><br />
<br />
=== StateT with List ===<br />
<br />
The previous examples have all been using the IO monad as the inner monad. Here is a more interesting example: combining <code>StateT</code> with the List monad to produce a monad for stateful nondeterministic computations.<br />
<br />
We will apply this powerful monad combination to the task of solving constraint satisfaction problems (in this case, a logic problem). The idea behind it is to have a number of variables that can take on different values and a number of predicates involving those variables that must be satisfied. The current variable assignments and the predicates make up the state of the computation, and the non-deterministic nature of the List monad allows us to easily test all combinations of variable assignments.<br />
<br />
We start by laying the groundwork we will need to represent the logic problem, a simple predicate language:<br />
<br />
=== Example 24 ===<br />
<br />
<haskell><br />
-- First, we develop a language to express logic problems<br />
type Var = String<br />
type Value = String<br />
data Predicate = Is Var Value -- var has specific value<br />
| Equal Var Var -- vars have same (unspecified) value<br />
| And Predicate Predicate -- both are true<br />
| Or Predicate Predicate -- at least one is true<br />
| Not Predicate -- it is not true<br />
deriving (Eq, Show)<br />
<br />
type Variables = [(Var,Value)]<br />
<br />
-- test for a variable NOT equaling a value<br />
isNot :: Var -> Value -> Predicate<br />
isNot var value = Not (Is var value)<br />
<br />
-- if a is true, then b must also be true<br />
implies :: Predicate -> Predicate -> Predicate<br />
implies a b = Not (a `And` (Not b))<br />
<br />
-- exclusive or<br />
orElse :: Predicate -> Predicate -> Predicate<br />
orElse a b = (a `And` (Not b)) `Or` ((Not a) `And` b)<br />
<br />
-- Check a predicate with the given variable bindings.<br />
-- An unbound variable causes a Nothing return value.<br />
check :: Predicate -> Variables -> Maybe Bool<br />
check (Is var value) vars = do val <- lookup var vars<br />
return (val == value)<br />
check (Equal v1 v2) vars = do val1 <- lookup v1 vars<br />
val2 <- lookup v2 vars<br />
return (val1 == val2)<br />
check (And p1 p2) vars = liftM2 (&&) (check p1 vars) (check p2 vars)<br />
check (Or p1 p2) vars = liftM2 (||) (check p1 vars) (check p2 vars)<br />
check (Not p) vars = liftM (not) (check p vars)<br />
</haskell><br />
<br />
The next thing we will need is some code for representing and solving constraint satisfaction problems. This is where we will define our combined monad.<br />
<br />
<haskell><br />
-- this is the type of our logic problem<br />
data ProblemState = PS {vars::Variables, constraints::[Predicate]}<br />
<br />
-- this is our monad type for non-determinstic computations with state<br />
type NDS a = StateT ProblemState [] a<br />
<br />
-- lookup a variable<br />
getVar :: Var -> NDS (Maybe Value)<br />
getVar v = do vs <- gets vars<br />
return $ lookup v vs<br />
<br />
-- set a variable<br />
setVar :: Var -> Value -> NDS ()<br />
setVar v x = do st <- get<br />
vs' <- return $ filter ((v/=).fst) (vars st)<br />
put $ st {vars=(v,x):vs'}<br />
<br />
-- Check if the variable assignments satisfy all of the predicates.<br />
-- The partial argument determines the value used when a predicate returns<br />
-- Nothing because some variable it uses is not set. Setting this to True<br />
-- allows us to accept partial solutions, then we can use a value of<br />
-- False at the end to signify that all solutions should be complete.<br />
isConsistent :: Bool -> NDS Bool<br />
isConsistent partial = do cs <- gets constraints<br />
vs <- gets vars<br />
let results = map (\p->check p vs) cs<br />
return $ and (map (maybe partial id) results)<br />
<br />
-- Return only the variable bindings that are complete consistent solutions.<br />
getFinalVars :: NDS Variables<br />
getFinalVars = do c <- isConsistent False<br />
guard c<br />
gets vars<br />
<br />
-- Get the first solution to the problem, by evaluating the solver computation with<br />
-- an initial problem state and then returning the first solution in the result list,<br />
-- or Nothing if there was no solution.<br />
getSolution :: NDS a -> ProblemState -> Maybe a<br />
getSolution c i = listToMaybe (evalStateT c i)<br />
<br />
-- Get a list of all possible solutions to the problem by evaluating the solver<br />
-- computation with an initial problem state.<br />
getAllSolutions :: NDS a -> ProblemState -> [a]<br />
getAllSolutions c i = evalStateT c i<br />
</haskell><br />
We are ready to apply the predicate language and stateful nondeterministic monad to solving a logic problem. For this example, we will use the well-known Kalotan puzzle which appeared in ''Mathematical Brain-Teasers'', Dover Publications (1976), by J. A. H. Hunter.<br />
<br />
<blockquote>The Kalotans are a tribe with a peculiar quirk: their males always tell the truth. Their females never make two consecutive true statements, or two consecutive untrue statements. An anthropologist (let's call him Worf) has begun to study them. Worf does not yet know the Kalotan language. One day, he meets a Kalotan (heterosexual) couple and their child Kibi. Worf asks Kibi: ``Are you a boy?'' The kid answers in Kalotan, which of course Worf doesn't understand. Worf turns to the parents (who know English) for explanation. One of them says: &quot;Kibi said: `I am a boy.'&quot; The other adds: &quot;Kibi is a girl. Kibi lied.&quot; Solve for the sex of Kibi and the sex of each parent.</blockquote><br />
We will need some additional predicates specific to this puzzle, and to define the universe of allowed variables values:<br />
<br />
<haskell><br />
-- if a male says something, it must be true<br />
said :: Var -> Predicate -> Predicate<br />
said v p = (v `Is` "male") `implies` p<br />
<br />
-- if a male says two things, they must be true<br />
-- if a female says two things, one must be true and one must be false<br />
saidBoth :: Var -> Predicate -> Predicate -> Predicate<br />
saidBoth v p1 p2 = And ((v `Is` "male") `implies` (p1 `And` p2))<br />
((v `Is` "female") `implies` (p1 `orElse` p2))<br />
<br />
-- lying is saying something is true when it isn't or saying something isn't true when it is<br />
lied :: Var -> Predicate -> Predicate<br />
lied v p = ((v `said` p) `And` (Not p)) `orElse` ((v `said` (Not p)) `And` p)<br />
<br />
-- Test consistency over all allowed settings of the variable.<br />
tryAllValues :: Var -> NDS ()<br />
tryAllValues var = do (setVar var "male") `mplus` (setVar var "female")<br />
c <- isConsistent True<br />
guard c<br />
</haskell><br />
<br />
All that remains to be done is to define the puzzle in the predicate language and get a solution that satisfies all of the predicates:<br />
<br />
<haskell><br />
-- Define the problem, try all of the variable assignments and print a solution.<br />
main :: IO ()<br />
main = do let variables = []<br />
constraints = [ Not (Equal "parent1" "parent2"),<br />
"parent1" `said` ("child" `said` ("child" `Is` "male")),<br />
saidBoth "parent2" ("child" `Is` "female")<br />
("child" `lied` ("child" `Is` "male")) ]<br />
problem = PS variables constraints<br />
print $ (`getSolution` problem) $ do tryAllValues "parent1"<br />
tryAllValues "parent2"<br />
tryAllValues "child"<br />
getFinalVars<br />
</haskell><br />
<br />
Each call to <code>tryAllValues</code> will fork the solution space, assigning the named variable to be <code>"male"</code> in one fork and <code>"female"</code> in the other. The forks which produce inconsistent variable assignments are eliminated (using the <code>guard</code> function). The call to <code>getFinalVars</code> applies <code>guard</code> again to eliminate inconsistent variable assignments and returns the remaining assignments as the value of the computation.<br />
<br />
== Managing the transformer stack ==<br />
<br />
As the number of monads combined together increases, it becomes increasingly important to manage the stack of monad transformers well.<br />
<br />
=== Selecting the correct order ===<br />
<br />
Once you have decided on the monad features you need, you must choose the correct order in which to apply the monad transformers to achieve the results you want. For instance you may know that you want a combined monad that is an instance of <code>MonadError</code> and <code>MonadState</code>, but should you apply <code>StateT</code> to the <code>Error</code> monad or <code>ErrorT</code> to the <code>State</code> monad?<br />
<br />
The decision depends on the exact semantics you want for your combined monad. Applying <code>StateT</code> to the <code>Error</code> monad gives a state transformer function of type <code>s -> Error e (a,s)</code>. Applying <code>ErrorT</code> to the <code>State</code> monad gives a state transformer function of type <code>s -> (Error e a,s)</code>. Which order to choose depends on the role of errors in your computation. If an error means no state could be produced, you would apply <code>StateT</code> to <code>Error</code>. If an error means no value could be produced, but the state remains valid, then you would apply <code>ErrorT</code> to <code>State</code>.<br />
<br />
Choosing the correct order requires understanding the transformation carried out by each monad transformer, and how that transformation affects the semantics of the combined monad.<br />
<br />
=== An example with multiple transformers ===<br />
<br />
The following example demonstrates the use of multiple monad transformers. The code uses the StateT monad transformer along with the List monad to produce a combined monad for doing stateful nondeterministic computations. In this case, however, we have added the <code>WriterT</code> monad transformer to perform logging during the computation. The problem we will apply this monad to is the famous N-queens problem: to place N queens on a chess board so that no queen can attack another.<br />
<br />
The first decision is in what order to apply the monad transformers. <code>StateT s (WriterT w [])</code> yields a type like: <code>s -> [((a,s),w)]</code>. <code>WriterT w (StateT s [])</code> yields a type like: <code>s -> [((a,w),s)]</code>. In this case, there is little difference between the two orders, so we will choose the second arbitrarily.<br />
<br />
Our combined monad is an instance of both <code>MonadState</code> and <code>MonadWriter</code>, so we can freely mix use of <code>get</code>, <code>put</code>, and <code>tell</code> in our monadic computations.<br />
<br />
=== Example 25 ===<br />
<br />
<haskell><br />
-- this is the type of our problem description<br />
data NQueensProblem = NQP {board::Board,<br />
ranks::[Rank], files::[File],<br />
asc::[Diagonal], desc::[Diagonal]}<br />
<br />
-- initial state = empty board, all ranks, files, and diagonals free<br />
initialState = let fileA = map (\r->Pos A r) [1..8]<br />
rank8 = map (\f->Pos f 8) [A .. H]<br />
rank1 = map (\f->Pos f 1) [A .. H]<br />
asc = map Ascending (nub (fileA ++ rank1))<br />
desc = map Descending (nub (fileA ++ rank8))<br />
in NQP (Board []) [1..8] [A .. H] asc desc<br />
<br />
-- this is our combined monad type for this problem<br />
type NDS a = WriterT [String] (StateT NQueensProblem []) a<br />
<br />
-- Get the first solution to the problem, by evaluating the solver computation with<br />
-- an initial problem state and then returning the first solution in the result list,<br />
-- or Nothing if there was no solution.<br />
getSolution :: NDS a -> NQueensProblem -> Maybe (a,[String])<br />
getSolution c i = listToMaybe (evalStateT (runWriterT c) i)<br />
<br />
-- add a Queen to the board in a specific position<br />
addQueen :: Position -> NDS ()<br />
addQueen p = do (Board b) <- gets board<br />
rs <- gets ranks<br />
fs <- gets files<br />
as <- gets asc<br />
ds <- gets desc<br />
let b' = (Piece Black Queen, p):b<br />
rs' = delete (rank p) rs<br />
fs' = delete (file p) fs<br />
(a,d) = getDiags p<br />
as' = delete a as<br />
ds' = delete d ds<br />
tell ["Added Queen at " ++ (show p)]<br />
put (NQP (Board b') rs' fs' as' ds')<br />
<br />
-- test if a position is in the set of allowed diagonals<br />
inDiags :: Position -> NDS Bool<br />
inDiags p = do let (a,d) = getDiags p<br />
as <- gets asc<br />
ds <- gets desc<br />
return $ (elem a as) && (elem d ds)<br />
<br />
-- add a Queen to the board in all allowed positions<br />
addQueens :: NDS ()<br />
addQueens = do rs <- gets ranks<br />
fs <- gets files<br />
allowed <- filterM inDiags [Pos f r | f <- fs, r <- rs]<br />
tell [show (length allowed) ++ " possible choices"]<br />
msum (map addQueen allowed)<br />
<br />
-- Start with an empty chess board and add the requested number of queens,<br />
-- then get the board and print the solution along with the log<br />
main :: IO ()<br />
main = do args <- getArgs<br />
let n = read (args!!0)<br />
cmds = replicate n addQueens<br />
sol = (`getSolution` initialState) $ do sequence_ cmds<br />
gets board<br />
case sol of<br />
Just (b,l) -> do putStr $ show b -- show the solution<br />
putStr $ unlines l -- show the log<br />
Nothing -> putStrLn "No solution"<br />
</haskell><br />
The program operates in a similar manner to the previous example, which solved the kalotan puzzle. In this example, however, we do not test for consistency using the <code>guard</code> function. Instead, we only create branches that correspond to allowed queen positions. We use the added logging facility to log the number of possible choices at each step and the position in which the queen was placed.<br />
<br />
=== Heavy lifting ===<br />
<br />
There is one subtle problem remaining with our use of multiple monad transformers. Did you notice that all of the computations in the previous example are done in the combined monad, even if they only used features of one monad? The code for these functions in tied unneccessarily to the definition of the combined monad, which decreases their reusability.<br />
<br />
This is where the <code>lift</code> function from the <code>MonadTrans</code> class comes into its own. The <code>lift</code> function gives us the ability to write our code in a clear, modular, reusable manner and then lift the computations into the combined monad as needed.<br />
<br />
Instead of writing brittle code like:<br />
<br />
<haskell><br />
logString :: String -> StateT MyState (WriterT [String] []) Int<br />
logString s = ...<br />
</haskell><br />
we can write clearer, more flexible code like:<br />
<br />
<haskell><br />
logString :: (MonadWriter [String] m) ==> String -> m Int<br />
logString s = ...<br />
</haskell><br />
and then lift the <code>logString</code> computation into the combined monad when we use it.<br />
<br />
[[Image:info.png]] You may need to use the compiler flags <code>-fglasgow-exts</code> with GHC or the equivalent flags with your Haskell compiler to use this technique. The issue is that <code>m</code> in the constraint above is a type constructor, not a type, and this is not supported in standard Haskell 2010. <br /><br />
<br />
<br />
When using lifting with complex transformer stacks, you may find yourself composing multiple lifts, like <code>lift . lift . lift $ f x</code>. This can become hard to follow, and if the transformer stack changes (perhaps you add <code>ErrorT</code> into the mix) the lifting may need to be changed all over the code. A good practice to prevent this is to declare helper functions with informative names to do the lifting:<br />
<br />
<haskell><br />
liftListToState = lift . lift . lift<br />
</haskell><br />
Then, the code is more informative and if the transformer stack changes, the impact on the lifting code is confined to a small number of these helper functions.<br />
<br />
The hardest part about lifting is understanding the semantics of lifting computations, since this depends on the details of the inner monad and the transformers in the stack. As a final task, try to understand the different roles that lifting plays in the following example code. Can you predict what the output of the program will be?<br />
<br />
=== Example 26 ===<br />
<br />
<haskell><br />
-- this is our combined monad type for this problem<br />
type NDS a = StateT Int (WriterT [String] []) a<br />
<br />
{- Here is a computation on lists -}<br />
<br />
-- return the digits of a number as a list<br />
getDigits :: Int -> [Int]<br />
getDigits n = let s = (show n)<br />
in map digitToInt s<br />
<br />
{- Here are some computations in MonadWriter -}<br />
<br />
-- write a value to a log and return that value<br />
logVal :: (MonadWriter [String] m) ==> Int -> m Int<br />
logVal n = do tell ["logVal: " ++ (show n)]<br />
return n<br />
<br />
-- do a logging computation and return the length of the log it wrote<br />
getLogLength :: (MonadWriter [[a]] m) ==> m b -> m Int<br />
getLogLength c = do (_,l) <- listen $ c<br />
return (length (concat l))<br />
<br />
-- log a string value and return 0<br />
logString :: (MonadWriter [String] m) ==> String -> m Int<br />
logString s = do tell ["logString: " ++ s]<br />
return 0<br />
<br />
{- Here is a computation that requires a WriterT [String] [] -}<br />
<br />
-- "Fork" the computation and log each list item in a different branch.<br />
logEach :: (Show a) ==> [a] -> WriterT [String] [] a<br />
logEach xs = do x <- lift xs<br />
tell ["logEach: " ++ (show x)]<br />
return x<br />
<br />
{- Here is a computation in MonadState -}<br />
<br />
-- increment the state by a specified value<br />
addVal :: (MonadState Int m) ==> Int -> m ()<br />
addVal n = do x <- get<br />
put (x+n)<br />
<br />
{- Here are some computations in the combined monad -}<br />
<br />
-- set the state to a given value, and log that value<br />
setVal :: Int -> NDS ()<br />
setVal n = do x <- lift $ logVal n<br />
put x<br />
<br />
-- "Fork" the computation, adding a different digit to the state in each branch.<br />
-- Because setVal is used, the new values are logged as well.<br />
addDigits :: Int -> NDS ()<br />
addDigits n = do x <- get<br />
y <- lift . lift $ getDigits n<br />
setVal (x+y)<br />
<br />
{- an equivalent construction is:<br />
addDigits :: Int -> NDS ()<br />
addDigits n = do x <- get<br />
msum (map (\i->setVal (x+i)) (getDigits n))<br />
-}<br />
<br />
{- This is an example of a helper function that can be used to put all of the lifting logic<br />
in one location and provide more informative names. This has the advantage that if the<br />
transformer stack changes in the future (say, to add ErrorT) the changes to the existing<br />
lifting logic are confined to a small number of functions.<br />
-}<br />
liftListToNDS :: [a] -> NDS a<br />
liftListToNDS = lift . lift<br />
<br />
-- perform a series of computations in the combined monad, lifting computations from other<br />
-- monads as necessary.<br />
main :: IO ()<br />
main = do mapM_ print $ runWriterT $ (`evalStateT` 0) $ do x <- lift $ getLogLength $ logString "hello"<br />
addDigits x<br />
x <- lift $ logEach [1,3,5]<br />
lift $ logVal x<br />
liftListToNDS $ getDigits 287<br />
<br />
</haskell><br />
Once you fully understand how the various lifts in the example work and how lifting promotes code reuse, you are ready for real-world monadic programming. All that is left to do is to hone your skills writing real software. Happy hacking!<br />
<br />
== Continuing Exploration ==<br />
<br />
This brings us to the end of this tutorial. If you want to continue learning about the mathematical foundations of monads, there are numerous [https://plato.stanford.edu/entries/category-theory/ category theory] resources on the internet. For more examples of monads and their applications in the real world, you might want to explore the design of the [https://www.cs.uu.nl/people/daan/papers/parsec.html Parsec] monadic parser combinator library and/or the [[Introduction to QuickCheck2 | QuickCheck]] testing tool. You may also be interested in [https://www.haskell.org/arrows/ arrows], which are similar to monads but more general.<br />
<br />
If you discover any errors — no matter how small — in this document, or if you have suggestions for how it can be improved, please write to the author at [mailto:jnewbern@yahoo.com jnewbern@yahoo.com].<br />
<br />
== A physical analogy for monads ==<br />
<br />
Because monads are such abstract entities, it is sometimes useful to think about a physical system that is analogous to a monad instead of thinking about monads directly. In this way, we can use our physical intuition and experiences to gain insights that we can relate back to the abstract world of computational monads.<br />
<br />
The particular physical analogy developed here is that of a mechanized assembly line. It is not a perfect fit for monads — especially with some of the higher-order aspects of monadic computation — but I believe it could be helpful to gain the initial understanding of how a monad works.<br />
<br />
Begin by thinking about a Haskell program as a conveyor belt. Input goes on end of the conveyor belt and is carried to a succession of work areas. At each work area, some operation is performed on the item on the conveyor belt and the result is carried by the conveyor belt to the next work area. Finally, the conveyor belt carries the final product to the end of the assembly line to be output.<br />
<br />
In this assembly line model, our physical monad is a system of machines that controls how successive work areas on the assembly line combine their functionality to create the overall product.<br />
<br />
Our monad consists of three parts:<br />
<br />
# Trays that hold work products as they move along the conveyor belt.<br />
# Loader machines that can put any object into a tray.<br />
# Combiner machines that can take a tray with an object and produce a tray with a new object. These combiner machines are attached to worker machines that actualy produce the new objects.<br />
<br />
We use the monad by setting up our assembly line as a loader machine which puts materials into trays at the beginning of the assembly line. The conveyor belt then carries these trays to each work area, where a combiner machine takes the tray and may decide based on its contents whether to run them through a worker machine, as shown in Figure A-1.<br />
<br />
<table><br />
<tbody><br />
<tr class="odd"><br />
<td align="left">[[Image:figureA-1.png]]</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">Figure A-1. An assembly line using a monad architecture.</td><br />
</tr><br />
</tbody><br />
</table><br />
<br />
The important thing to notice about the monadic assembly line is that it separates out the work of combining the output of the worker machines from the actual work done by the worker machines. Once they are separated, we can vary them independently. So the same combiner machines could be used on an assembly line to make airplanes and an assembly line to make chopsticks. Likewise, the same worker machines could be used with different combiners to alter the way the final product is produced.<br />
<br />
Lets take the example of an assembly line to make chopsticks, and see how it is handled in our physical analogy and how me might represent it as a program in Haskell. We will have three worker machines. The first takes small pieces of wood as input and outputs a tray containing a pair of roughly shaped chopsticks. The second takes a pair of roughly shaped chopsticks and outputs a tray containing a pair of smooth, polished chopsticks with the name of the restaurant printed on them. The third takes a pair of polished chopsticks and outputs a tray containing a finished pair of chopsticks in a printed paper wrapper. We could represent this in Haskell as:<br />
<br />
<haskell><br />
-- the basic types we are dealing with<br />
type Wood = ...<br />
type Chopsticks = ...<br />
data Wrapper x = Wrapper x<br />
<br />
-- NOTE: the Tray type comes from the Tray monad<br />
<br />
-- worker function 1: makes roughly shaped chopsticks<br />
makeChopsticks :: Wood -> Tray Chopsticks<br />
makeChopsticks w = ...<br />
<br />
-- worker function 2: polishes chopsticks<br />
polishChopsticks :: Chopsticks -> Tray Chopsticks<br />
polishChopsticks c = ...<br />
<br />
-- worker function 3: wraps chopsticks<br />
wrapChopsticks :: Chopsticks -> Tray Wrapper Chopsticks<br />
wrapChopsticks c = ...<br />
</haskell><br />
It is clear that the worker machines contain all of the functionality needed to produce chopsticks. What is missing is the specification of the trays, loader, and combiner machines that collectively make up the Tray monad. Our trays should either be empty or contain a single item. Our loader machine would simply take an item and place it in a tray on the conveyor belt. The combiner machine would take each input tray and pass along empty trays while feeding the contents of non-empty trays to its worker machine. In Haskell, we would define the <code>Tray</code> monad as:<br />
<br />
<haskell><br />
-- trays are either empty or contain a single item<br />
data Tray x = Empty | Contains x<br />
<br />
-- Tray is a monad<br />
instance Monad Tray where<br />
Empty >>= _ = Empty<br />
(Contains x) >>= worker = worker x<br />
return = Contains<br />
fail _ = Empty<br />
</haskell><br />
[[Image:info.png]] You may recognize the <code>Tray</code> monad as a disguised version of the <code>Maybe</code> monad that is a standard part of Haskell 2010 library. <br /><br />
<br />
<br />
All that remains is to sequence the worker machines together using the loader and combiner machines to make a complete assembly line, as shown in Figure A-2.<br />
<br />
<table><br />
<tbody><br />
<tr class="odd"><br />
<td align="left">[[Image:figureA-2.png]]</td><br />
</tr><br />
<tr class="even"><br />
<td align="left">Figure A-2. A complete assembly line for making chopsticks using a monadic approach.</td><br />
</tr><br />
</tbody><br />
</table><br />
<br />
In Haskell, the sequencing can be done using the standard monadic functions:<br />
<br />
<haskell><br />
assemblyLine :: Wood -> Tray Wrapped Chopsticks<br />
assemblyLine w = (return w) >>= makeChopsticks >>= polishChopsticks >>= wrapChopsticks<br />
</haskell><br />
or using the built in Haskell &quot;do&quot; notation for monads:<br />
<br />
<haskell><br />
assemblyLine :: Wood -> Tray Wrapped Chopsticks<br />
assemblyLine w = do c <- makeChopsticks w<br />
c' <- polishChopsticks c<br />
c'' <- wrapChopsticks c'<br />
return c''<br />
</haskell><br />
So far, you have seen how monads are like a framework for building assembly lines, but you probably haven't been overawed by their utility. To see why we might want to build our assembly line using the monadic approach, consider what would happen if we wanted to change the manufacturing process.<br />
<br />
Right now, when a worker machine malfunctions, it uses the <code>fail</code> routine to produce an empty tray. The <code>fail</code> routine takes an argument describing the failure, but our <code>Tray</code> type ignores this and simply produces an empty tray. This empty tray travels down the assembly line and the combiner machines allow it to bypass the remaining worker machines. It eventually reaches the end of the assembly line, where it is brought to you, the quality control engineer. It is your job to figure out which machine failed, but all you have to go on is an empty tray.<br />
<br />
You realize that your job would be much easier if you took advantage of the failure messages that are currently ignored by the <code>fail</code> routine in your <code>Tray</code> monad. Because your assembly line is organized around a monadic approach, it is easy for you to add this functionality to your assembly line without changing your worker machines.<br />
<br />
To make the change, you simply create a new tray type that can never be empty. It will always either contain an item or it will contain a failure report describing the exact reason there is no item in the tray.<br />
<br />
<haskell><br />
-- tray2s either contain a single item or contain a failure report<br />
data Tray2 x = Contains x | Failed String<br />
<br />
-- Tray2 is a monad<br />
instance Monad Tray2 where<br />
(Failed reason) >>= _ = Failed reason<br />
(Contains x) >>= worker = worker x<br />
return = Contains<br />
fail reason = Failed reason<br />
</haskell><br />
[[Image:info.png]] You may recognize the <code>Tray2</code> monad as a disguised version of the <code>Error</code> monad that is a standard part of the Haskell 2010 libraries.<br /><br />
<br />
<br />
Replacing the <code>Tray</code> monad with the <code>Tray2</code> monad instantly upgrades your assembly line. Now when a failure occurs, the tray that is brought to the quality control engineer contains a failure report detailing the exact cause of the failure!<br />
<br />
== Haskell code examples ==<br />
<br />
This appendix contains a list of all of the code supplied with the tutorial. The source code can be [https://web.archive.org/web/20061210172052/https://www.nomaware.com/monads/html/examples.html found here].<br />
<br />
=== [[All_About_Monads#Example 1|Example 1]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Meet the Monads|Meet the Monads]].<br />
<br />
The example code introduces the monad concept without using Haskell typeclasses. It shows how a monadic combinator can be used to simplify the construction of computations from sequences of computations which may not return a result.<br />
<br />
=== [[All_About_Monads#Example 2|Example 2]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Doing_it_with_class|Doing it with class]]<br />
<br />
The example code builds on the first example, and shows how do-notation can be used with an instance of the <code>Monad</code> class (in this case, <code>Maybe</code> is the monad used).<br />
<br />
=== [[All_About_Monads#Example 3|Example 3]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code builds on the first two examples, and shows a somewhat atypical — but very powerful — use of the <code>foldM</code> function outside of a do-block.<br />
<br />
=== [[All_About_Monads#Example 4|Example 4]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows a more typical use of the <code>foldM</code> function within a do-block. It combines dictionary values read from different files into a single dictionary using the <code>foldM</code> function within the IO monad.<br />
<br />
=== [[All_About_Monads#Example 5|Example 5]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows the use of the <code>filterM</code> function within a do-block. It prints the subset of its arguments that specify directories and ignores non-directory arguments.<br />
<br />
=== [[All_About_Monads#Example 6|Example 6]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows the use of the <code>liftM</code> function within a do-block. It looks up a name in a list and uses a lifted String manipulation function to modify it within the Maybe monad.<br />
<br />
=== [[All_About_Monads#Example 7|Example 7]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows a higher-order application of <code>liftM2</code>. It folds lifted operations within the List monad to produce lists of all combinations of elements combined with the lifted operator.<br />
<br />
=== [[All_About_Monads#Example 8|Example 8]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows a higher-order application of <code>ap</code>. It folds <code>ap</code> through a list of <code>Maybe (a->a)</code> functions to process sequences of commands.<br />
<br />
=== [[All_About_Monads#Example 9|Example 9]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows the use of <code>msum</code> in the Maybe monad to select the first variable match in a stack of binding environments.<br />
<br />
=== [[All_About_Monads#Example 10|Example 10]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad_support_in_Haskell|Monad support in Haskell]].<br />
<br />
The example code shows the use of <code>guard</code> in the Maybe monad to select only the records from a list that satisfy a predicate (equivalent to <code>filter</code>).<br />
<br />
=== [[All_About_Monads#Example 11|Example 11]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The_Maybe_monad|The Maybe monad]].<br />
<br />
The example code shows how to use the <code>Maybe</code> monad to build complex queries from simpler queries that may fail to return a result. The specific example used is looking up mail preferences for someone based on either their full name or a nickname.<br />
<br />
=== [[All_About_Monads#Example 12|Example 12]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The_Error_monad|The Error monad]].<br />
<br />
The example code demonstrates the use of the <code>Either</code> type constructor as an <code>Error</code> monad with a custom error type. The example parses hexadecimal digits and uses the exception handling mechanism of the <code>Error</code> monad to provide informative error messages in the event of a parse failure.<br />
<br />
=== [[All_About_Monads#Example 13|Example 13]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The List monad|The List monad]].<br />
<br />
The example code uses the built-in list type constructor as a monad for non-deterministic computation. The example demonstrates parsing an ambiguous grammar consisting of integers, hex values, and words.<br />
<br />
=== [[All_About_Monads#Example 14|Example 14]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The IO monad|The IO monad]].<br />
<br />
The example code implements a simple version of the standard Unix command &quot;tr&quot;. The example demonstrates use of the IO monad including implicit <code>fail</code> calls due to pattern matching failures and the use of <code>catcherror</code>.<br />
<br />
=== [[All_About_Monads#Example 15|Example 15]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The State monad|The State monad]].<br />
<br />
The example code shows how the State monad can be used instead of explicitly passing state. The example uses the State monad to manage the random number generator state while building a compound data value requiring multiple calls to the random number generator.<br />
<br />
=== [[All_About_Monads#Example 16|Example 16]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The Reader monad|The Reader monad]].<br />
<br />
The example code shows how the Reader monad can be used to simplify computations involving a shared environment. The example uses the Reader monad to implement a simple template substitution system. The example code demonstrates the use of the Parsec monadic parser combinator library.<br />
<br />
=== [[All_About_Monads#Example 17|Example 17]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The Writer monad|The Writer monad]].<br />
<br />
The example code shows how the Writer monad can be used to implement logging. The example implements a very simple firewall simulator and uses the Writer monad to log the firewall activity.<br />
<br />
=== [[All_About_Monads#Example 18|Example 18]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#The Continuation monad|The Continuation monad]].<br />
<br />
The example code shows how the Continuation monad's escape continuations work. The example computes a complex transformation of a number.<br />
<br />
=== [[All_About_Monads#Example 19|Example 19]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Combining monads the hard way|Combining monads the hard way]].<br />
<br />
The example code shows how the Continuation monad can be nested within the IO monad given a suitable computational structure. The example is a slight modification of example 18.<br />
<br />
=== [[All_About_Monads#Example 20|Example 20]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Combining monads the hard way|Combining monads the hard way]].<br />
<br />
The example code shows how the Continuation monad and IO monad can be used simultaneously, but without using monad transformers. The example builds on examples 18 and 19.<br />
<br />
=== [[All_About_Monads#Example 21|Example 21]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Monad transformers|Monad transformers]].<br />
<br />
The example code shows how the transformer version of the Continuation monad can be used to create a combined monad for using continuations and doing I/O. The example builds on examples 18, 19 and 20.<br />
<br />
=== [[All_About_Monads#Example 22|Example 22]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Standard monad transformers|Standard monad transformers]].<br />
<br />
The example code shows how the transformer version of the Writer monad can be used to create a combined monad for logging and doing I/O. The example adds timestamps to the log entries of the firewall simulator from example 17.<br />
<br />
=== [[All_About_Monads#Example 23|Example 23]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Standard monad transformers|Standard monad transformers]].<br />
<br />
The example code shows how the transformer version of the Reader monad can be used to create a monad that combines a shared environment with I/O. The example converts the template system of example 16 to use files as templates.<br />
<br />
=== [[All_About_Monads#Example 24|Example 24]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Standard monad transformers|Standard monad transformers]].<br />
<br />
The example code uses the <code>StateT</code> transformer on the List monad to create a combined monad for doing non-deterministic stateful computations. The example uses the combined monad to solve a logic problem.<br />
<br />
=== [[All_About_Monads#Example 25|Example 25]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#An example with multiple transformers|An example with multiple monad transformers]].<br />
<br />
The example code uses the <code>StateT</code> and <code>WriterT</code> transformers on the List monad to create a combined monad for doing non-deterministic stateful computations with logging. The example uses the combined monad to solve the N-queens problem.<br />
<br />
=== [[All_About_Monads#Example 26|Example 26]] ===<br />
<br />
This example is discussed in the section: [[All_About_Monads#Heavy lifting|Heavy lifting]].<br />
<br />
The example code demonstrates the use of the <code>lift</code> function and the necessity of managing its use in complex transformer stacks.<br />
<br />
[[Category:Monad]]<br />
[[Category:Standard classes]]<br />
[[Category:Standard libraries]]<br />
[[Category:Standard packages]]<br />
[[Category:Standard types]]<br />
[[Category:Tutorials]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=63504A practical Template Haskell Tutorial2020-11-16T18:50:35Z<p>Henk-Jan van Tuyl: Removed reference error message</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><ref name="dep-tys"/><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ''Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD 'fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
{-# LANGUAGE QuasiQuotes #-}<br />
<br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE 'Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply 'Char [lift cs]<br />
lift (Alt r1 r2) = apply 'Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply 'Seq (map lift [r1, r2])<br />
lift (Star r1) = apply 'Star (map lift [r1])<br />
lift Empty = apply 'Empty []<br />
lift Void = apply 'Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation is often described as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if-conditionals, for-loops, and let-bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=PVP&diff=63503PVP2020-11-16T17:22:14Z<p>Henk-Jan van Tuyl: Solved double redirect</p>
<hr />
<div>#REDIRECT [[pvp:]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Library_versioning_policy&diff=63502Library versioning policy2020-11-16T17:20:38Z<p>Henk-Jan van Tuyl: Solved double redirect</p>
<hr />
<div>#redirect [[pvp:]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Raspberry_Pi&diff=63499Raspberry Pi2020-11-14T18:13:22Z<p>Henk-Jan van Tuyl: Removed the stub template.</p>
<hr />
<div><br />
== Introduction ==<br />
<br />
Raspberry Pi is an [[ARM]] based single-board computer, developed for educational purposes, costing USD 25. For more details, see [http://en.wikipedia.org/wiki/Raspberry_Pi the Wikipedia article about Raspberry Pi], or the [http://www.raspberrypi.org/faqs FAQ list].<br />
<br />
[[Image:Raspberry_Pi_Beta_Board.jpg]]<br />
<br />
== Links == <br />
<br />
* [https://www.haskell.org/ghc/blog/20200515-ghc-on-arm.html The state of GHC on ARM] blog of bgamari at 2020-05-15<br />
* [https://github.com/blitzcode/hue-dashboard/blob/master/README.md#raspberry-pi Steps to get Haskell software running on Raspberry Pi]<br />
<br />
* [https://github.com/ku-fpg/raspberry-pi/wiki/GHC-Cross-Compiler-for-Raspberry-Pi GHC Cross Compiler for Raspberry Pi]<br />
<br />
* [http://www.reddit.com/r/haskell/comments/u7cwv/some_observationsproblems_of_getting_haskellghc/ Some observations/problems of getting Haskell/GHC running on the Raspberry Pi] (Reddit)<br />
<br />
* [http://www.raspberrypi.org/ The official Raspberry Pi site]<br />
<br />
* [http://alenribic.com/posts/2012-08-06-running-haskell-on-raspberry-pi.html Running Haskell on Raspberry Pi] (blog)<br />
<br />
* [http://alenribic.com/posts/2012-08-17-raspberry-pi-in-a-haskell-cloud.html Raspberry Pi in a Haskell Cloud] (blog)<br />
<br />
* [http://www.mail-archive.com/haskell-cafe@haskell.org/msg99529.html Re: <nowiki>[Haskell-cafe]</nowiki> Haskell (GHC 7) on ARM]<br />
<br />
* [http://www.raspberrypi.org/phpBB3/viewtopic.php?f=34&t=6655 Haskell/GHC observations on the official Raspberry Pi forum]<br />
<br />
* [https://haskellembedded.github.io/posts/2015-12-15-arm.html Guide to Haskell ARM compilers, cross-compilers, and QEMU]<br />
<br />
* [https://gist.github.com/jamesthompson/7730209b2b154bd0a182e6fe945a2838 A script to install Stack on Raspbian]<br />
<br />
* [https://trandi.wordpress.com/2017/11/29/receipts-printer-photo-booth/ A post about using Haskell to control a thermal printer from a Raspberry Pi. Quickly goes through how Stack can now install all dependencies seamlessly, except the LLVM-3.7 Also nice basic example on processing images and using the Serial port.]<br />
<br />
== GHC Status ==<br />
<br />
Of the "official" images currently available from the [http://www.raspberrypi.org/downloads Raspberry Pi Downloads] page, the following versions of GHC are available<br />
<br />
* Arch Linux - 6.12.3-1<br />
* Debian Squeeze - [http://packages.debian.org/stable/haskell/ghc6 6.12.1-13]<br />
* Debian Wheezy - [http://packages.debian.org/wheezy/ghc 7.4.1-3]<br />
* Raspbian Jessie - 7.6.3-21+rpi1<br />
<br />
'''Note:''' GHCi does not work on ARM with older versions, but it has become available in GHC 7.8. See [http://www.haskell.org/pipermail/haskell-cafe/2013-December/111825.html this post on haskell-cafe] for the status as of December 2013. [https://stackoverflow.com/questions/29379706/ghci-on-raspberry-pi-2 Success with 7.8 on a Raspberry Pi 2.]<br />
<br />
There seemed to be a point where GHCi was [http://www.haskell.org/pipermail/haskell-cafe/2012-June/101704.html merged into version 7.4.2.], and it may still be possible to install it in an experimental manner, but it is not (currently) available in the Debian Raspberry Pi repository. [http://www.raspberrypi.org/phpBB3/viewtopic.php?f=34&t=6655 Here is a discussion thread wherein djhuk describes] compiling and installing GHC-7.4.2 via QEMU to the Raspberry Pi, with incomplete GHCi functionality.<br />
<br />
To build a cross-compiler from Linux to Raspberry Pi (running Raspbian), see the [https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/RaspberryPi GHC Trac].<br />
<br />
== Libraries ==<br />
<br />
* pi-lcd<br />
: This package allows using an Adafruit character LCD and keypad kit on a Raspberry Pi from Haskell.<br />
:: [https://hackage.haskell.org/package/pi-lcd The package on Hackage]<br />
:: [https://github.com/ppelleti/pi-lcd On GitHub]<br />
:: [https://mail.haskell.org/pipermail/haskell-cafe/2017-February/126310.html The announcement]<br />
<br />
* wiringPi <br />
: A Haskell binding to the wiringPi library, for using GPIO on the Raspberry Pi<br />
:: [https://hackage.haskell.org/package/wiringPi The package on Hackage]<br />
:: [https://github.com/ppelleti/hs-wiringPi On GitHub]<br />
:: [https://mail.haskell.org/pipermail/haskell-cafe/2017-January/125909.html The announcement]<br />
<br />
== Current Issues ==<br />
<br />
The main issue encountered so far is the memory limitations of the devices with 256 MB RAM; [[GHC]] will execute fine, but problems will start to arise when using [[cabal-install]] to install new libraries, especially ones with lots of dependencies. (Recent model B boards have 512 MB on board [http://www.raspberrypi.org/archives/2180], Raspberry Pi 2 Model B boards have 1GB on board.)<br />
<br />
Potential solutions to this problem have been suggested, including using [http://wiki.qemu.org/Main_Page QEMU] on a more powerful system and thus compiling your application there and copying the resulting binary across to your Raspberry Pi<br />
<br />
== Books ==<br />
* Heitz, Ryan [http://www.manning.com/heitz/ Hello Raspberry Pi!]. Manning Publications (2015). p.p. 225. ISBN 9781617292453<br />
<br />
== See also ==<br />
<br />
* [[Arduino]]<br />
<br />
* [[Robotics]]<br />
<br />
* [[ARM]]<br />
<br />
* [[iPhone]]<br />
<br />
<br />
[[Category:Platforms]]<br />
[[Category:Robotics]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Raspberry_Pi&diff=63498Raspberry Pi2020-11-14T18:08:50Z<p>Henk-Jan van Tuyl: /* Links */ Added "The state of GHC on ARM"</p>
<hr />
<div>{{Stub}}<br />
<br />
== Introduction ==<br />
<br />
Raspberry Pi is an [[ARM]] based single-board computer, developed for educational purposes, costing USD 25. For more details, see [http://en.wikipedia.org/wiki/Raspberry_Pi the Wikipedia article about Raspberry Pi], or the [http://www.raspberrypi.org/faqs FAQ list].<br />
<br />
[[Image:Raspberry_Pi_Beta_Board.jpg]]<br />
<br />
== Links == <br />
<br />
* [https://www.haskell.org/ghc/blog/20200515-ghc-on-arm.html The state of GHC on ARM] blog of bgamari at 2020-05-15<br />
* [https://github.com/blitzcode/hue-dashboard/blob/master/README.md#raspberry-pi Steps to get Haskell software running on Raspberry Pi]<br />
<br />
* [https://github.com/ku-fpg/raspberry-pi/wiki/GHC-Cross-Compiler-for-Raspberry-Pi GHC Cross Compiler for Raspberry Pi]<br />
<br />
* [http://www.reddit.com/r/haskell/comments/u7cwv/some_observationsproblems_of_getting_haskellghc/ Some observations/problems of getting Haskell/GHC running on the Raspberry Pi] (Reddit)<br />
<br />
* [http://www.raspberrypi.org/ The official Raspberry Pi site]<br />
<br />
* [http://alenribic.com/posts/2012-08-06-running-haskell-on-raspberry-pi.html Running Haskell on Raspberry Pi] (blog)<br />
<br />
* [http://alenribic.com/posts/2012-08-17-raspberry-pi-in-a-haskell-cloud.html Raspberry Pi in a Haskell Cloud] (blog)<br />
<br />
* [http://www.mail-archive.com/haskell-cafe@haskell.org/msg99529.html Re: <nowiki>[Haskell-cafe]</nowiki> Haskell (GHC 7) on ARM]<br />
<br />
* [http://www.raspberrypi.org/phpBB3/viewtopic.php?f=34&t=6655 Haskell/GHC observations on the official Raspberry Pi forum]<br />
<br />
* [https://haskellembedded.github.io/posts/2015-12-15-arm.html Guide to Haskell ARM compilers, cross-compilers, and QEMU]<br />
<br />
* [https://gist.github.com/jamesthompson/7730209b2b154bd0a182e6fe945a2838 A script to install Stack on Raspbian]<br />
<br />
* [https://trandi.wordpress.com/2017/11/29/receipts-printer-photo-booth/ A post about using Haskell to control a thermal printer from a Raspberry Pi. Quickly goes through how Stack can now install all dependencies seamlessly, except the LLVM-3.7 Also nice basic example on processing images and using the Serial port.]<br />
<br />
== GHC Status ==<br />
<br />
Of the "official" images currently available from the [http://www.raspberrypi.org/downloads Raspberry Pi Downloads] page, the following versions of GHC are available<br />
<br />
* Arch Linux - 6.12.3-1<br />
* Debian Squeeze - [http://packages.debian.org/stable/haskell/ghc6 6.12.1-13]<br />
* Debian Wheezy - [http://packages.debian.org/wheezy/ghc 7.4.1-3]<br />
* Raspbian Jessie - 7.6.3-21+rpi1<br />
<br />
'''Note:''' GHCi does not work on ARM with older versions, but it has become available in GHC 7.8. See [http://www.haskell.org/pipermail/haskell-cafe/2013-December/111825.html this post on haskell-cafe] for the status as of December 2013. [https://stackoverflow.com/questions/29379706/ghci-on-raspberry-pi-2 Success with 7.8 on a Raspberry Pi 2.]<br />
<br />
There seemed to be a point where GHCi was [http://www.haskell.org/pipermail/haskell-cafe/2012-June/101704.html merged into version 7.4.2.], and it may still be possible to install it in an experimental manner, but it is not (currently) available in the Debian Raspberry Pi repository. [http://www.raspberrypi.org/phpBB3/viewtopic.php?f=34&t=6655 Here is a discussion thread wherein djhuk describes] compiling and installing GHC-7.4.2 via QEMU to the Raspberry Pi, with incomplete GHCi functionality.<br />
<br />
To build a cross-compiler from Linux to Raspberry Pi (running Raspbian), see the [https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/RaspberryPi GHC Trac].<br />
<br />
== Libraries ==<br />
<br />
* pi-lcd<br />
: This package allows using an Adafruit character LCD and keypad kit on a Raspberry Pi from Haskell.<br />
:: [https://hackage.haskell.org/package/pi-lcd The package on Hackage]<br />
:: [https://github.com/ppelleti/pi-lcd On GitHub]<br />
:: [https://mail.haskell.org/pipermail/haskell-cafe/2017-February/126310.html The announcement]<br />
<br />
* wiringPi <br />
: A Haskell binding to the wiringPi library, for using GPIO on the Raspberry Pi<br />
:: [https://hackage.haskell.org/package/wiringPi The package on Hackage]<br />
:: [https://github.com/ppelleti/hs-wiringPi On GitHub]<br />
:: [https://mail.haskell.org/pipermail/haskell-cafe/2017-January/125909.html The announcement]<br />
<br />
== Current Issues ==<br />
<br />
The main issue encountered so far is the memory limitations of the devices with 256 MB RAM; [[GHC]] will execute fine, but problems will start to arise when using [[cabal-install]] to install new libraries, especially ones with lots of dependencies. (Recent model B boards have 512 MB on board [http://www.raspberrypi.org/archives/2180], Raspberry Pi 2 Model B boards have 1GB on board.)<br />
<br />
Potential solutions to this problem have been suggested, including using [http://wiki.qemu.org/Main_Page QEMU] on a more powerful system and thus compiling your application there and copying the resulting binary across to your Raspberry Pi<br />
<br />
== Books ==<br />
* Heitz, Ryan [http://www.manning.com/heitz/ Hello Raspberry Pi!]. Manning Publications (2015). p.p. 225. ISBN 9781617292453<br />
<br />
== See also ==<br />
<br />
* [[Arduino]]<br />
<br />
* [[Robotics]]<br />
<br />
* [[ARM]]<br />
<br />
* [[iPhone]]<br />
<br />
<br />
[[Category:Platforms]]<br />
[[Category:Robotics]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template:Main/Headlines&diff=63497Template:Main/Headlines2020-11-14T18:05:53Z<p>Henk-Jan van Tuyl: Added releases GHC 8.8.4 and 8.10.2</p>
<hr />
<div><div class="subtitle">Headlines</div><br />
* ''2020:''<br />
** The [https://haskell.foundation/ Haskell Foundation] is [https://www.youtube.com/watch?v=MEmRarBL9kw&t=330 announced] at the Haskell eXchange 2020<br />
** [https://www.haskell.org/ghc/blog/20200808-ghc-8.10.2-released.html GHC 8.10.2] is released<br />
** [https://www.haskell.org/ghc/blog/20200715-ghc-8.8.4-released.html GHC 8.8.4] is released<br />
** [https://www.haskell.org/ghc/blog/20200324-ghc-8.10.1-released.html GHC 8.10.1] is released<br />
** [https://www.haskell.org/ghc/blog/20200116-ghc-8.8.2-released.html GHC 8.8.2] is released<br />
<br />
* ''2019:''<br />
** [https://www.haskell.org/ghc/blog/20190825-ghc-8.8.1-released.html GHC 8.8.1] is released<br />
<br />
* ''2018:''<br />
** [http://web.archive.org/web/20181111185411/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.2-released GHC 8.6.2] is released<br />
** [http://web.archive.org/web/20181204181813/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.1-released GHC 8.6.1] is released<br />
** [https://www.haskell.org/ghc/download_ghc_8_4_3.html GHC 8.4.3] is released<br />
** The '''[https://www.haskell.org/platform/ Haskell Platform 8.4.3]''' is [https://mail.haskell.org/pipermail/haskell-cafe/2018-June/129256.html announced] and ready for [https://downloads.haskell.org/~platform/8.4.3/ download]<br />
<br />
* ''2017:''<br />
** [https://www.haskell.org/ghc/ GHC 8.2.1] is released<br />
** The [https://www.haskell.org/platform/ Haskell Platform 8.2.1] is released<br />
<br />
* ''2016:''<br />
** [https://www.haskell.org/ghc/ GHC 8.0.1] is released<br />
<br />
* ''2015:''<br />
** [http://www.haskell.org/ghc/ GHC 7.10.1] is released<br />
<br />
* ''2014:''<br />
** [http://www.haskell.org/ghc/ GHC 7.8.4] is released<br />
** The '''[http://www.haskell.org/platform/ Haskell Platform 2014.2]''' has been [http://www.haskell.org/pipermail/haskell/2014-August/024284.html released]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template:Main/Headlines&diff=63486Template:Main/Headlines2020-11-06T01:36:57Z<p>Henk-Jan van Tuyl: Added Haskell Foundation</p>
<hr />
<div><div class="subtitle">Headlines</div><br />
* ''2020:''<br />
** The [https://haskell.foundation/ Haskell Foundation] is [https://www.youtube.com/watch?v=MEmRarBL9kw&t=330 announced] at the Haskell eXchange 2020<br />
** [https://www.haskell.org/ghc/blog/20200324-ghc-8.10.1-released.html GHC 8.10.1] is released<br />
** [https://www.haskell.org/ghc/blog/20200116-ghc-8.8.2-released.html GHC 8.8.2] is released<br />
<br />
* ''2019:''<br />
** [https://www.haskell.org/ghc/blog/20190825-ghc-8.8.1-released.html GHC 8.8.1] is released<br />
<br />
* ''2018:''<br />
** [http://web.archive.org/web/20181111185411/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.2-released GHC 8.6.2] is released<br />
** [http://web.archive.org/web/20181204181813/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.1-released GHC 8.6.1] is released<br />
** [https://www.haskell.org/ghc/download_ghc_8_4_3.html GHC 8.4.3] is released<br />
** The '''[https://www.haskell.org/platform/ Haskell Platform 8.4.3]''' is [https://mail.haskell.org/pipermail/haskell-cafe/2018-June/129256.html announced] and ready for [https://downloads.haskell.org/~platform/8.4.3/ download]<br />
<br />
* ''2017:''<br />
** [https://www.haskell.org/ghc/ GHC 8.2.1] is released<br />
** The [https://www.haskell.org/platform/ Haskell Platform 8.2.1] is released<br />
<br />
* ''2016:''<br />
** [https://www.haskell.org/ghc/ GHC 8.0.1] is released<br />
<br />
* ''2015:''<br />
** [http://www.haskell.org/ghc/ GHC 7.10.1] is released<br />
<br />
* ''2014:''<br />
** [http://www.haskell.org/ghc/ GHC 7.8.4] is released<br />
** The '''[http://www.haskell.org/platform/ Haskell Platform 2014.2]''' has been [http://www.haskell.org/pipermail/haskell/2014-August/024284.html released]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Benchmarks_Game&diff=63379Benchmarks Game2020-07-24T13:38:20Z<p>Henk-Jan van Tuyl: Removed obsolete message about website change</p>
<hr />
<div>This is for entries to [https://salsa.debian.org/benchmarksgame-team/benchmarksgame The Computer Language Benchmarks Game] (Formerly known as The Great Language Shootout). You can see [https://salsa.debian.org/benchmarksgame-team/benchmarksgame/tree/master/public/data the current results as data files].<br />
<br />
[[Image:Chartvs.png|center|frame|Haskell entries compared to C on the quad core, Feb 2009]]<br />
<br />
== Parallel implementations ==<br />
New implementations written for parallelism. You should almost certainly<br />
be working on these only:<br />
<br />
* [[/Parallel]]<br />
<br />
== Submitting guide ==<br />
<br />
Now that GHC 8.8.1 is installed on the Benchmarks Game servers, please make full use of it! There is an immediate need for a complete revamp of all the entries to fix and optimise them for this version of GHC. Please pick a program and contribute!<br />
<br />
GHC change information since version 8.0.1 can be found on the [https://www.haskell.org/ghc/blog.html GHC Developer Blog]<br />
<br />
GHC 6.10 gave us the option of<br />
* parallel garbage collector<br />
<br />
GHC 6.8 gave us the option of <br />
* `par`<br />
* SMP runtime<br />
* new regex libs<br />
* lots of other stuff<br />
<br />
GHC 6.6 gave the option of using:<br />
* [https://hackage.haskell.org/package/bytestring/docs/Data-ByteString.html Data.ByteString]<br />
* [https://hackage.haskell.org/package/regex-posix/docs/Text-Regex-Posix-ByteString-Lazy.html Text.Regex.*]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#bang-patterns-and-strict-haskell bang patterns]<br />
which should greatly improve clarity and brevity. Line count is not<br />
significant now (code is gzipped to determine size), so aim for maximum<br />
clarity.<br />
<br />
Suggested best practices for submitting an entry to the Benchmarks Game include:<br />
<br />
* Posting the proposed code to the community to allow for a best of breed entry. Proposed code is here on the wiki and often in the Haskell-cafe mailing list. This has already helped improve the submitted code.<br />
<br />
* Provide complete performance measurements against the current best entry.<br />
<br />
* Creating clean, functional-style code or fast, imperative-style code. There are multiple versions ("GHC", "GHC#2", "GHC#3", "GHC#4") of GHC codes on many of the benchmarks with no clear rational for the different versions. It'd be better to have entries for "GHC" be clean, short, functional code and entries for "GHC-#2" be fastest, probably-ugliest code.<br />
<br />
* When you submit via the trac system, record in the wiki section for that entry a link to the submission.<br />
<br />
* Check for gzip file size before you submit -- lots of points to be had there.<br />
<br />
* Try different compile options and the other ideas on the [[Performance/GHC]] page.<br />
<br />
<haskell><br />
--<br />
-- The Computer Language Benchmarks Game, https://benchmarksgame-team.pages.debian.net/benchmarksgame/<br />
-- Haskell Benchmarks Game entries, https://wiki.haskell.org/Benchmarks_Game<br />
-- <br />
-- Simon Marlow<br />
-- Shortened by Don Stewart<br />
--<br />
</haskell><br />
<br />
== Results ==<br />
<br />
Results for all benchmarks: [https://salsa.debian.org/benchmarksgame-team/benchmarksgame/tree/master/public/data]<br />
<br />
== Todo ==<br />
<br />
The current benchmarks can highlight weak spots in libraries and<br />
compilers that need improving. Some things noticed included:<br />
<br />
* hashtable performance is poor. A simple binding to a basic C hashtable would be very useful<br />
* it would be nice to have tre regexes in the core libs (instead of POSIX ones)<br />
<br />
''Why tre regexes? The libtre code is buggy, though if the shootout avoids the bugs then I guess one might want to use it. Would libpcre be a better choice?''--[[User:ChrisKuklewicz|ChrisKuklewicz]] 00:21, 24 February 2009 (UTC)<br />
<br />
<br />
== Obsolete benchmarks ==<br />
<br />
* [[Shootout/Takfp | Takfp]]<br />
<br />
* [[Shootout/Ack | Ack]] <br />
<br />
* [[Shootout/Harmonic | Harmonic]]<br />
<br />
* [[Shootout/Healthcare | Healthcare]]<br />
<br />
* [[Shootout/Nsieve | N-sieve]]<br />
<br />
* [[Shootout/Nsieve Bits | N-sieve Bits]]<br />
<br />
* [[Shootout/Partial sums | Partial sums]]<br />
<br />
* [[Shootout/Cheap concurrency | Cheap concurrency]]<br />
<br />
* [[Shootout/Chameneos | Chameneos]]<br />
<br />
* [[Shootout/Random | Random]]<br />
<br />
* [[Shootout/Recursive | Recursive]]<br />
<br />
* [[Shootout/SumFile | SumFile]]<br />
<br />
<br />
[[Category:Contests]]<br />
[[Category:Code]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Humor&diff=63286Humor2020-04-19T14:48:46Z<p>Henk-Jan van Tuyl: Added "Red Riding Hood Teaches Programming"</p>
<hr />
<div>Who says functional programmers never have any fun? Here's some of the<br />
hoaxes and other funny stuff from several sources.<br />
<br />
* [http://www.youtube.com/watch?v=Ci48kqp11F8 Ranjit Jhala performs Lambda Style!]<br />
* [http://ro-che.info/ccc/01.html Cartesian Closed Comic]<br />
*[[Let's_Play_Free_Games]]<br />
*[[Music of monads]]<br />
*[http://www.xent.com/pipermail/fork/Week-of-Mon-20070219/044101.html If Haskell were a working girl]<br />
*[[Humor/Microsoft|Microsoft takes over Haskell]]<br />
*[http://www.willamette.edu/~fruehr/haskell/evolution.html The Evolution of a Haskell Programmer] (can you write a factorial function?) <br />
*[[Humor/Haskell saves lives|Haskell saves lives!]]<br />
*[[Humor/Poem|An ode to Haskell]]<br />
*[[Humor/Flakes|Try some Haskell today!]]<br />
*[[Humor/Porn|Functional porn]]<br />
*[http://www.willamette.edu/~fruehr/haskell/seuss.html Dr. Seuss builds a parser]<br />
*[[Humor/Limericks|Limericks]]<br />
*[[Humor/Hugme|The latest Hugs release?]]<br />
*[[Humor/Enron|Haskell fingers Enron]]<br />
*[[Humor/1984|Haskells 1984 parallelisms]]<br />
*[[Humor/irish_joke|How to keep an imperative programmer busy for hours]]<br />
*[[Humor/How quick can you write a ISI paper with Haskell or without it ?]]<br />
*[[Humor/Urgent|URGENT ASSISTANCE NEEDED!]]<br />
*[[Humor/Homework|Need help with your homework?]]<br />
*[[Humor/Y-agra|Need help performing?]]<br />
*[[Humor/Slow|Haskell is slow!]]<br />
*[[Humor/Wanda|Wanda the fish is speaking]]<br />
*[http://www.newadvent.org/cathen/10447b.htm Monads explained by the Catholic Church]<br />
*[http://marc.info/?l=haskell&m=66622004421268 Committee Advocating The Superstitious Use of Parentheses]<br />
*[http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg00159.html The Beta Release of Glasgow Haskell] (and [http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg00191.html explanation])<br />
*[http://www.dcs.gla.ac.uk/~partain/haskerl/partain-1.html The Haskerl Extension to Haskell]<br />
* HaskellWiki's [http://www.haskell.org/haskellwiki/QuotesPage QuotesPage]. E.g. a quotation from <nowiki><autrijus></nowiki>:<br />
** Perl: "Easy things are easy, hard things are possible"<br />
** Haskell: "Hard things are easy, the impossible just happened"<br />
* [[Lambdabot|Lambdabot's]] [http://www.cse.unsw.edu.au/~dons/code/lambdabot/State/quote quotes archive].<br />
* [[HaskellCosmetics|Haskell cosmetics]], pure and good for you<br />
* [http://archive.fo/seKtU Haskell No Operation]<br />
* [[Almost Haskell]]<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2006-November/019190.html There's a monster in my Haskell!] <br />
* [http://nssdc.gsfc.nasa.gov/image/planetary/jupiter/io.jpg What does IO look like?], or how why threading the real world is tricky.<br />
*[[Humor/Erlkönig|King IO (freely adapted from Goethe)]]<br />
*[http://koweycode.blogspot.com/2007/01/think-of-monad.html Think of a monad ... ]<br />
* [http://www.haskell.org.MonadTransformer.parallelnetz.de/haskellwiki/Category:Monad The warm, fuzzy thing transformer]<br />
* The [[Humor/LearningCurve|Haskell Learning Curve]]<br />
* [http://spl.smugmug.com/gallery/13227630_j2MHcg/#!i=960526161&k=XwKHSBM Lambdacats], inspired by the [http://en.wikipedia.org/wiki/Lolcat lolcat phenomenon].<br />
*[[Humor/Dialogs|The benefits of Haskell, via the Socratic method]]<br />
*[[Humor/Goldilocks|Goldilocks]]<br />
*[[Humor/Hackage Theme Song|Hackage Theme Song]]<br />
*[[Shooting your self in the foot]]<br />
*[[Haiku]]<br />
*[http://blog.plover.com/prog/burritos.html Monads are like burritos]<br />
*[https://toggl.com/blog/little-red-riding-hood-teaches-programming-comic Little Red Riding Hood Teaches Programming ] [Comic]<br />
*More Haskell humor at [http://www.reddit.com/r/ProgrammerHumor/search?q=haskell&restrict_sr=on reddit.com]<br />
<br />
[[Category:Humor|*]]<br />
[[Category:Community]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Benchmarks_Game/Parallel/BinaryTrees&diff=63285Benchmarks Game/Parallel/BinaryTrees2020-04-18T23:27:39Z<p>Henk-Jan van Tuyl: </p>
<hr />
<div>== Binary Trees ==<br />
<br />
Description of the benchmark: https://benchmarksgame-team.pages.debian.net/benchmarksgame/description/binarytrees.html#binarytrees<br />
<br />
Haskell entries: https://benchmarksgame-team.pages.debian.net/benchmarksgame/measurements/ghc.html<br />
<br />
'''*The following text may be outdated*'''<br />
<br />
<br />
=== 2009-03-01: Current Entry ===<br />
<br />
Submitted: http://alioth.debian.org/tracker/index.php?func=detail&aid=311523&group_id=30402&atid=411646<br />
<br />
Also filed a bug ticket with GHC to find out if the GC growth strategy can be improved (so that -H240M isn't required): http://hackage.haskell.org/trac/ghc/ticket/3061<br />
<br />
<haskell><br />
{-# OPTIONS -funbox-strict-fields #-}<br />
{-# LANGUAGE BangPatterns #-}<br />
--<br />
-- The Computer Language Benchmarks Game<br />
-- http://shootout.alioth.debian.org/<br />
--<br />
-- Contributed by Don Stewart<br />
-- Modified by Stephen Blackheath to parallelize (a very tiny tweak)<br />
--<br />
-- Compile with:<br />
--<br />
-- > ghc -O2 -fasm -threaded --make <br />
--<br />
-- Run with:<br />
--<br />
-- > ./A +RTS -N4 -H300M -RTS 20<br />
-- <br />
-- Where '4' is the number of cores. and "set your -H value high (3 or<br />
-- more times the maximum residency)", as per GHC User's Guide:<br />
--<br />
-- <http://haskell.org/ghc/docs/6.10.1/html/users_guide/runtime-control.html#rts-options-gc><br />
--<br />
-- -H "provides a “suggested heap size” for the garbage collector. The<br />
-- garbage collector will use about this much memory until the program<br />
-- residency grows and the heap size needs to be expanded to retain<br />
-- reasonable performance."<br />
--<br />
<br />
import System<br />
import Data.Bits<br />
import Text.Printf<br />
import Control.Parallel.Strategies<br />
<br />
--<br />
-- an artificially strict tree.<br />
--<br />
-- normally you would ensure the branches are lazy, but this benchmark<br />
-- requires strict allocation.<br />
--<br />
data Tree = Nil | Node !Int !Tree !Tree<br />
<br />
minN = 4<br />
<br />
io s n t = printf "%s of depth %d\t check: %d\n" s n t<br />
<br />
main = do<br />
n <- getArgs >>= readIO . head<br />
let maxN = max (minN + 2) n<br />
stretchN = maxN + 1<br />
<br />
-- stretch memory tree<br />
let c = check (make 0 stretchN)<br />
io "stretch tree" stretchN c<br />
<br />
-- allocate a long lived tree<br />
let !long = make 0 maxN<br />
<br />
-- allocate, walk, and deallocate many bottom-up binary trees<br />
let vs = parMap rnf id $ depth minN maxN<br />
mapM_ (\((m,d,i)) -> io (show m ++ "\t trees") d i) vs<br />
<br />
-- confirm the the long-lived binary tree still exists<br />
io "long lived tree" maxN (check long)<br />
<br />
-- generate many trees<br />
depth :: Int -> Int -> [(Int,Int,Int)]<br />
depth d m<br />
| d <= m = (2*n,d,sumT d n 0) : depth (d+2) m<br />
| otherwise = []<br />
where n = 1 `shiftL` (m - d + minN)<br />
<br />
-- allocate and check lots of trees<br />
sumT :: Int -> Int -> Int -> Int<br />
sumT d 0 t = t<br />
sumT d i t = sumT d (i-1) (t + a + b)<br />
where a = check (make i d)<br />
b = check (make (-i) d)<br />
<br />
-- traverse the tree, counting up the nodes<br />
check :: Tree -> Int<br />
check Nil = 0<br />
check (Node i l r) = i + check l - check r<br />
<br />
-- build a tree<br />
make :: Int -> Int -> Tree<br />
make i 0 = Node i Nil Nil<br />
make i d = Node i (make (i2-1) d2) (make i2 d2)<br />
where i2 = 2*i; d2 = d-1<br />
<br />
</haskell><br />
<br />
=== Parallel Strategies: parMap ===<br />
<br />
* Status: submitted.<br />
<br />
Flags:<br />
<br />
$ ghc -O2 --make -fasm -threaded Parallel.hs<br />
$ ./Parallel 20 +RTS -N5 -A350M<br />
<br />
This is a version of the Haskell GHC binary-trees benchmark, annotated for parallelism, using parallel strategy combinators.<br />
When compiled with the -threaded flag, and run with +RTS -N5 -RTS, it will exploit all cores on the quad-core machine,<br />
dramatically reducing running times.<br />
<br />
On my quad core, running time goes from, <br />
<br />
* single core, 26.997s<br />
* quad core, 5.692s<br />
<br />
The following flags should be used:<br />
<br />
Compile time:<br />
<br />
ghc -O2 -fasm --make Parallel2.hs -threaded<br />
<br />
Runtime:<br />
<br />
./Parallel2 20 +RTS -N5 -A350M -RTS<br />
<br />
The -N5 flag asks the Haskell runtime to use 5 capabilites, which map onto the underlying cores.<br />
<br />
Here is the result on my quad core,<br />
<br />
$ time ./Parallel2 20 +RTS -N5 -A350M -RTS<br />
stretch tree of depth 21 check: -1<br />
2097152 trees of depth 4 check: -2097152<br />
524288 trees of depth 6 check: -524288<br />
131072 trees of depth 8 check: -131072<br />
32768 trees of depth 10 check: -32768<br />
8192 trees of depth 12 check: -8192<br />
2048 trees of depth 14 check: -2048<br />
512 trees of depth 16 check: -512<br />
128 trees of depth 18 check: -128<br />
32 trees of depth 20 check: -32<br />
long lived tree of depth 20 check: -1<br />
./Parallel2 20 +RTS -N5 -A350M -RTS 15.80s user 1.52s system 304% cpu 5.692 total<br />
<br />
Which is a satisfying result, as the parallelisation strategy is super simple.<br />
<br />
<br />
Code:<br />
<br />
<haskell><br />
<br />
{-# OPTIONS -fbang-patterns -funbox-strict-fields #-}<br />
--<br />
-- The Computer Language Shootout<br />
-- http://shootout.alioth.debian.org/<br />
--<br />
-- Contributed by Don Stewart and Thomas Davie<br />
--<br />
-- This implementation uses a parallel strategy to exploit the quad core machine.<br />
-- For more information about Haskell parallel strategies, see,<br />
--<br />
-- http://www.macs.hw.ac.uk/~dsg/gph/papers/html/Strategies/strategies.html<br />
--<br />
<br />
import System<br />
import Data.Bits<br />
import Text.Printf<br />
import Control.Parallel.Strategies<br />
import Control.Parallel<br />
<br />
--<br />
-- an artificially strict tree.<br />
--<br />
-- normally you would ensure the branches are lazy, but this benchmark<br />
-- requires strict allocation.<br />
--<br />
data Tree = Nil | Node !Int !Tree !Tree<br />
<br />
minN = 4<br />
<br />
io s n t = printf "%s of depth %d\t check: %d\n" s n t<br />
<br />
main = do<br />
n <- getArgs >>= readIO . head<br />
let maxN = max (minN + 2) n<br />
stretchN = maxN + 1<br />
<br />
-- stretch memory tree<br />
let c = check (make 0 stretchN)<br />
io "stretch tree" stretchN c<br />
<br />
-- allocate a long lived tree<br />
let !long = make 0 maxN<br />
<br />
-- allocate, walk, and deallocate many bottom-up binary trees<br />
let vs = (parMap rnf) (depth' maxN) [minN,minN+2..maxN]<br />
mapM_ (\((m,d,i)) -> io (show m ++ "\t trees") d i) vs<br />
<br />
-- confirm the the long-lived binary tree still exists<br />
io "long lived tree" maxN (check long)<br />
<br />
-- generate many trees<br />
depth' :: Int -> Int -> (Int,Int,Int)<br />
depth' m d =<br />
(2*n,d,sumT d n 0)<br />
where<br />
n = 1 `shiftL` (m - d + minN)<br />
<br />
-- allocate and check lots of trees<br />
sumT :: Int -> Int -> Int -> Int<br />
sumT d 0 t = t<br />
sumT d i t = sumT d (i-1) (t + a + b)<br />
where a = check (make i d)<br />
b = check (make (-i) d)<br />
<br />
-- traverse the tree, counting up the nodes<br />
check :: Tree -> Int<br />
check Nil = 0<br />
check (Node i l r) = i + check l - check r<br />
<br />
-- build a tree<br />
make :: Int -> Int -> Tree<br />
make i 0 = Node i Nil Nil<br />
make i d = Node i (make (i2-1) d2) (make i2 d2)<br />
where i2 = 2*i; d2 = d-1<br />
<br />
</haskell></div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Benchmarks_Game&diff=63284Benchmarks Game2020-04-18T23:13:09Z<p>Henk-Jan van Tuyl: /* Submitting guide */ Updated links and GHC version</p>
<hr />
<div>This is for entries to [https://salsa.debian.org/benchmarksgame-team/benchmarksgame The Computer Language Benchmarks Game] (Formerly known as The Great Language Shootout). You can see [https://salsa.debian.org/benchmarksgame-team/benchmarksgame/tree/master/public/data the current results as data files].<br />
<br />
The old site was closed at 2018-05-01, the new site is not fully functional yet (at 2018-05-17), see the <br />
[https://www.reddit.com/r/programming/comments/88jg07/the_computer_language_benchmarks_games/ announcement].<br />
<br />
[[Image:Chartvs.png|center|frame|Haskell entries compared to C on the quad core, Feb 2009]]<br />
<br />
== Parallel implementations ==<br />
New implementations written for parallelism. You should almost certainly<br />
be working on these only:<br />
<br />
* [[/Parallel]]<br />
<br />
== Submitting guide ==<br />
<br />
Now that GHC 8.8.1 is installed on the Benchmarks Game servers, please make full use of it! There is an immediate need for a complete revamp of all the entries to fix and optimise them for this version of GHC. Please pick a program and contribute!<br />
<br />
GHC change information since version 8.0.1 can be found on the [https://www.haskell.org/ghc/blog.html GHC Developer Blog]<br />
<br />
GHC 6.10 gave us the option of<br />
* parallel garbage collector<br />
<br />
GHC 6.8 gave us the option of <br />
* `par`<br />
* SMP runtime<br />
* new regex libs<br />
* lots of other stuff<br />
<br />
GHC 6.6 gave the option of using:<br />
* [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-ByteString.html Data.ByteString]<br />
* [http://www.haskell.org/ghc/docs/latest/html/libraries/regex-posix/Text-Regex-Posix-ByteString.html Text.Regex.*]<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html bang patterns]<br />
which should greatly improve clarity and brevity. Line count is not<br />
significant now (code is gzipped to determine size), so aim for maximum<br />
clarity.<br />
<br />
Suggested best practices for submitting an entry to the Benchmarks Game include:<br />
<br />
* Posting the proposed code to the community to allow for a best of breed entry. Proposed code is here on the wiki and often in the Haskell-cafe mailing list. This has already helped improve the submitted code.<br />
<br />
* Provide complete performance measurements against the current best entry.<br />
<br />
* Creating clean, functional-style code or fast, imperative-style code. There are multiple versions ("GHC", "GHC#2", "GHC#3", "GHC#4") of GHC codes on many of the benchmarks with no clear rational for the different versions. It'd be better to have entries for "GHC" be clean, short, functional code and entries for "GHC-#2" be fastest, probably-ugliest code.<br />
<br />
* When you submit via the trac system, record in the wiki section for that entry a link to the submission.<br />
<br />
* Check for gzip file size before you submit -- lots of points to be had there.<br />
<br />
* Try different compile options and the other ideas on the [[Performance/GHC]] page.<br />
<br />
<haskell><br />
--<br />
-- The Computer Language Benchmarks Game, https://benchmarksgame-team.pages.debian.net/benchmarksgame/<br />
-- Haskell Benchmarks Game entries, https://wiki.haskell.org/Benchmarks_Game<br />
-- <br />
-- Simon Marlow<br />
-- Shortened by Don Stewart<br />
--<br />
</haskell><br />
<br />
== Results ==<br />
<br />
Results for all benchmarks: [https://salsa.debian.org/benchmarksgame-team/benchmarksgame/tree/master/public/data]<br />
<br />
== Todo ==<br />
<br />
The current benchmarks can highlight weak spots in libraries and<br />
compilers that need improving. Some things noticed included:<br />
<br />
* hashtable performance is poor. A simple binding to a basic C hashtable would be very useful<br />
* it would be nice to have tre regexes in the core libs (instead of POSIX ones)<br />
<br />
''Why tre regexes? The libtre code is buggy, though if the shootout avoids the bugs then I guess one might want to use it. Would libpcre be a better choice?''--[[User:ChrisKuklewicz|ChrisKuklewicz]] 00:21, 24 February 2009 (UTC)<br />
<br />
<br />
== Obsolete benchmarks ==<br />
<br />
* [[Shootout/Takfp | Takfp]]<br />
<br />
* [[Shootout/Ack | Ack]] <br />
<br />
* [[Shootout/Harmonic | Harmonic]]<br />
<br />
* [[Shootout/Healthcare | Healthcare]]<br />
<br />
* [[Shootout/Nsieve | N-sieve]]<br />
<br />
* [[Shootout/Nsieve Bits | N-sieve Bits]]<br />
<br />
* [[Shootout/Partial sums | Partial sums]]<br />
<br />
* [[Shootout/Cheap concurrency | Cheap concurrency]]<br />
<br />
* [[Shootout/Chameneos | Chameneos]]<br />
<br />
* [[Shootout/Random | Random]]<br />
<br />
* [[Shootout/Recursive | Recursive]]<br />
<br />
* [[Shootout/SumFile | SumFile]]<br />
<br />
<br />
[[Category:Contests]]<br />
[[Category:Code]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template:Main/Headlines&diff=63283Template:Main/Headlines2020-04-18T21:01:46Z<p>Henk-Jan van Tuyl: Added "GHC 8.10.1 is released"</p>
<hr />
<div><div class="subtitle">Headlines</div><br />
* ''2020:''<br />
** [https://www.haskell.org/ghc/blog/20200324-ghc-8.10.1-released.html GHC 8.10.1] is released<br />
** [https://www.haskell.org/ghc/blog/20200116-ghc-8.8.2-released.html GHC 8.8.2] is released<br />
<br />
* ''2019:''<br />
** [https://www.haskell.org/ghc/blog/20190825-ghc-8.8.1-released.html GHC 8.8.1] is released<br />
<br />
* ''2018:''<br />
** [http://web.archive.org/web/20181111185411/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.2-released GHC 8.6.2] is released<br />
** [http://web.archive.org/web/20181204181813/https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.1-released GHC 8.6.1] is released<br />
** [https://www.haskell.org/ghc/download_ghc_8_4_3.html GHC 8.4.3] is released<br />
** The '''[https://www.haskell.org/platform/ Haskell Platform 8.4.3]''' is [https://mail.haskell.org/pipermail/haskell-cafe/2018-June/129256.html announced] and ready for [https://downloads.haskell.org/~platform/8.4.3/ download]<br />
<br />
* ''2017:''<br />
** [https://www.haskell.org/ghc/ GHC 8.2.1] is released<br />
** The [https://www.haskell.org/platform/ Haskell Platform 8.2.1] is released<br />
<br />
* ''2016:''<br />
** [https://www.haskell.org/ghc/ GHC 8.0.1] is released<br />
<br />
* ''2015:''<br />
** [http://www.haskell.org/ghc/ GHC 7.10.1] is released<br />
<br />
* ''2014:''<br />
** [http://www.haskell.org/ghc/ GHC 7.8.4] is released<br />
** The '''[http://www.haskell.org/platform/ Haskell Platform 2014.2]''' has been [http://www.haskell.org/pipermail/haskell/2014-August/024284.html released]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=WxHaskell/Windows&diff=63159WxHaskell/Windows2019-12-13T13:51:44Z<p>Henk-Jan van Tuyl: Changed GCC version</p>
<hr />
<div>== wxWidgets 3.0 and wxHaskell >= 0.92 ==<br />
<br />
=== Installing the easy way ===<br />
<br />
The easiest way to install wxHaskell on Windows, is to use a wxInstall package. wxInstall Achelanne contains wxWidgets 3.0, compiled with GCC 5.2.0, the necessary DLLs, and an installation script to install wxHaskell. It is available in 32 bit and in 64 bit and can be used for GHC 7.10.3 and later.<br />
<br />
wxInstall Abriline installs wxWidgets 3.0 together with the latest wxHaskell packages from Hackage and is available for 32 bit GHC, using GCC 4.5.2 and for 64 bit GHC using GCC 4.6.3; this means Abriline can be used (amongst others) for Haskell Platforms 2013.2.0.0, 2014.2.0.0 and 7.10.2, and MinGHC 7.10.1. The Haskell packages are installed locally.<br />
<br />
Installation instructions:<br />
<br />
* If the most recent wxHaskell packages are already installed, unregister them first (with <code>ghc-pkg unregister &lt;package name&gt;</code>).<br />
<br />
* Download one of the [http://sourceforge.net/projects/wxhaskell/files/wxInstall/ installation packages] and unzip it to its destination directory. <br />
<br />
* Click on Install.bat; the wxHaskell packages will be installed.<br />
<br />
* Adjust your search path as advised by Install.bat<br />
<br />
<br />
To test wxHaskell, install [[wxAsteroids]] with:<br />
<code><br />
cabal install wxAsteroids<br />
</code><br />
and run it with command <code>wxAsteroids</code> (the directory %APPDATA%\cabal\bin must be in your search path).<br />
<br />
You can update to a newer version of wxHaskell by running Install.bat <br />
again; for a newer version of wxWidgets, a new configuration of this package is needed.<br />
<br />
=== Installing the hard way ===<br />
<br />
'''This is something you do if there is no installation package available for your configuration, or you want to modify wxHaskell.'''<br />
<br />
wxHaskell binds to wxWidgets, so wxWidgets must be installed first.<br />
We will install wxWidgets with the GCC that is packaged with GHC, to prevent incompatibilities between object/archive files.<br />
<br><br />
You need mingw32-make.exe from [http://www.mingw.org/ MinGW] and sh.exe from [http://sourceforge.net/projects/mingw/files/MSYS/ MSYS] in your search path (look for sh.exe in your GHC directory tree). If you do not have it yet, install [http://git-scm.com/ GIT]. <br />
Download [https://sourceforge.net/projects/wxhaskell/files/wx-config-win/ wx-config.exe] (a new version for wxWidgets > 3.0) and copy it somewhere into your search path. It is also possible to download [https://github.com/wxHaskell/wxHaskell/tree/master/wx-config-win/wx-config-win the source for wx-config from the official wxHaskell repository]; compile it with<br />
c++ wx-config.cpp -o wx-config<br />
The C++ compiler comes with GHC.<br />
<br />
==== Installing wxWidgets ====<br />
<br />
Install the [http://wxwidgets.org/ wxWidgets source] in C:\Libs\wxWidgets\3.1.1<br />
<br><br />
Commands to compile wxWidgets and wxHaskell with Haskell Platform 2014.2.0.0 and later:<br />
<pre><br />
Set WXWIDGETS_VERSION=3.1.1<br />
Set WXWIN=C:\Libs\wxWidgets\%WXWIDGETS_VERSION%<br />
Cd %WXWIN%\build\msw<br />
</pre><br />
Edit config.gcc so that the following values are set: <br />
<pre><br />
SHARED ?= 1<br />
BUILD ?= release<br />
</pre><br />
If you are using GCC 5.2.0 or later (included with GHC 7.10.3 and later), change CXXFLAGS as well:<br />
<pre><br />
CXXFLAGS ?= -std=gnu++11 -Wno-deprecated-declarations<br />
</pre><br />
(Without -Wno-deprecated-declarations, you will get a huge amount of useless 'deprecated' messages.)<br />
If you want to compile 64 bit binaries, set the following as well<br />
(64 bit compilation requires GCC > 4.6, which comes with GHC > 7.10):<br />
<pre><br />
# Standard flags for CC <br />
CFLAGS ?= -m64<br />
<br />
# Standard flags for C++ <br />
CXXFLAGS ?= -m64 -std=gnu++11 -Wno-deprecated-declarations<br />
<br />
# Standard preprocessor flags (common for CC and CXX) <br />
CPPFLAGS ?= -D_M_AMD64<br />
</pre><br />
<br />
Edit ..\..\include\wx\msw\setup.h, change line 788 (may differ in later versions of wxWidgets, look for the #define for none-_MSC_VER compilers) from<br />
<pre><br />
# define wxUSE_GRAPHICS_CONTEXT 0<br />
</pre><br />
to<br />
<pre><br />
# define wxUSE_GRAPHICS_CONTEXT 1<br />
</pre><br />
<br><br />
Set the environment variables<br />
<br />
* for Haskell Platform 2014.2.0.0:<br />
<pre><br />
Set HASKELL_COMPILER_DIR=C:\Program Files\Haskell Platform\2014.2.0.0<br />
Set PATH=%HASKELL_COMPILER_DIR%\mingw\libexec\gcc\mingw32\4.5.2\;%HASKELL_COMPILER_DIR%\lib\extralibs\bin;%HASKELL_COMPILER_DIR%\bin;%HASKELL_COMPILER_DIR%\mingw\bin;%path%<br />
Set LIBRARY_PATH=%HASKELL_COMPILER_DIR%\mingw\lib;%HASKELL_COMPILER_DIR%\mingw\lib\gcc\mingw32\4.5.2;%LIBRARY_PATH%<br />
</pre><br />
<br />
* for Haskell Platform 7.10.2-a:<br />
<pre><br />
Set HASKELL_COMPILER_DIR=C:\Program Files\Haskell Platform\7.10.2-a<br />
Set Path=%HASKELL_COMPILER_DIR%\lib\extralibs\bin;%HASKELL_COMPILER_DIR%\bin;%HASKELL_COMPILER_DIR%\mingw\bin;%path%<br />
Set LIBRARY_PATH=%WXWIN%\lib\gcc_lib;%HASKELL_COMPILER_DIR%\mingw\lib;%LIBRARY_PATH%<br />
</pre><br />
Clean and build wxWidgets, using the MinGW shell:<br />
<pre><br />
sh -c "mingw32-make -f makefile.gcc clean"<br />
sh -c "mingw32-make -f makefile.gcc all"<br />
</pre><br />
There will be many linker warnings for old versions of GCC, those are solved in a more recent GCC version.<br />
The result is now in %WXWIN%\lib\gcc_dll<br />
<br />
If you get a message like<br />
<pre><br />
'c:/Program' is not recognized as an internal or external command,<br />
</pre><br />
there is probably a space in the path to an executable. It is better to <br />
install the Haskel Platform in a directory without spaces in the full <br />
name, but there is another solution: use the old fashioned short names, like:<br />
<pre><br />
Set HASKELL_COMPILER_DIR=C:\PROGRA~1\HASKEL~1\7.10.2-a<br />
</pre><br />
(Use the MS-DOS command <code>For %i In (ghc.exe) Do Echo %~sdp$PATH:i</code> to see the path to GHC with short names)<br />
<br><br />
<br />
If you get a message about denied access: if you already compiled and <br />
ran a wxHaskell program, the wxWidgets DLLs are loaded and cannot be <br />
overwritten. Restart the computer.<br />
<br />
==== Installing wxHaskell ====<br />
<br />
Using the environment variables HASKELL_COMPILER_DIR and WXWIN from the previous subsection:<br />
<pre><br />
Set WXCFG=gcc_dll\mswu<br />
Set CPLUS_INCLUDE_PATH=%HASKELL_COMPILER_DIR%\mingw\lib\gcc\mingw32\4.5.2\include\c++;%WXWIN%\include<br />
Set LIBRARY_PATH=%WXWIN%\lib\gcc_lib;%HASKELL_COMPILER_DIR%\mingw\lib\<br />
</pre><br />
<br />
<br />
===== From GitHub =====<br />
<br />
You can get wxHaskell from Hackage and from GitHub;<br />
to install the most recent version of wxHaskell from the repository:<br />
<pre><br />
Cd &lt;Where\you\want\to\install\wxHaskell&gt;<br />
git clone https://github.com/wxHaskell/wxHaskell.git<br />
Cd wxHaskell<br />
cabal install .\wxdirect<br />
cabal install .\wxc<br />
cabal install .\wxcore<br />
cabal install .\wx<br />
</pre><br />
<br />
Make sure that all below mentioned DLLs are in the search path and try a sample program:<br />
<pre><br />
Cd samples\wxcore<br />
ghc BouncingBalls<br />
BouncingBalls<br />
</pre><br />
Click with the left mouse button on the window to create new bouncing balls.<br />
<br />
If you get an exception code 0xc000007b immediately after starting your wxHaskell program, there is a mismatch between bitness of your program and the bitness of the wxWidgets DLLs. Note, that the package wxc checks the bitness at installation time, but things can go wrong afterwards, like changing the search path to point to a different version of the wxWidgets DLLs.<br />
<br />
===== From Hackage =====<br />
<br />
To install the wxHaskell from Hackage:<br />
<pre><br />
cabal install wx<br />
</pre><br />
<br />
== wxWidgets 3.0 and wxHaskell 0.91.x ==<br />
<br />
{|border=1 style="border-collapse: collapse;"<br />
! Windows<br />
! Haskell Platform<br />
! wxWidgets<br />
|-<br />
|| 8.1 || 2013.2.0.0 || 3.0.1<br />
|-<br />
|| 8.1 || 2014.2.0.0 || 3.0.1, 3.0.2<br />
|-<br />
|}<br />
<br />
<br />
Prerequisites:<br />
* If you want to install from Hackage: [http://sourceforge.net/projects/mingw/files/OldFiles/MinGW%205.1.6/ MinGW 5.1.6] and [http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe MSYS 1.0.11] (a recent version of MinGW will result in incompatible DLLs). You must select the C++ compiler and MinGW-make options when installing MinGW. Add the full path to directories MinGW\bin and msys\1.0\bin to your search path. If you install the most recent version from GitHub, use the same version of GCC as the one that comes with GHC (use command <code>gcc --version</code>), to prevent compatibility problems.<br />
<br />
<br />
Environment variables:<br />
<br />
* GHC_VERSION: 7.8.3 (some recent version)<br />
* WXC_VERSION: 0.91.0.0 (preferably the most recent version, see [http://hackage.haskell.org/package/wxc Hackage])<br />
* WXWIN: C:\wxWidgets-3.0.3<br />
* WXCFG: gcc_dll\mswu<br />
* PATH: (add these) %WXWIN%\lib\gcc_dll;%WXWIN%;%APPDATA%\cabal\bin;%APPDATA%\cabal\i386-windows-ghc-%GHC_VERSION%\wxc-%WXC_VERSION%<br />
<br />
If you are using a cabal sandbox, you must add the following to your search path:<br />
* .cabal-sandbox\bin<br />
to ensure that wxdirect.exe can be found.<br />
<br />
Steps:<br />
<br />
<ol><br />
<li> Make sure, that the GCC from the MinGW package is used for compilation of wxWidgets, by adding its directory to the start of the search path, with a command like:<br />
<pre><br />
Set path=C:\MinGW\bin;%path%<br />
</pre><br />
<li> Download [http://wxwidgets.org/downloads wxWidgets 3.0.3 source]<br />
<li> Extract to C:\wxWidgets-3.0.3<br />
<li> [http://wiki.wxwidgets.org/Compiling_wxWidgets_with_MinGW Build wxWidgets-3.0.3]<br />
<br>Edit <tt>wxwidgets-src-dir\build\msw\config.gcc</tt> so that the following values are set:<br />
<pre><br />
SHARED ?= 1<br />
BUILD ?= release<br />
</pre><br />
Then (in cmd.exe, ''not'' bash):<br />
<pre><br />
cd wxwidgets-src-dir\build\msw<br />
sh<br />
mingw32-make -f makefile.gcc<br />
</pre><br />
<li> Download [https://sourceforge.net/projects/wxhaskell/files/wx-config-win/ wx-config.exe] (a new version for wxWidgets > 3.0) and copy it somewhere into your search path, for instance via<br />
<pre><br />
copy wx-config.exe %CABAL_DIR%\bin<br />
</pre><br />
<li> Make sure, that the GCC that comes with GHC is used for the rest of the procedure, by adding its directory to the search path, with a command like:<br />
<pre><br />
Set path=C:\Haskell\Haskell Platform\2014.2.0.0\mingw\bin\;%path%<br />
</pre><br />
<li> Install the wxHaskell libraries</li><br />
To get the most recent version (using [http://git-scm.com/ Git]):<br />
<pre><br />
git clone git://github.com/wxHaskell/wxHaskell.git<br />
cd wxHaskell\wxdirect<br />
cabal update<br />
cabal install<br />
cd ..\wxc<br />
cabal install<br />
cd ..\wxcore<br />
cabal install<br />
cd ..\wx<br />
cabal install<br />
</pre><br />
Or, for the Hackage version:<br />
<pre><br />
cabal update<br />
cabal install wx<br />
</pre><br />
Or, if you want to install the dependencies separately:<br />
<pre><br />
cabal update<br />
cabal install wxdirect<br />
cabal install wxc<br />
cabal install wxcore<br />
cabal install wx<br />
</pre><br />
<li> Install the DLLs described in the next subsection<br />
</ol><br />
<br />
<br />
=== DLLs ===<br />
<br />
In order to run a wxHaskell application, Windows must be able to find the following wxWidgets DLLs (see [http://msdn.microsoft.com/en-us/library/7d83bc18(v=vs.71).aspx Search Path Used by Windows to Locate a DLL]):<br />
<br />
* wxWidgets-x.y.z\lib\gcc_dll\*.dll<br />
<br />
The following file can be found in directory wxc\dist\build\, after building package wxc in directory wxc:<br />
* wxc.dll (be sure to recompile and copy this one when you compile your application with a new compiler)<br />
<br />
If you are using GHC 7.10.3 or later, the rest of the necessary DLLs can be found in the mingw\bin directory of your GHC installation. For an earlier GHC, you can find the DLLs in the [http://sourceforge.net/projects/wxhaskell/files/wxInstall/ wxInstall Abriline packages], or as described below.<br />
<br />
The following DLLs can be found in directory "Haskell Platform\2014.2.0.0\mingw\bin\", or in ghc-7.10.1\mingw\bin\ if you installed the compiler only (change revision as needed):<br />
* libgcc_s_dw2-1.dll<br />
* libstdc++-6.dll<br />
* mingwm10.dll <br />
<br />
Some wxHaskell applications also require the following DLLs:<br />
* uuid.dll<br />
* perl510.dll<br />
* libapr-1.dll<br />
* libapriconv-1.dll<br />
* libaprutil-1.dll<br />
<br />
These DLLs can be obtained by installing [http://sourceforge.net/projects/xampp/files/XAMPP%20Windows/1.7.4/ XAMPP 1.7.4]; the DLLs are in the directories:<br />
* xampp\perl\site\lib\auto\APR\UUID<br />
* xampp\perl\bin<br />
* xampp\apache\bin<br />
<br />
If there are still DLLs missing, you can find out which, using [http://cygwin.com/cygwin-ug-net/cygcheck.html cygcheck] from the [http://www.cygwin.com/ Cygwin project]. Note, that you will get problems if you have both MinGW and Cygwin in your search path; it is best to specify the full path to cygcheck.exe, or copy cygcheck.exe to some location in the search path.<br />
Sample command:<br />
C:\programs\cygwin\bin\cygcheck.exe .\h.exe<br />
(the .\ must be specified)<br />
<br />
== wxWidgets 2.8 and wxHaskell 0.13.x ==<br />
<br />
Follow [http://www.scribd.com/doc/38034374/20100923-WxHaskell-Setup SkyTreeBird's guide]. It which walks you through the basic steps<br />
<br />
* wx-config<br />
* wxPack<br />
* setting up environment variables<br />
* <code>cabal install wx</code><br />
<br />
Note that the best way to refer to WxWidgets in your PATH is probably to use the WXWIN variable that you set, eg. <code>%WXWIN%\lib\gcc_dll</code><br />
<br />
The guide has been tested with the following configurations. Others may work too:<br />
<br />
{|border=1 style="border-collapse: collapse;"<br />
! Windows<br />
! Haskell Platform<br />
! wxWidgets<br />
|-<br />
|| XP || 2010.2.0.0 || 2.8.10<br />
|-<br />
|| 7 || 2011.2.0.1 || 2.8.12<br />
|}<br />
<br />
<br />
=== DLLs ===<br />
<br />
In order to run a wxHaskell application, the following DLLs must be in the search path:<br />
<br />
* mingwm10.dll; this can be found in directory "Haskell Platform\2012.2.0.0\mingw\bin\", or in ghc-7.4.2\mingw\bin\ if you installed just the compiler (change revision as needed)<br />
<br />
* wxmsw28u_gcc_custom.dll<br />
<br />
<br />
<br />
=== Troubleshooting installation with cabal ===<br />
<br />
These remarks refer to wx-0.13.2 and Haskell Platform 2011.4.0.0 on Windows 7.<br />
<br />
Cabal package wx depends on wxcore which depends on wxdirect. By default cabal installs on a per user base, thus wxdirect.exe will be installed to <code>c:\Users\<YOUR NAME>\AppData\Roaming\cabal\bin\</code>. This folder must be in your <code>PATH</code> for <code>cabal install wxcore</code> to succeed. <br />
<br />
Package wxcore-0.13.2 does not work well with wx-config revision 21 2006-10-19 (downloaded from [http://sites.google.com/site/wxconfig/ here] on Feb 2<sup>nd</sup> 2012). If <code>cabal install wxcore</code> fails with an output containing "Usage: wx-config [options]" try this: <br />
<br />
* <code>cabal unpack wxcore</code><br />
* <code>cd wxcore-0.13.2</code><br />
* edit <code>Setup.hs</code> and comment out/remove the line containing <code>"wx-config" ["--version"]</code><br />
* <code>runhaskell.exe Setup.hs configure --user</code><br />
* <code>runhaskell.exe Setup.hs build</code><br />
* <code>runhaskell.exe Setup.hs install</code><br />
<br />
Finally call <code>cabal install wx</code>.<br />
<br />
<br />
== See also ==<br />
<br />
* [[../Cygwin]]<br />
<br />
[[Category:wxHaskell|Windows]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Abbreviations&diff=63142Abbreviations2019-11-21T19:08:40Z<p>Henk-Jan van Tuyl: Updated more links</p>
<hr />
<div>== An overview of Haskell related abbreviations ==<br />
<br />
Note: if there is an abbreviation you cannot find here, it might be the name of a package, so check the [http://hackage.haskell.org/packages/ Hackage package list]. For GHC related abbreviations, see [https://gitlab.haskell.org/ghc/ghc/wikis/commentary/abbreviations GHC Source Code Abbreviations]. The abbreviation might also indicate a [[Conferences | conference]]. <br />
<br />
{| <br />
| ABI<br />
| [https://en.wikipedia.org/wiki/Application_binary_interface Application Binary Interface]<br />
|- <br />
| ADP<br />
| [https://bibiserv.cebitec.uni-bielefeld.de/adp/ Algebraic Dynamic Programming]<br />
|- <br />
| ADT <br />
| [[Abstract data type | Abstract Data Type]] / [[Algebraic data type | Algebraic Data Type]]<br />
|- <br />
| AFAIC <br />
| As Far As I'm Concerned / As Far As I Can<br />
|- <br />
| AFAICS<br />
| As Far As I Can See<br />
|- <br />
| AFAICT <br />
| As Far As I Can Tell<br />
|- <br />
| AFAIK<br />
| As Far As I Know<br />
|- <br />
| AFAIU<br />
| As Far As I Understand<br />
|- <br />
| AFRP<br />
| [[Arrows-based Functional Reactive Programming]]<br />
|- <br />
| AKA<br />
| Also Known As<br />
|- <br />
| alist<br />
| Association list, a list of key-value pairs, [(key, value)]<br />
|- <br />
| AMP<br />
| [https://wiki.haskell.org/Functor-Applicative-Monad_Proposal Applicative-Monad Proposal]<br />
|- <br />
| ANN<br />
| ANNouncement / [https://en.wikipedia.org/wiki/Artificial_neural_network Artificial Neural Network]<br />
|- <br />
| API<br />
| [https://en.wikipedia.org/wiki/Application_programming_interface Application Programming Interface]<br />
|- <br />
| aPToP<br />
| [http://www.cs.toronto.edu/~hehner/aPToP/ A practical theory of programming]<br />
|- <br />
| ASAP<br />
| As Soon As Possible<br />
|- <br />
| AST<br />
| [https://en.wikipedia.org/wiki/Abstract_syntax_tree Abstract syntax tree]<br />
|-<br />
| AT<br />
| [[Abstract data type | Abstract (Data) Type]] / [http://nattermorphisms.blogspot.com/2008/10/2-minute-intro-to-associated-types-type.html Associated (Data) Type] (see also [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.646.5887&rep=rep1&type=pdf Associated types with class])<br />
|- <br />
| BE<br />
| [https://en.wikipedia.org/wiki/Endianness Big Endian]<br />
|- <br />
| BSD<br />
| [https://en.wikipedia.org/wiki/BSD_license Berkeley Software Distributions (license)]<br />
|- <br />
| Cabal<br />
| [[Cabal | Common Architecture for Building Applications and Libraries]]<br />
|- <br />
| CAF<br />
| [[Constant applicative form | Constant Applicative Form]]<br />
|- <br />
| CAML<br />
| A programming language<br />
|- <br />
| CFG<br />
| [https://en.wikipedia.org/wiki/Context-free_grammar Context-Free Grammar]<br />
|- <br />
| CFP<br />
| Call For Papers - request to send material for a symposium<br />
|- <br />
| CLC<br />
| [[Core Libraries Committee]]<br />
|-<br />
| CPR<br />
| [https://www.microsoft.com/en-us/research/publication/constructed-product-result-analysis-haskell/ Constructed Product Result] (analysis)<br />
|- <br />
| CPS<br />
| [[Continuation | Continuation-Passing Style]]<br />
|- <br />
| CSE<br />
| [https://en.wikipedia.org/wiki/Common_subexpression_elimination Common subexpression elimination] <br />
|- <br />
| CUFP<br />
| [http://cufp.org/ Commercial Users of Functional Programming] <br />
|- <br />
| DAG<br />
| [https://en.wikipedia.org/wiki/Directed_acyclic_graph Directed acyclic graph]<br />
|- <br />
| DFA<br />
| [https://en.wikipedia.org/wiki/Deterministic_finite_automaton Deterministic Finite Automaton], [https://en.wikipedia.org/wiki/Data_flow_analysis Data Flow Analysis], [https://en.wikipedia.org/wiki/Differential_fault_analysis Differential Fault Analysis] or [https://en.wikipedia.org/wiki/Dual_Factor_Authentication Dual Factor Authentication]<br />
|- <br />
| DPH<br />
| [[GHC/Data Parallel Haskell | Data Parallel Haskell]]<br />
|- <br />
| DRY<br />
| [https://en.wikipedia.org/wiki/Don't_repeat_yourself Don't repeat yourself]<br />
|- <br />
| DSEL<br />
| [[Embedded domain specific language | Domain-Specific Embedded Language]]<br />
|- <br />
| DSL<br />
| [[Embedded domain specific language | Domain-Specific Language]]<br />
|- <br />
<br />
| DVCS<br />
| [https://en.wikipedia.org/wiki/Distributed_version_control_system Distributed Version Control System]<br />
|- <br />
| EDSL<br />
| [[Embedded domain specific language | Embedded Domain-Specific Language]]<br />
|- <br />
| EHC<br />
| The [https://web.archive.org/web/20160916002228/foswiki.cs.uu.nl/foswiki/Ehc/WebHome Essential Haskell Compiler]<br />
|- <br />
| elt<br />
| Element (of a list/set/...)<br />
|- <br />
| FAQ<br />
| [[:Category:FAQ | Frequently Asked Questions]]<br />
|- <br />
| FD <br />
| [[Functional dependencies | Functional Dependencies]]<br />
|- <br />
| FFI <br />
| [[Foreign Function Interface]]<br />
|- <br />
| FHM<br />
| [https://db.inf.uni-tuebingen.de/team/GeorgeGiorgidze.html Functional Hybrid Modeling]<br />
|- <br />
| FPL<br />
| [http://www.haskell.org Functional Programming Language]<br />
|-<br />
| FTFY <br />
| Fixed That For You<br />
|-<br />
| FRP<br />
| [[Functional Reactive Programming]]<br />
|- <br />
| FSF<br />
| [https://www.fsf.org/ Free Software Foundation]<br />
|- <br />
| FTP<br />
| [[Foldable Traversable In Prelude | Foldable/Traversable in Prelude proposal]]<br />
|- <br />
| FTW<br />
| [https://en.wiktionary.org/wiki/FTW For The World / For The Win]<br />
|- <br />
| FunDeps<br />
| [[Functional dependencies | Functional Dependencies]]<br />
|- <br />
| FWIW<br />
| For what it's worth<br />
|- <br />
| GCC<br />
| [http://gcc.gnu.org/ GNU Compiler Collection]<br />
|- <br />
| GHC<br />
| [https://www.haskell.org/ghc/ Glasgow Haskell Compiler]<br />
|-<br />
| GPL<br />
| [http://www.gnu.org/licenses/gpl.html GNU General Public License]<br />
|- <br />
| GPL2<br />
| [http://www.gnu.org/licenses/gpl2.html GNU General Public License, Version 2]<br />
|- <br />
| GPL3<br />
| [http://www.gnu.org/licenses/gpl.html GNU General Public License, Version 3]<br />
|- <br />
| GSoC<br />
| [https://developers.google.com/open-source/gsoc/?csw=1 Google Summer of Code]<br />
|- <br />
| GUI<br />
| [https://en.wikipedia.org/wiki/Graphical_User_Interface Graphical User Interface]<br />
|- <br />
| HaLVM<br />
| [https://github.com/GaloisInc/HaLVM Haskell Lightweight Virtual Machine]<br />
|- <br />
| HBC<br />
| [https://wiki.haskell.org/Implementations#HBI_and_HBC.2C_Chalmers.27_Haskell_Interpreter_and_Compiler Haskell-B Compiler]<br />
|- <br />
| HBI<br />
| [https://wiki.haskell.org/Implementations#HBI_and_HBC.2C_Chalmers.27_Haskell_Interpreter_and_Compiler Haskell-B Interpreter]<br />
|- <br />
| HCAR<br />
| [https://wiki.haskell.org/Haskell_Communities_and_Activities_Report Haskell Communities and Activities Report]<br />
|- <br />
| HIE<br />
| [https://github.com/haskell/haskell-ide-engine Haskell IDE Engine]<br />
|-<br />
| HNF<br />
| [https://encyclopedia2.thefreedictionary.com/head+normal+form Head Normal Form]<br />
|- <br />
| HOAS <br />
| [https://en.wikipedia.org/wiki/Higher-order_abstract_syntax Higher-Order Abstract Syntax] (using binding in the host language to represent binding in the embedded language)<br />
|- <br />
| HOF<br />
| [[Higher order function | Higher-Order Functions]]<br />
|- <br />
| HPC<br />
| [[Haskell program coverage | Haskell Program Coverage]], a tool-kit to record and display Haskell program coverage / [https://prime.haskell.org/wiki/Committee Haskell Prime Committee] / High Performance Computing<br />
|- <br />
| HPFFP<br />
| [https://haskellbook.com/ Haskell Programming From First Principles] (book)<br />
|- <br />
| HSE<br />
| [http://hackage.haskell.org/package/haskell-src-exts Haskell-Source with Extensions] (a package on Hackage, haskell-src-exts); an extension of the standard haskell-src package<br />
|- <br />
| HTH<br />
| Hope This Helps<br />
|- <br />
| HTML<br />
| [https://en.wikipedia.org/wiki/HTML HyperText Markup Language]<br />
|- <br />
| HUGS <br />
| [[Hugs | Haskell User's Gofer System]]<br />
|- <br />
| HWN<br />
| [[Haskell Weekly News]]<br />
|- <br />
| I18n<br />
| Internationalization / Internationalisation (which shows why the abbreviation is useful)<br />
|- <br />
| IANAL<br />
| I Am Not A Lawyer<br />
|- <br />
| ICFP<br />
| [http://www.icfpconference.org/ International Conference on Functional Programming]<br />
|- <br />
| IFL<br />
| [[Conferences#Implementation_of_Functional_Languages_.28IFL.29 | Implementation and Application of Functional Languages]], symposium<br />
|- <br />
| IHG<br />
| [http://industry.haskell.org/ Industrial Haskell Group]<br />
|- <br />
| IIRC<br />
| If I Recall Correctly<br />
|- <br />
| IIUIC<br />
| If I Understand It Correctly<br />
|- <br />
| IIUC<br />
| If I Understand Correctly<br />
|- <br />
| IME <br />
| In My Experience<br />
|- <br />
| IMHO<br />
| In My Humble Opinion<br />
|- <br />
| IMNSHO<br />
| In My Not So Humble Opinion<br />
|- <br />
| IMO<br />
| In My Opinion<br />
|- <br />
| IOW<br />
| In Other Words<br />
|- <br />
| IR<br />
| [http://lambda.uta.edu/cse5317/notes/node5.html Intermediate Representation] in a two-phase compiler<br />
|- <br />
| IRC<br />
| [[IRC channel | Internet Relay Chat]]<br />
|- <br />
| ISTR<br />
| I Seem To Recall<br />
|- <br />
| JFYI<br />
| Just For Your Information<br />
|- <br />
| JHC<br />
| [[Jhc|John's Haskell Compiler]]. Compiles to efficient C programs via whole program analysis and other optimizations.<br />
|- <br />
| JVM<br />
| [https://en.wikipedia.org/wiki/Java_Virtual_Machine Java Virtual Machine]<br />
|- <br />
| LE<br />
| [https://en.wikipedia.org/wiki/Endianness Little Endian]<br />
|- <br />
| LGPL<br />
| [http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License]<br />
|- <br />
| LHC<br />
| [https://github.com/Lemmih/lhc LLVM Haskell Compiler]. LHC is a whole-program optimizing backend for the Glorious Glasgow Haskell Compiler<br />
|- <br />
| LHS<br />
| Left-Hand Side (of a statement)<br />
|- <br />
| LLVM<br />
| [[LLVM | Low-Level Virtual Machine]]<br />
|- <br />
| LSP<br />
| [https://en.wikipedia.org/wiki/Language_Server_Protocol Language Server Protocol] (used by the Haskell IDE Engine)<br />
|- <br />
| LtU<br />
| [http://lambda-the-ultimate.org/ Lambda the Ultimate] (Website)<br />
|- <br />
| LYH<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| LYAH<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| LYAHFGG<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| MFP<br />
| [[MonadFail Proposal]]<br />
|- <br />
| ML<br />
| A [https://en.wikipedia.org/wiki/ML_(programming_language) programming language] / Mailing List / Machine Learning<br />
|- <br />
| MMR <br />
| [[Monomorphism Restriction | MonoMorphism Restriction]]<br />
|- <br />
| MPTC<br />
| [[Multi-parameter type class | Multi-Parameter Type Class]]<br />
|- <br />
| MR<br />
| [[Monomorphism Restriction]]<br />
|- <br />
| MRP<br />
| [https://mail.haskell.org/pipermail/libraries/2015-September/026121.html Monad of no `return` Proposal (MRP)]: Moving `return` out of `Monad`<br />
|- <br />
| MTL<br />
| [http://hackage.haskell.org/package/mtl Monad Transformer Library]<br />
|- <br />
| NCG<br />
| [https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/backends/ncg Native Code Generator], a GHC backend<br />
|- <br />
| NF<br />
| [https://encyclopedia2.thefreedictionary.com/Normal+Form Normal Form], in addition to the [https://en.wikipedia.org/wiki/Normal_form explanations in the Wikipedia article], a fully evaluated expression<br />
|- <br />
| nhc98<br />
| [https://www.haskell.org/nhc98/ Nearly a Haskell Compiler]<br />
|- <br />
| NLP<br />
| [https://wiki.haskell.org/Applications_and_libraries/Linguistics#Natural_language_processing_and_combinatory_logic Natural Language Processing]<br />
|- <br />
| OCAML<br />
| [http://caml.inria.fr/ Objective Caml] (A programming language)<br />
|- <br />
| OOM<br />
| Out Of Memory<br />
|- <br />
| OP<br />
| Original Poster (who sent the first e-mail of the current thread) or Original Post (the first e-mail of the current thread)<br />
|- <br />
| OT<br />
| Off-Topic<br />
|- <br />
| PADL<br />
| [https://wiki.haskell.org/Conferences#Practical_Aspects_of_Declarative_Languages_.28PADL.29 Practical Aspects of Declarative Languages], symposium<br />
|- <br />
| PM<br />
| Personal Message, a message to someone on a message board, that no one else can read<br />
|- <br />
| POPL<br />
| [https://en.wikipedia.org/wiki/POPL Principles of Programming Languages, Symposium on]<br />
|-<br />
| POV<br />
| Point Of View<br />
|- <br />
| ppl<br />
| People<br />
|- <br />
| PR<br />
| [https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests Pull Request]<br />
|-<br />
| PRNG <br />
| [https://en.wikipedia.org/wiki/Pseudorandom_number_generator Pseudorandom number generator]<br />
|-<br />
| PVP<br />
| [[Package versioning policy]]<br />
|- <br />
| RDP<br />
| [https://awelonblue.wordpress.com/2011/05/21/comparing-frp-to-rdp/ Reactive Demand Programming]<br />
|- <br />
| RFC<br />
| [https://en.wikipedia.org/wiki/Request_For_Comment Request For Comments]<br />
|- <br />
| RHS<br />
| Right-Hand Side (of a statement)<br />
|- <br />
| RNG<br />
| [https://en.wikipedia.org/wiki/Random_number_generator Random number generator]<br />
|-<br />
| RWH<br />
| [http://book.realworldhaskell.org/ Real World Haskell], a book about Haskell<br />
|-<br />
| SAT<br />
| [https://en.wikipedia.org/wiki/Boolean_satisfiability_problem SATisfiability problem]<br />
|- <br />
| SEC<br />
| [http://conal.net/blog/posts/semantic-editor-combinators Semantic editor combinator]<br />
|- <br />
| SHE<br />
| [http://personal.cis.strath.ac.uk/~conor/pub/she/ Strathclyde Haskell Enhancement], an experimental preprocessor for the Glasgow Haskell Compiler<br />
|- <br />
| SICP<br />
| [https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html Structure and Interpretation of Computer Programs]<br />
|- <br />
| SML<br />
| [https://en.wikipedia.org/wiki/Standard_ML Standard ML, a programming language]<br />
|- <br />
| SMP<br />
| [https://en.wikipedia.org/wiki/Symmetric_multiprocessing Symmetric Multi-Processing]<br />
|- <br />
| SMT <br />
| [https://en.wikipedia.org/wiki/Satisfiability_Modulo_Theories Satisfiability Modulo Theories]<br />
|- <br />
| SO<br />
| [https://stackoverflow.com/ StackOverflow], a programming question and answer site<br />
|- <br />
| SOE<br />
| [https://wiki.haskell.org/Books#Textbooks Haskell School Of Expression] (title of a book)<br />
|- <br />
| SORF<br />
| [https://gitlab.haskell.org/ghc/ghc/wikis/records/overloaded-record-fields Simple Overloaded Record Fields]<br />
|- <br />
| SPJ<br />
| [https://www.microsoft.com/en-us/research/people/simonpj/ Simon Peyton Jones]<br />
|- <br />
| SPOJ<br />
| [https://www.spoj.com/ Sphere Online Judge], an online judge system with over 9000 problems. The solution to problems can be submitted in over 40 languages, including Haskell<br />
|- <br />
| SQL<br />
| [https://en.wikipedia.org/wiki/SQL Structured Query Language]<br />
|- <br />
| STG machine<br />
| [https://www.microsoft.com/en-us/research/publication/implementing-lazy-functional-languages-on-stock-hardware-the-spineless-tagless-g-machine/ Spineless Tagless G-machine]<br />
|- <br />
| STLC<br />
| [https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus Simply Typed Lambda Calculus]<br />
|- <br />
| STM<br />
| [[Software transactional memory]]<br />
|- <br />
| SYB<br />
| [[Scrap your boilerplate | Scrap Your Boilerplate]]<br />
|- <br />
| TaPL<br />
| [https://www.cis.upenn.edu/~bcpierce/tapl/ Types and Programming Languages] (book)<br />
|- <br />
| TCM<br />
| [http://conal.net/blog/tag/type-class-morphism Type Class Morphism]<br />
|- <br />
| TCO<br />
| [https://en.wikipedia.org/wiki/Tail_call_optimization Tail-Call Optimization]<br />
|- <br />
| TDNR<br />
| [https://prime.haskell.org/wiki/TypeDirectedNameResolution Type Directed Name Resolution]<br />
|- <br />
| TF<br />
| [[GHC/Type_families | Type families]]<br />
|- <br />
| TFP<br />
| [https://wiki.haskell.org/Conferences#Trends_in_Functional_Programming_.28TFP.29 Trends in Functional Programming], symposium<br />
|- <br />
| TH<br />
| [[Template Haskell]]<br />
|- <br />
| TIA<br />
| Thanks In Advance<br />
|- <br />
| TIL<br />
| Today I Learned<br />
|- <br />
| tl;dr<br />
| Too Long; Didn't Read<br />
|- <br />
| TLDR<br />
| Too Long; Didn't Read<br />
|- <br />
| TMI<br />
| Too Much Information<br />
|- <br />
| TMR<br />
| [[The Monad.Reader]]<br />
|- <br />
| TTBOMK<br />
| To the best of my knowledge<br />
|- <br />
| UHC<br />
| [https://web.archive.org/web/20170729171806/foswiki.cs.uu.nl/foswiki/UHC Utrecht Haskell Compiler]<br />
|- <br />
| UTF8<br />
| [http://unicode.org/faq/utf_bom.html#UTF8 Unicode Transformation Format, byte-oriented] (also written as UTF-8)<br />
|- <br />
| VCS<br />
| [https://en.wikipedia.org/wiki/Version_Control_System Version Control System]<br />
|- <br />
| VPS<br />
| [https://en.wikipedia.org/wiki/Virtual_Private_Server Virtual Private Server], a virtual machine for hosting a website<br />
|- <br />
| WHNF<br />
| [[Weak head normal form | Weak Head Normal Form]]<br />
|- <br />
| wrt<br />
| With Respect To, or With Regard To<br />
|- <br />
| XML<br />
| [https://en.wikipedia.org/wiki/XML eXtensible Markup Language]<br />
|- <br />
| YAHT<br />
| [https://en.wikibooks.org/wiki/Haskell/YAHT Yet Another Haskell Tutorial]<br />
|- <br />
| YHC<br />
| [[Yhc | York Haskell Compiler]]<br />
|- <br />
| YMMV<br />
| [https://en.wiktionary.org/wiki/your_mileage_may_vary Your Mileage May Vary]<br />
|- <br />
|}<br />
<br />
[[Category:Language]]<br />
[[Category:Glossary]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Abbreviations&diff=63137Abbreviations2019-11-21T14:51:19Z<p>Henk-Jan van Tuyl: Updated links</p>
<hr />
<div>== An overview of Haskell related abbreviations ==<br />
<br />
Note: if there is an abbreviation you cannot find here, it might be the name of a package, so check the [http://hackage.haskell.org/packages/ Hackage package list]. For GHC related abbreviations, see [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Abbreviations GHC Source Code Abbreviations]. The abbreviation might also indicate a [[Conferences | conference]]. <br />
<br />
{| <br />
| ABI<br />
| [https://en.wikipedia.org/wiki/Application_binary_interface Application Binary Interface]<br />
|- <br />
| ADP<br />
| [https://bibiserv.cebitec.uni-bielefeld.de/adp/ Algebraic Dynamic Programming]<br />
|- <br />
| ADT <br />
| [[Abstract data type | Abstract Data Type]] / [[Algebraic data type | Algebraic Data Type]]<br />
|- <br />
| AFAIC <br />
| As Far As I'm Concerned / As Far As I Can<br />
|- <br />
| AFAICS<br />
| As Far As I Can See<br />
|- <br />
| AFAICT <br />
| As Far As I Can Tell<br />
|- <br />
| AFAIK<br />
| As Far As I Know<br />
|- <br />
| AFAIU<br />
| As Far As I Understand<br />
|- <br />
| AFRP<br />
| [[Arrows-based Functional Reactive Programming]]<br />
|- <br />
| AKA<br />
| Also Known As<br />
|- <br />
| alist<br />
| Association list, a list of key-value pairs, [(key, value)]<br />
|- <br />
| AMP<br />
| [https://wiki.haskell.org/Functor-Applicative-Monad_Proposal Applicative-Monad Proposal]<br />
|- <br />
| ANN<br />
| ANNouncement / [https://en.wikipedia.org/wiki/Artificial_neural_network Artificial Neural Network]<br />
|- <br />
| API<br />
| [https://en.wikipedia.org/wiki/Application_programming_interface Application Programming Interface]<br />
|- <br />
| aPToP<br />
| [http://www.cs.toronto.edu/~hehner/aPToP/ A practical theory of programming]<br />
|- <br />
| ASAP<br />
| As Soon As Possible<br />
|- <br />
| AST<br />
| [https://en.wikipedia.org/wiki/Abstract_syntax_tree Abstract syntax tree]<br />
|-<br />
| AT<br />
| [[Abstract data type | Abstract (Data) Type]] / [http://nattermorphisms.blogspot.com/2008/10/2-minute-intro-to-associated-types-type.html Associated (Data) Type] (see also [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.646.5887&rep=rep1&type=pdf Associated types with class])<br />
|- <br />
| BE<br />
| [https://en.wikipedia.org/wiki/Endianness Big Endian]<br />
|- <br />
| BSD<br />
| [https://en.wikipedia.org/wiki/BSD_license Berkeley Software Distributions (license)]<br />
|- <br />
| Cabal<br />
| [[Cabal | Common Architecture for Building Applications and Libraries]]<br />
|- <br />
| CAF<br />
| [[Constant applicative form | Constant Applicative Form]]<br />
|- <br />
| CAML<br />
| A programming language<br />
|- <br />
| CFG<br />
| [https://en.wikipedia.org/wiki/Context-free_grammar Context-Free Grammar]<br />
|- <br />
| CFP<br />
| Call For Papers - request to send material for a symposium<br />
|- <br />
| CLC<br />
| [[Core Libraries Committee]]<br />
|-<br />
| CPR<br />
| [https://www.microsoft.com/en-us/research/publication/constructed-product-result-analysis-haskell/ Constructed Product Result] (analysis)<br />
|- <br />
| CPS<br />
| [[Continuation | Continuation-Passing Style]]<br />
|- <br />
| CSE<br />
| [https://en.wikipedia.org/wiki/Common_subexpression_elimination Common subexpression elimination] <br />
|- <br />
| CUFP<br />
| [http://cufp.org/ Commercial Users of Functional Programming] <br />
|- <br />
| DAG<br />
| [https://en.wikipedia.org/wiki/Directed_acyclic_graph Directed acyclic graph]<br />
|- <br />
| DFA<br />
| [https://en.wikipedia.org/wiki/Deterministic_finite_automaton Deterministic Finite Automaton], [https://en.wikipedia.org/wiki/Data_flow_analysis Data Flow Analysis], [https://en.wikipedia.org/wiki/Differential_fault_analysis Differential Fault Analysis] or [https://en.wikipedia.org/wiki/Dual_Factor_Authentication Dual Factor Authentication]<br />
|- <br />
| DPH<br />
| [[GHC/Data Parallel Haskell | Data Parallel Haskell]]<br />
|- <br />
| DRY<br />
| [https://en.wikipedia.org/wiki/Don't_repeat_yourself Don't repeat yourself]<br />
|- <br />
| DSEL<br />
| [[Embedded domain specific language | Domain-Specific Embedded Language]]<br />
|- <br />
| DSL<br />
| [[Embedded domain specific language | Domain-Specific Language]]<br />
|- <br />
<br />
| DVCS<br />
| [https://en.wikipedia.org/wiki/Distributed_version_control_system Distributed Version Control System]<br />
|- <br />
| EDSL<br />
| [[Embedded domain specific language | Embedded Domain-Specific Language]]<br />
|- <br />
| EHC<br />
| The [https://web.archive.org/web/20160916002228/foswiki.cs.uu.nl/foswiki/Ehc/WebHome Essential Haskell Compiler]<br />
|- <br />
| elt<br />
| Element (of a list/set/...)<br />
|- <br />
| FAQ<br />
| [[:Category:FAQ | Frequently Asked Questions]]<br />
|- <br />
| FD <br />
| [[Functional dependencies | Functional Dependencies]]<br />
|- <br />
| FFI <br />
| [[Foreign Function Interface]]<br />
|- <br />
| FHM<br />
| [https://db.inf.uni-tuebingen.de/team/GeorgeGiorgidze.html Functional Hybrid Modeling]<br />
|- <br />
| FPL<br />
| [http://www.haskell.org Functional Programming Language]<br />
|-<br />
| FTFY <br />
| Fixed That For You<br />
|-<br />
| FRP<br />
| [[Functional Reactive Programming]]<br />
|- <br />
| FSF<br />
| [https://www.fsf.org/ Free Software Foundation]<br />
|- <br />
| FTP<br />
| [[Foldable Traversable In Prelude | Foldable/Traversable in Prelude proposal]]<br />
|- <br />
| FTW<br />
| [https://en.wiktionary.org/wiki/FTW For The World / For The Win]<br />
|- <br />
| FunDeps<br />
| [[Functional dependencies | Functional Dependencies]]<br />
|- <br />
| FWIW<br />
| For what it's worth<br />
|- <br />
| GCC<br />
| [http://gcc.gnu.org/ GNU Compiler Collection]<br />
|- <br />
| GHC<br />
| [https://www.haskell.org/ghc/ Glasgow Haskell Compiler]<br />
|-<br />
| GPL<br />
| [http://www.gnu.org/licenses/gpl.html GNU General Public License]<br />
|- <br />
| GPL2<br />
| [http://www.gnu.org/licenses/gpl2.html GNU General Public License, Version 2]<br />
|- <br />
| GPL3<br />
| [http://www.gnu.org/licenses/gpl.html GNU General Public License, Version 3]<br />
|- <br />
| GSoC<br />
| [https://developers.google.com/open-source/gsoc/?csw=1 Google Summer of Code]<br />
|- <br />
| GUI<br />
| [https://en.wikipedia.org/wiki/Graphical_User_Interface Graphical User Interface]<br />
|- <br />
| HaLVM<br />
| [https://github.com/GaloisInc/HaLVM Haskell Lightweight Virtual Machine]<br />
|- <br />
| HBC<br />
| [https://wiki.haskell.org/Implementations#HBI_and_HBC.2C_Chalmers.27_Haskell_Interpreter_and_Compiler Haskell-B Compiler]<br />
|- <br />
| HBI<br />
| [https://wiki.haskell.org/Implementations#HBI_and_HBC.2C_Chalmers.27_Haskell_Interpreter_and_Compiler Haskell-B Interpreter]<br />
|- <br />
| HCAR<br />
| [https://wiki.haskell.org/Haskell_Communities_and_Activities_Report Haskell Communities and Activities Report]<br />
|- <br />
| HIE<br />
| [https://github.com/haskell/haskell-ide-engine Haskell IDE Engine]<br />
|-<br />
| HNF<br />
| [https://encyclopedia2.thefreedictionary.com/head+normal+form Head Normal Form]<br />
|- <br />
| HOAS <br />
| [https://en.wikipedia.org/wiki/Higher-order_abstract_syntax Higher-Order Abstract Syntax] (using binding in the host language to represent binding in the embedded language)<br />
|- <br />
| HOF<br />
| [[Higher order function | Higher-Order Functions]]<br />
|- <br />
| HPC<br />
| [[Haskell program coverage | Haskell Program Coverage]], a tool-kit to record and display Haskell program coverage / [https://prime.haskell.org/wiki/Committee Haskell Prime Committee] / High Performance Computing<br />
|- <br />
| HPFFP<br />
| [https://haskellbook.com/ Haskell Programming From First Principles] (book)<br />
|- <br />
| HSE<br />
| [http://hackage.haskell.org/package/haskell-src-exts Haskell-Source with Extensions] (a package on Hackage, haskell-src-exts); an extension of the standard haskell-src package<br />
|- <br />
| HTH<br />
| Hope This Helps<br />
|- <br />
| HTML<br />
| [https://en.wikipedia.org/wiki/HTML HyperText Markup Language]<br />
|- <br />
| HUGS <br />
| [[Hugs | Haskell User's Gofer System]]<br />
|- <br />
| HWN<br />
| [[Haskell Weekly News]]<br />
|- <br />
| I18n<br />
| Internationalization / Internationalisation (which shows why the abbreviation is useful)<br />
|- <br />
| IANAL<br />
| I Am Not A Lawyer<br />
|- <br />
| ICFP<br />
| [http://www.icfpconference.org/ International Conference on Functional Programming]<br />
|- <br />
| IFL<br />
| [[Conferences#Implementation_of_Functional_Languages_.28IFL.29 | Implementation and Application of Functional Languages]], symposium<br />
|- <br />
| IHG<br />
| [http://industry.haskell.org/ Industrial Haskell Group]<br />
|- <br />
| IIRC<br />
| If I Recall Correctly<br />
|- <br />
| IIUIC<br />
| If I Understand It Correctly<br />
|- <br />
| IIUC<br />
| If I Understand Correctly<br />
|- <br />
| IME <br />
| In My Experience<br />
|- <br />
| IMHO<br />
| In My Humble Opinion<br />
|- <br />
| IMNSHO<br />
| In My Not So Humble Opinion<br />
|- <br />
| IMO<br />
| In My Opinion<br />
|- <br />
| IOW<br />
| In Other Words<br />
|- <br />
| IR<br />
| [http://lambda.uta.edu/cse5317/notes/node5.html Intermediate Representation] in a two-phase compiler<br />
|- <br />
| IRC<br />
| [[IRC channel | Internet Relay Chat]]<br />
|- <br />
| ISTR<br />
| I Seem To Recall<br />
|- <br />
| JFYI<br />
| Just For Your Information<br />
|- <br />
| JHC<br />
| [[Jhc|John's Haskell Compiler]]. Compiles to efficient C programs via whole program analysis and other optimizations.<br />
|- <br />
| JVM<br />
| [https://en.wikipedia.org/wiki/Java_Virtual_Machine Java Virtual Machine]<br />
|- <br />
| LE<br />
| [https://en.wikipedia.org/wiki/Endianness Little Endian]<br />
|- <br />
| LGPL<br />
| [http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License]<br />
|- <br />
| LHC<br />
| [https://github.com/Lemmih/lhc LLVM Haskell Compiler]. LHC is a whole-program optimizing backend for the Glorious Glasgow Haskell Compiler<br />
|- <br />
| LHS<br />
| Left-Hand Side (of a statement)<br />
|- <br />
| LLVM<br />
| [[LLVM | Low-Level Virtual Machine]]<br />
|- <br />
| LSP<br />
| [https://en.wikipedia.org/wiki/Language_Server_Protocol Language Server Protocol] (used by the Haskell IDE Engine)<br />
|- <br />
| LtU<br />
| [http://lambda-the-ultimate.org/ Lambda the Ultimate] (Website)<br />
|- <br />
| LYH<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| LYAH<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| LYAHFGG<br />
| [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
|- <br />
| MFP<br />
| [[MonadFail Proposal]]<br />
|- <br />
| ML<br />
| A [https://en.wikipedia.org/wiki/ML_(programming_language) programming language] / Mailing List / Machine Learning<br />
|- <br />
| MMR <br />
| [[Monomorphism Restriction | MonoMorphism Restriction]]<br />
|- <br />
| MPTC<br />
| [[Multi-parameter type class | Multi-Parameter Type Class]]<br />
|- <br />
| MR<br />
| [[Monomorphism Restriction]]<br />
|- <br />
| MRP<br />
| [https://mail.haskell.org/pipermail/libraries/2015-September/026121.html Monad of no `return` Proposal (MRP)]: Moving `return` out of `Monad`<br />
|- <br />
| MTL<br />
| [http://hackage.haskell.org/package/mtl Monad Transformer Library]<br />
|- <br />
| NCG<br />
| [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/NCG Native Code Generator], a GHC backend<br />
|- <br />
| NF<br />
| [http://encyclopedia2.thefreedictionary.com/Normal+Form Normal Form], in addition to the [https://en.wikipedia.org/wiki/Normal_form explanations in the Wikipedia article], a fully evaluated expression<br />
|- <br />
| nhc98<br />
| [https://www.haskell.org/nhc98/ Nearly a Haskell Compiler]<br />
|- <br />
| NLP<br />
| [https://wiki.haskell.org/Applications_and_libraries/Linguistics#Natural_language_processing_and_combinatory_logic Natural Language Processing]<br />
|- <br />
| OCAML<br />
| [http://caml.inria.fr/ Objective Caml] (A programming language)<br />
|- <br />
| OOM<br />
| Out Of Memory<br />
|- <br />
| OP<br />
| Original Poster (who sent the first e-mail of the current thread) or Original Post (the first e-mail of the current thread)<br />
|- <br />
| OT<br />
| Off-Topic<br />
|- <br />
| PADL<br />
| [https://wiki.haskell.org/Conferences#Practical_Aspects_of_Declarative_Languages_.28PADL.29 Practical Aspects of Declarative Languages], symposium<br />
|- <br />
| PM<br />
| Personal Message, a message to someone on a message board, that no one else can read<br />
|- <br />
| POPL<br />
| [https://en.wikipedia.org/wiki/POPL Principles of Programming Languages, Symposium on]<br />
|-<br />
| POV<br />
| Point Of View<br />
|- <br />
| ppl<br />
| People<br />
|- <br />
| PR<br />
| [https://help.github.com/articles/using-pull-requests/ Pull Request]<br />
|-<br />
| PRNG <br />
| [https://en.wikipedia.org/wiki/Pseudorandom_number_generator Pseudorandom number generator]<br />
|-<br />
| PVP<br />
| [[Package versioning policy]]<br />
|- <br />
| RDP<br />
| [https://awelonblue.wordpress.com/2011/05/21/comparing-frp-to-rdp/ Reactive Demand Programming]<br />
|- <br />
| RFC<br />
| [https://en.wikipedia.org/wiki/Request_For_Comment Request For Comments]<br />
|- <br />
| RHS<br />
| Right-Hand Side (of a statement)<br />
|- <br />
| RNG<br />
| [https://en.wikipedia.org/wiki/Random_number_generator Random number generator]<br />
|-<br />
| RWH<br />
| [http://book.realworldhaskell.org/ Real World Haskell], a book about Haskell<br />
|-<br />
| SAT<br />
| [https://en.wikipedia.org/wiki/Boolean_satisfiability_problem SATisfiability problem]<br />
|- <br />
| SEC<br />
| [http://conal.net/blog/posts/semantic-editor-combinators Semantic editor combinator]<br />
|- <br />
| SHE<br />
| [http://personal.cis.strath.ac.uk/~conor/pub/she/ Strathclyde Haskell Enhancement], an experimental preprocessor for the Glasgow Haskell Compiler<br />
|- <br />
| SICP<br />
| [https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html Structure and Interpretation of Computer Programs]<br />
|- <br />
| SML<br />
| [https://en.wikipedia.org/wiki/Standard_ML Standard ML, a programming language]<br />
|- <br />
| SMP<br />
| [https://en.wikipedia.org/wiki/Symmetric_multiprocessing Symmetric Multi-Processing]<br />
|- <br />
| SMT <br />
| [https://en.wikipedia.org/wiki/Satisfiability_Modulo_Theories Satisfiability Modulo Theories]<br />
|- <br />
| SO<br />
| [https://stackoverflow.com/ StackOverflow], a programming question and answer site<br />
|- <br />
| SOE<br />
| [https://wiki.haskell.org/Books#Textbooks Haskell School Of Expression] (title of a book)<br />
|- <br />
| SORF<br />
| [https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields Simple Overloaded Record Fields]<br />
|- <br />
| SPJ<br />
| [https://www.microsoft.com/en-us/research/people/simonpj/ Simon Peyton Jones]<br />
|- <br />
| SPOJ<br />
| [https://www.spoj.com/ Sphere Online Judge], an online judge system with over 9000 problems. The solution to problems can be submitted in over 40 languages, including Haskell<br />
|- <br />
| SQL<br />
| [https://en.wikipedia.org/wiki/SQL Structured Query Language]<br />
|- <br />
| STG machine<br />
| [https://www.microsoft.com/en-us/research/publication/implementing-lazy-functional-languages-on-stock-hardware-the-spineless-tagless-g-machine/ Spineless Tagless G-machine]<br />
|- <br />
| STLC<br />
| [https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus Simply Typed Lambda Calculus]<br />
|- <br />
| STM<br />
| [[Software transactional memory]]<br />
|- <br />
| SYB<br />
| [[Scrap your boilerplate | Scrap Your Boilerplate]]<br />
|- <br />
| TaPL<br />
| [https://www.cis.upenn.edu/~bcpierce/tapl/ Types and Programming Languages] (book)<br />
|- <br />
| TCM<br />
| [http://conal.net/blog/tag/type-class-morphism Type Class Morphism]<br />
|- <br />
| TCO<br />
| [https://en.wikipedia.org/wiki/Tail_call_optimization Tail-Call Optimization]<br />
|- <br />
| TDNR<br />
| [https://prime.haskell.org/wiki/TypeDirectedNameResolution Type Directed Name Resolution]<br />
|- <br />
| TF<br />
| [[GHC/Type_families | Type families]]<br />
|- <br />
| TFP<br />
| [https://wiki.haskell.org/Conferences#Trends_in_Functional_Programming_.28TFP.29 Trends in Functional Programming], symposium<br />
|- <br />
| TH<br />
| [[Template Haskell]]<br />
|- <br />
| TIA<br />
| Thanks In Advance<br />
|- <br />
| TIL<br />
| Today I Learned<br />
|- <br />
| tl;dr<br />
| Too Long; Didn't Read<br />
|- <br />
| TLDR<br />
| Too Long; Didn't Read<br />
|- <br />
| TMI<br />
| Too Much Information<br />
|- <br />
| TMR<br />
| [[The Monad.Reader]]<br />
|- <br />
| TTBOMK<br />
| To the best of my knowledge<br />
|- <br />
| UHC<br />
| [https://web.archive.org/web/20170729171806/foswiki.cs.uu.nl/foswiki/UHC Utrecht Haskell Compiler]<br />
|- <br />
| UTF8<br />
| [http://unicode.org/faq/utf_bom.html#UTF8 Unicode Transformation Format, byte-oriented] (also written as UTF-8)<br />
|- <br />
| VCS<br />
| [https://en.wikipedia.org/wiki/Version_Control_System Version Control System]<br />
|- <br />
| VPS<br />
| [https://en.wikipedia.org/wiki/Virtual_Private_Server Virtual Private Server], a virtual machine for hosting a website<br />
|- <br />
| WHNF<br />
| [[Weak head normal form | Weak Head Normal Form]]<br />
|- <br />
| wrt<br />
| With Respect To, or With Regard To<br />
|- <br />
| XML<br />
| [https://en.wikipedia.org/wiki/XML eXtensible Markup Language]<br />
|- <br />
| YAHT<br />
| [https://en.wikibooks.org/wiki/Haskell/YAHT Yet Another Haskell Tutorial]<br />
|- <br />
| YHC<br />
| [[Yhc | York Haskell Compiler]]<br />
|- <br />
| YMMV<br />
| [https://en.wiktionary.org/wiki/your_mileage_may_vary Your Mileage May Vary]<br />
|- <br />
|}<br />
<br />
[[Category:Language]]<br />
[[Category:Glossary]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=How_to_unpack_a_tar_file_in_Windows&diff=63023How to unpack a tar file in Windows2019-08-28T15:37:03Z<p>Henk-Jan van Tuyl: /* TarTool */ Updated link to tartool</p>
<hr />
<div>= Introduction =<br />
Source code is often packed for download as a TAR (Tape ARchive) file, that is a standard format in the Unix/Linux world. These files have a <tt>.tar</tt> extension; they can also be compressed, the extension is <tt>.tar.gz</tt> or <tt>.tar.bz2</tt> in these cases. There are several ways to unpack these files.<br />
<br />
<br />
= tar =<br />
If you have MinGW/MSYS or Cygwin installed, you can use the <tt>tar</tt> command to unpack such files:<br />
tar xvf <.tar file><br />
tar xzvf <.tar.gz file><br />
tar xjvf <.tar.bz2 file><br />
Try <code>tar --help</code> or see the [http://man7.org/linux/man-pages/man1/tar.1.html tar man page] for more information.<br />
<br />
= 7-Zip =<br />
Another option is to install 7-Zip, which has a nice graphical user interface. 7-Zip can also be used to unpack many other formats and to create tar files (amongst others).<br />
<br />
# Download and install 7-Zip from [http://www.7-zip.org/ 7-zip.org]. If you do not want to use 7-Zip as a command line tool, skip the next steps.<br />
# Add the directory you installed 7-Zip into to your path (Start -> Control Panel -> System -> Advanced -> Environment Variables).<br />
# Move the tar file to the directory you wish to unpack into (usually the tar file will put everything into a directory inside this directory).<br />
# Open a command prompt, and cd to the directory.<br />
# If the tar file is compressed, type <tt> 7z x ''filename.tar.gz''</tt> at the command prompt (where <tt>''filename.tar.gz''</tt> is the name of the compressed tar file). This results in a tar file called <tt>''filename.tar''</tt><br />
# Type <tt> 7z x ''filename.tar''</tt> at the command prompt (where <tt>''filename.tar''</tt> is the name of the tar file).<br />
<br />
Instead of using 7-Zip on the command line, you can use the file manager and click on a <tt>.tar</tt>, <tt>.tar.gz</tt>, or<tt>.tar.bz2</tt> file; 7-Zip will automatically start.<br />
<br />
= TarTool =<br />
<br />
A simple windows command line tool (no install , just unzip)<br />
<br />
Its hosted on codeplex [https://github.com/senthilrajasek/tartool tartool], complete with the source code.<br />
<br />
#to decompress and untar .tar.gz (.tgz) files or<br />
#just untar .tar files<br />
<br />
>TarTool.exe<br />
<br />
Usage :<br />
<br />
>TarTool sourceFile destinationDirectory<br />
<br />
>TarTool D:\sample.tar.gz ./<br />
<br />
>TarTool sample.tgz temp<br />
<br />
>TarTool -x sample.tar temp<br />
<br />
TarTool 2.0 Beta supports bzip2 files such as tar.bz2 and .bz2 extraction.<br />
<br />
TarTool -xj sample.tar.bz2 temp<br />
or<br />
TarTool -j sample.bz2<br />
<br />
More details are on this post -- http://blog.rajasekharan.com/2009/01/16/tartool-windows-tar-gzip-tgz-extraction-tool/</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=How_to_unpack_a_tar_file_in_Windows&diff=63022How to unpack a tar file in Windows2019-08-28T15:34:25Z<p>Henk-Jan van Tuyl: /* tar */ Added "tar --help" suggestion</p>
<hr />
<div>= Introduction =<br />
Source code is often packed for download as a TAR (Tape ARchive) file, that is a standard format in the Unix/Linux world. These files have a <tt>.tar</tt> extension; they can also be compressed, the extension is <tt>.tar.gz</tt> or <tt>.tar.bz2</tt> in these cases. There are several ways to unpack these files.<br />
<br />
<br />
= tar =<br />
If you have MinGW/MSYS or Cygwin installed, you can use the <tt>tar</tt> command to unpack such files:<br />
tar xvf <.tar file><br />
tar xzvf <.tar.gz file><br />
tar xjvf <.tar.bz2 file><br />
Try <code>tar --help</code> or see the [http://man7.org/linux/man-pages/man1/tar.1.html tar man page] for more information.<br />
<br />
= 7-Zip =<br />
Another option is to install 7-Zip, which has a nice graphical user interface. 7-Zip can also be used to unpack many other formats and to create tar files (amongst others).<br />
<br />
# Download and install 7-Zip from [http://www.7-zip.org/ 7-zip.org]. If you do not want to use 7-Zip as a command line tool, skip the next steps.<br />
# Add the directory you installed 7-Zip into to your path (Start -> Control Panel -> System -> Advanced -> Environment Variables).<br />
# Move the tar file to the directory you wish to unpack into (usually the tar file will put everything into a directory inside this directory).<br />
# Open a command prompt, and cd to the directory.<br />
# If the tar file is compressed, type <tt> 7z x ''filename.tar.gz''</tt> at the command prompt (where <tt>''filename.tar.gz''</tt> is the name of the compressed tar file). This results in a tar file called <tt>''filename.tar''</tt><br />
# Type <tt> 7z x ''filename.tar''</tt> at the command prompt (where <tt>''filename.tar''</tt> is the name of the tar file).<br />
<br />
Instead of using 7-Zip on the command line, you can use the file manager and click on a <tt>.tar</tt>, <tt>.tar.gz</tt>, or<tt>.tar.bz2</tt> file; 7-Zip will automatically start.<br />
<br />
= TarTool =<br />
<br />
A simple windows command line tool (no install , just unzip)<br />
<br />
Its hosted on codeplex [http://tartool.codeplex.com/ tartool], complete with the source code.<br />
<br />
#to decompress and untar .tar.gz (.tgz) files or<br />
#just untar .tar files<br />
<br />
>TarTool.exe<br />
<br />
Usage :<br />
<br />
>TarTool sourceFile destinationDirectory<br />
<br />
>TarTool D:\sample.tar.gz ./<br />
<br />
>TarTool sample.tgz temp<br />
<br />
>TarTool -x sample.tar temp<br />
<br />
TarTool 2.0 Beta supports bzip2 files such as tar.bz2 and .bz2 extraction.<br />
<br />
TarTool -xj sample.tar.bz2 temp<br />
or<br />
TarTool -j sample.bz2<br />
<br />
More details are on this post -- http://blog.rajasekharan.com/2009/01/16/tartool-windows-tar-gzip-tgz-extraction-tool/</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=How_to_unpack_a_tar_file_in_Windows&diff=63021How to unpack a tar file in Windows2019-08-28T15:32:26Z<p>Henk-Jan van Tuyl: /* tar */ Updated link to man page</p>
<hr />
<div>= Introduction =<br />
Source code is often packed for download as a TAR (Tape ARchive) file, that is a standard format in the Unix/Linux world. These files have a <tt>.tar</tt> extension; they can also be compressed, the extension is <tt>.tar.gz</tt> or <tt>.tar.bz2</tt> in these cases. There are several ways to unpack these files.<br />
<br />
<br />
= tar =<br />
If you have MinGW/MSYS or Cygwin installed, you can use the <tt>tar</tt> command to unpack such files:<br />
tar xvf <.tar file><br />
tar xzvf <.tar.gz file><br />
tar xjvf <.tar.bz2 file><br />
See the [http://man7.org/linux/man-pages/man1/tar.1.html tar man page] for more information.<br />
<br />
= 7-Zip =<br />
Another option is to install 7-Zip, which has a nice graphical user interface. 7-Zip can also be used to unpack many other formats and to create tar files (amongst others).<br />
<br />
# Download and install 7-Zip from [http://www.7-zip.org/ 7-zip.org]. If you do not want to use 7-Zip as a command line tool, skip the next steps.<br />
# Add the directory you installed 7-Zip into to your path (Start -> Control Panel -> System -> Advanced -> Environment Variables).<br />
# Move the tar file to the directory you wish to unpack into (usually the tar file will put everything into a directory inside this directory).<br />
# Open a command prompt, and cd to the directory.<br />
# If the tar file is compressed, type <tt> 7z x ''filename.tar.gz''</tt> at the command prompt (where <tt>''filename.tar.gz''</tt> is the name of the compressed tar file). This results in a tar file called <tt>''filename.tar''</tt><br />
# Type <tt> 7z x ''filename.tar''</tt> at the command prompt (where <tt>''filename.tar''</tt> is the name of the tar file).<br />
<br />
Instead of using 7-Zip on the command line, you can use the file manager and click on a <tt>.tar</tt>, <tt>.tar.gz</tt>, or<tt>.tar.bz2</tt> file; 7-Zip will automatically start.<br />
<br />
= TarTool =<br />
<br />
A simple windows command line tool (no install , just unzip)<br />
<br />
Its hosted on codeplex [http://tartool.codeplex.com/ tartool], complete with the source code.<br />
<br />
#to decompress and untar .tar.gz (.tgz) files or<br />
#just untar .tar files<br />
<br />
>TarTool.exe<br />
<br />
Usage :<br />
<br />
>TarTool sourceFile destinationDirectory<br />
<br />
>TarTool D:\sample.tar.gz ./<br />
<br />
>TarTool sample.tgz temp<br />
<br />
>TarTool -x sample.tar temp<br />
<br />
TarTool 2.0 Beta supports bzip2 files such as tar.bz2 and .bz2 extraction.<br />
<br />
TarTool -xj sample.tar.bz2 temp<br />
or<br />
TarTool -j sample.bz2<br />
<br />
More details are on this post -- http://blog.rajasekharan.com/2009/01/16/tartool-windows-tar-gzip-tgz-extraction-tool/</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Stack&diff=63020Stack2019-08-28T13:57:07Z<p>Henk-Jan van Tuyl: /* Blog posts / Tutorials */ Changed link to a more up-to-date article</p>
<hr />
<div>{{Stub}}<br />
<br />
For the description of the common computer term <code>stack</code>, see the Wikipedia article [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Stack (abstract data type)] or [https://en.wikipedia.org/wiki/Call_stack Call stack].<br />
<br />
<br />
== Introduction ==<br />
<br />
Stack is a development tool for the entire Haskell development cycle, from installing the compiler and packages to testing and benchmarking software.<br />
<br />
== Blog posts / Tutorials ==<br />
<br />
* [https://duplode.github.io/posts/casual-hacking-with-stack-reloaded.html Casual Hacking With stack, Reloaded] - Explains how to start up a new package with Stack and what each file is for.<br />
<br />
== Important links ==<br />
<br />
* [https://docs.haskellstack.org/ The Haskell Tool Stack], the official Stack website.<br />
* [https://github.com/commercialhaskell/stack#readme The readme file]<br />
* [http://docs.haskellstack.org/en/stable/install_and_upgrade/ Download instructions]<br />
* [http://docs.haskellstack.org/en/stable/faq/ FAQ list]<br />
* [https://groups.google.com/forum/#!forum/haskell-stack The mailing list]<br />
* [https://github.com/commercialhaskell/stack The stack repository]<br />
<br />
== Other links ==<br />
<br />
* [https://www.fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack ANNOUNCING: first public beta of stack]<br />
* [https://www.fpcomplete.com/blog/2015/06/stack-0-1-release stack 0.1 released]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Windows&diff=63019Windows2019-08-28T13:55:37Z<p>Henk-Jan van Tuyl: /* Compilers/interpreters */ Added Stack</p>
<hr />
<div>== Quickstart on Windows 7 ==<br />
<br />
This page describes what you need to know to ''use'' Haskell on a Windows machine.<br />
See [https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Windows the GHC Trac Wiki] for what you need to know to ''build'' GHC on Windows.<br />
<br />
For a minimal setup [https://www.haskell.org/downloads/windows download the MinGHC package from haskell.org/downloads].<br />
<br />
This should install ghc, ghci, cabal, mingw and msys2 to "C:\Program Files\MinGHC-#.##.##" for the latest MinGHC version #, and add the correct programs to your path. <br />
<br />
=== Msys2 Shells and Building Hoogle ===<br />
<br />
If you launch <hask>msys2_shell.bat</hask> (as opposed to <hask>mingw32_shell.bat</hask> or <hask>mingw64_shell.bat</hask>) then make sure that the following environment variable is defined : <br />
<br />
* <hask>MSYSTEM=MINGW32</hask> or <hask>MSYSTEM=MINGW64</hask><br />
<br />
Then test by firing up either <hask>msys2_shell.bat</hask>, <hask>mingw32_shell.bat</hask>, or <hask>mingw64_shell.bat</hask> and then executing the following sequence of commands : <br />
<br />
* <hask><br />
mkdir test<br />
cd test<br />
cabal sandbox init<br />
cabal install hoogle<br />
</hask><br />
<br />
Note that the absence of the environment variables above will result in linker errors when building hoogle.<br />
<br />
== Editors ==<br />
<br />
* [http://www.e-texteditor.com/ E-Text Editor (TextMate for Windows)]<br />
* [http://www.textpad.com/ TextPad]<br />
* [http://ftp.gnu.org/gnu/emacs/windows/ Emacs], [http://www.vim.org/ Vi(m)], etc<br />
* [http://www.leksah.org/index.html Leksah]: Haskell IDE written in Haskell<br />
* [http://eclipsefp.sourceforge.net/ Eclipse]<br />
* [http://notepad-plus-plus.org/ Notepad++]<br />
* [http://www.sublimetext.com/ Sublime Text]<br />
* [http://www.pnotepad.org/ Programmer's Notepad]<br />
See also the [[Editors]] page<br />
<br />
== Compilers/interpreters ==<br />
<br />
* [[Stack]] &mdash; this is not a compiler, but will install [[GHC]] automatically.<br />
* [http://www.haskell.org/platform/ The Haskell Platform] is a combination of GHC and a set of blessed libraries<br />
* [[WinHugs]]<br />
* [[GHC]]: Special notes for Cygwin users - [http://www.haskell.org/ghc/docs/6.6/html/building/platforms.html] [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-cygwin.html]<br />
* [http://code.google.com/p/winghci/ WinGhci], a GUI for GHCi (included in the Haskell Platform)<br />
<br />
== Tools for compilation ==<br />
<br />
If you use [https://www.haskell.org/downloads/windows MinGHC], the necessary compilers and Unix tools for compilation (such as MSYS2, mingw, gcc / g++, etc.) are installed automatically.<br />
<br />
* As some of the packages contain Unix/Linux specific scripts/commands, you need [http://www.mingw.org/ MinGW] or [http://mingw-w64.org/doku.php Mingw-w64] (the 64 bit version of MinGW) and [http://www.mingw.org/wiki/msys MSYS] to simulate a Unix environment. In some cases you need [http://www.cygwin.com/ Cygwin] instead. If you use [http://code.google.com/p/msysgit/ msysgit] on Windows already, all you need to do is add MinGW to your path.<br />
<br />
* If you need to link to C-software, [http://en.wikipedia.org/wiki/Environment_variable#DOS.2C_OS.2F2_and_Windows_.28Command_Prompt.29 define environment variable] C_INCLUDE_PATH that lists the directories where the header files can be found, for example:<br />
Set C_INCLUDE_PATH=C:\usr\local\include;C:\usr\local\include\SDL<br />
:(It is advisable to use paths without spaces, because some scripts in the MinGW/MSYS environment have problems with spaces in paths.)<br><br />
:For linking the libraries, you need to define environment variable LIBRARY_PATH as well, listing the directories where .a and .lib files can be found. In case C++ software must be compiled, define CPLUS_INCLUDE_PATH to list the directories with C++ header files.<br />
<br />
* Packages are often delivered as a .tar or .tar.gz file, see [[How to unpack a tar file in Windows]]<br />
<br />
* In some cases, [http://sourceforge.net/projects/pkgconfiglite/files/latest/download pkg-config.exe] is needed for compiling C/C++ packages<br />
<br />
== Generating Dynamically Linked Libraries (DLL's) ==<br />
<br />
If you have GHC >= 7.0.1, see [http://www.haskell.org/ghc/docs/latest/html/users_guide/using-shared-libs.html Using shared libraries] and [http://www.haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html Building and using Win32 DLLs].<br />
<br />
=== Linking DLL's against C++ ===<br />
<br />
Recent improvements to GHC's handling of shared libraries make this fairly painless for simple projects. However, as of GHC 7.10.1, linking against C++ object files can break FFI symbol exports. To circumvent the issue, use dlltool.exe (in a similar process to building with < GHC 7.0.1). <br />
<br />
This process can be automated by combining GHC's ability to generate a makefile, dlltool.exe's ability to create a .def symbol export file from compiled object files, and [http://hackage.haskell.org/package/shake-0.15.4/docs/Development-Shake-Util.html#v:parseMakefile Shake's makefile parser]. <br />
<br />
First the makefile is created:<br />
ghc -M -dep-suffix . dep-makefile ./<make> MyMain.hs<br />
<br />
Then dlltool.exe extracts all exported symbols from the compiled object files (.o). <br />
<br />
dlltool.exe -z dll.def -D MyDll.dll --export-all-symbols hs/<file1>.o hs/<file2>.o ...<br />
<br />
Finally, a .dll can be output by including the .def file in the ghc command.<br />
<br />
ghc -static -shared -package base -package ... -o MyDll.dll cpp/<file.o> ... hs/<file1>.o hs/<file2>.o ... dll.def -lstdc++<br />
<br />
dlltool.exe is included in the MinGHC distribution of GHC. In 7.10.1, it is installed at "C:\Program Files\MinGHC-7.10.1\ghc-7.10.1\mingw\bin"<br />
<br />
A clumsy, but working [http://shakebuild.com/ Shake]file implementing this approach is available [https://gist.github.com/oconnore/7d874f23dc4a825f5bc4 here] for reference. <br />
<br />
=== Building DLL's with an older GHC ===<br />
<br />
To work with/produce DLL files with GHC < 7.0.1, you need dlltool.exe, from the [http://sourceforge.net/projects/mingw/files/ mingw-binutils] package and pexports.exe from the [http://sourceforge.net/projects/mingw/files/ mingw-utils] package. For more information see [http://www.cse.yorku.ca/tdb/_doc.php/userg/man/name/dlltool/section/1 the dlltool manual] and [http://www.willus.com/mingw/yongweiwu_stdcall.html Stdcall and DLL tools of MSVC and MinGW]<br />
<br />
== Libraries ==<br />
<br />
* GUI : [[wxHaskell]] - A binding of wxWidgets (formerly known as wxWindows) in Haskell. Note: see also [[wxHaskell/Windows]]<br />
<br />
* GUI : [[Gtk2Hs]] - A binding of GTK+ in Haskell. Note: this requires installing [http://www.gtk.org GTK+] on windows.<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Win32 Win32] - low levelish bindings to Windows API. Comes with GHC and non-minimal Hugs distribution. [https://github.com/haskell/win32 Win32 git repo]<br />
<br />
* [[HDBC-ODBC under Windows]] for database access.<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/winerror winerror]: Error handling for foreign calls to the Windows API<br />
<br />
== Special tips and tricks for Windows ==<br />
<br />
* If there are DLLs missing from your environment, you can find out which, using [http://cygwin.com/cygwin-ug-net/using-utils.html cygcheck] from the [http://www.cygwin.com/ Cygwin project]. Note, that you will get problems if you have both MinGW and Cygwin in your search path; it is best to specify the full path to cygcheck.exe, or copy cygcheck.exe to some location in the search path.<br />
: Another option is [http://www.dependencywalker.com/ Dependency Walker]; this tool can also be used to find out, in which DLL a crash occurs.<br />
<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2013-February/106436.html Terminal Win32/Building Haskeline/8.3 file issue] (Haskell-cafe)<br />
<br />
* darcs : http://wiki.darcs.net/WindowsConfiguration<br />
<br />
* Make sure your Haskell compiler (e.g. GHC) and tools are on your system path: http://www.computerhope.com/issues/ch000549.htm<br />
<br />
* Instead of using WinGHCi, one can also run GHCi in shell mode in Emacs &mdash; do 'M-x shell' in Emacs, then type 'ghci'.<br />
<br />
* GHCi on Cygwin: When running GHC under a Cygwin shell on Windows, Ctrl-C sometimes doesn't work. A workaround is to use the rlwrap program to invoke GHCi : In addition to proper Ctrl-C, you also get Emacs (or vi) key bindings and command history across sessions, which saves you a load of typing.<br />
<br />
* If a package depends (either directly or indirectly) on the <code>unix</code> package, you cannot compile it on Windows (except when using Cygwin).<br />
:A simple way to see, if a package X depends on <code>unix</code>, is giving the command:<br />
cabal install X --dry-run<br />
:This will list all packages that would be installed<br />
<br />
* If you are missing or need to distribute libraries with an application, the correct place to put them is *NOT* in \WINDOWS\System32 as once was the practice in the early days of Windows. All sane applications/installers keep their own private dependencies in the application directory. E.g., if the user has chosen to install your application to C:\Program Files\Foo then it is best to install any DLLs in the same location.<br />
<br />
* When compiling a program with GUI, use the compiler option -optl-mwindows to prevent a DOS-shell being displayed behind your GUI. (This passes the option -mwindows to the linker.)<br />
<br />
* Source files from Unix(-like) systems have lines terminated with Line Feed only; if your favorite editor cannot handle this, you can convert the files to MS-DOS format with the <code>unix2dos</code> command (from the [http://sourceforge.net/projects/mingw/files/ mingw-utils] package). For more information, give command: <code>unix2dos --help</code><br />
:Note, that GHC can handle source files in Unix format.<br />
<br />
* To convert a set of files to MS-DOS format (note: this might damage binary files):<br />
::<code>C:\MSYS\1.0\bin\find . -type f -exec unix2dos {} ;</code><br />
:Note: the <code>find</code> command included in MSYS is different from the MS-DOS <code>find</code> command, therefore, you need to specify the entire path to this command.<br />
<br />
== Binary downloads ==<br />
<br />
=== Haskell ===<br />
<br />
Below a list of binary packages for Windows. To be sure you get the most recent version of each, it is best to download the source from [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] and compile (except for the Haskell Platform).<br />
<br />
* [http://www.haskell.org/platform/windows.html The Haskell Platform] [[Haskell Platform | (HaskellWiki page)]], contains GHC and a set of libraries and tools <br />
* [https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-i386-unknown-mingw32.tar.xz GHC 7.8.3 for Windows x86], [https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-x86_64-unknown-mingw32.tar.xz GHC 7.8.3 for Windows 64 bit] [[GHC | (HaskellWiki page)]]<br />
* [http://leksah.org/download.html Leksah] [[Leksah | (HaskellWiki page)]]<br />
* [http://darcs.net/Binaries Darcs] [[Darcs | (HaskellWiki page)]]<br />
* [http://repetae.net/computer/haskell/DrIFT/drop/ Drift] [http://repetae.net/computer/haskell/DrIFT/ (website)] <br />
* [http://www.haskell.org/haddock/haddock-0.7-Win32.zip Haddock 0.7] (obsolete) [http://www.haskell.org/haddock/ (website)] <br />
* [http://www.haskell.org/happy/dist/1.13/happy-1-13.msi Happy 1.13] (obsolete) [http://www.haskell.org/happy/ (website)] <br />
* [ftp://ftp.cs.york.ac.uk/pub/haskell/contrib/hscolour-1.9.zip HsColour 1.9] [http://www.cs.york.ac.uk/fp/darcs/hscolour/ (website)] <br />
* [http://cvs.haskell.org/Hugs/pages/downloading.htm WinHugs September 2006] [http://www.haskell.org/hugs/ (website)] <br />
* [http://haskell.forkio.com/Home/curl-win32/curl-7.19.4-mingw32.zip?attredirects=0 cURL 7.19.4] [http://haskell.forkio.com/Home/curl-win32/ (website)]<br />
<br />
=== Development ===<br />
<br />
[https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Windows Setting up a Windows system for building GHC]<br />
<br />
== Shipping Installable Applications ==<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bamse bamse] lets you build windows installers for your Haskell app (MSI). N.B. <code>bamse</code> is not updated since 2009 and can not be compiled with recent compiler/packages; it depends on <code>com</code>, which also suffered bitrot.<br />
* [http://www.jrsoftware.org/isinfo.php Inno Setup] is another tool to create windows installers.<br />
* [http://wixtoolset.org/ WiX Toolset], builds Windows installation packages from XML source code<br />
* [http://zero-install.sourceforge.net/ Zero Install] creates packages for several platforms ("a decentralised cross-distribution software installation system")<br />
<br />
[[Category:OS]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Stack&diff=63018Stack2019-08-28T13:54:08Z<p>Henk-Jan van Tuyl: /* Important links */ Added link to ''The Haskell Tool Stack''</p>
<hr />
<div>{{Stub}}<br />
<br />
For the description of the common computer term <code>stack</code>, see the Wikipedia article [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Stack (abstract data type)] or [https://en.wikipedia.org/wiki/Call_stack Call stack].<br />
<br />
<br />
== Introduction ==<br />
<br />
Stack is a development tool for the entire Haskell development cycle, from installing the compiler and packages to testing and benchmarking software.<br />
<br />
== Blog posts / Tutorials ==<br />
<br />
* [https://duplode.github.io/posts/casual-hacking-with-stack.html Casual Hacking With stack] - Explains how to start up a new package with Stack and what each file is for.<br />
<br />
<br />
== Important links ==<br />
<br />
* [https://docs.haskellstack.org/ The Haskell Tool Stack], the official Stack website.<br />
* [https://github.com/commercialhaskell/stack#readme The readme file]<br />
* [http://docs.haskellstack.org/en/stable/install_and_upgrade/ Download instructions]<br />
* [http://docs.haskellstack.org/en/stable/faq/ FAQ list]<br />
* [https://groups.google.com/forum/#!forum/haskell-stack The mailing list]<br />
* [https://github.com/commercialhaskell/stack The stack repository]<br />
<br />
== Other links ==<br />
<br />
* [https://www.fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack ANNOUNCING: first public beta of stack]<br />
* [https://www.fpcomplete.com/blog/2015/06/stack-0-1-release stack 0.1 released]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Windows&diff=63017Windows2019-08-28T13:35:32Z<p>Henk-Jan van Tuyl: /* Compilers/interpreters */ Removed link to MinGHC</p>
<hr />
<div>== Quickstart on Windows 7 ==<br />
<br />
This page describes what you need to know to ''use'' Haskell on a Windows machine.<br />
See [https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Windows the GHC Trac Wiki] for what you need to know to ''build'' GHC on Windows.<br />
<br />
For a minimal setup [https://www.haskell.org/downloads/windows download the MinGHC package from haskell.org/downloads].<br />
<br />
This should install ghc, ghci, cabal, mingw and msys2 to "C:\Program Files\MinGHC-#.##.##" for the latest MinGHC version #, and add the correct programs to your path. <br />
<br />
=== Msys2 Shells and Building Hoogle ===<br />
<br />
If you launch <hask>msys2_shell.bat</hask> (as opposed to <hask>mingw32_shell.bat</hask> or <hask>mingw64_shell.bat</hask>) then make sure that the following environment variable is defined : <br />
<br />
* <hask>MSYSTEM=MINGW32</hask> or <hask>MSYSTEM=MINGW64</hask><br />
<br />
Then test by firing up either <hask>msys2_shell.bat</hask>, <hask>mingw32_shell.bat</hask>, or <hask>mingw64_shell.bat</hask> and then executing the following sequence of commands : <br />
<br />
* <hask><br />
mkdir test<br />
cd test<br />
cabal sandbox init<br />
cabal install hoogle<br />
</hask><br />
<br />
Note that the absence of the environment variables above will result in linker errors when building hoogle.<br />
<br />
== Editors ==<br />
<br />
* [http://www.e-texteditor.com/ E-Text Editor (TextMate for Windows)]<br />
* [http://www.textpad.com/ TextPad]<br />
* [http://ftp.gnu.org/gnu/emacs/windows/ Emacs], [http://www.vim.org/ Vi(m)], etc<br />
* [http://www.leksah.org/index.html Leksah]: Haskell IDE written in Haskell<br />
* [http://eclipsefp.sourceforge.net/ Eclipse]<br />
* [http://notepad-plus-plus.org/ Notepad++]<br />
* [http://www.sublimetext.com/ Sublime Text]<br />
* [http://www.pnotepad.org/ Programmer's Notepad]<br />
See also the [[Editors]] page<br />
<br />
== Compilers/interpreters ==<br />
<br />
* [http://www.haskell.org/platform/ The Haskell Platform] is a combination of GHC and a set of blessed libraries<br />
* [[WinHugs]]<br />
* [[GHC]]: Special notes for Cygwin users - [http://www.haskell.org/ghc/docs/6.6/html/building/platforms.html] [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-cygwin.html]<br />
* [http://code.google.com/p/winghci/ WinGhci], a GUI for GHCi (included in the Haskell Platform)<br />
<br />
== Tools for compilation ==<br />
<br />
If you use [https://www.haskell.org/downloads/windows MinGHC], the necessary compilers and Unix tools for compilation (such as MSYS2, mingw, gcc / g++, etc.) are installed automatically.<br />
<br />
* As some of the packages contain Unix/Linux specific scripts/commands, you need [http://www.mingw.org/ MinGW] or [http://mingw-w64.org/doku.php Mingw-w64] (the 64 bit version of MinGW) and [http://www.mingw.org/wiki/msys MSYS] to simulate a Unix environment. In some cases you need [http://www.cygwin.com/ Cygwin] instead. If you use [http://code.google.com/p/msysgit/ msysgit] on Windows already, all you need to do is add MinGW to your path.<br />
<br />
* If you need to link to C-software, [http://en.wikipedia.org/wiki/Environment_variable#DOS.2C_OS.2F2_and_Windows_.28Command_Prompt.29 define environment variable] C_INCLUDE_PATH that lists the directories where the header files can be found, for example:<br />
Set C_INCLUDE_PATH=C:\usr\local\include;C:\usr\local\include\SDL<br />
:(It is advisable to use paths without spaces, because some scripts in the MinGW/MSYS environment have problems with spaces in paths.)<br><br />
:For linking the libraries, you need to define environment variable LIBRARY_PATH as well, listing the directories where .a and .lib files can be found. In case C++ software must be compiled, define CPLUS_INCLUDE_PATH to list the directories with C++ header files.<br />
<br />
* Packages are often delivered as a .tar or .tar.gz file, see [[How to unpack a tar file in Windows]]<br />
<br />
* In some cases, [http://sourceforge.net/projects/pkgconfiglite/files/latest/download pkg-config.exe] is needed for compiling C/C++ packages<br />
<br />
== Generating Dynamically Linked Libraries (DLL's) ==<br />
<br />
If you have GHC >= 7.0.1, see [http://www.haskell.org/ghc/docs/latest/html/users_guide/using-shared-libs.html Using shared libraries] and [http://www.haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html Building and using Win32 DLLs].<br />
<br />
=== Linking DLL's against C++ ===<br />
<br />
Recent improvements to GHC's handling of shared libraries make this fairly painless for simple projects. However, as of GHC 7.10.1, linking against C++ object files can break FFI symbol exports. To circumvent the issue, use dlltool.exe (in a similar process to building with < GHC 7.0.1). <br />
<br />
This process can be automated by combining GHC's ability to generate a makefile, dlltool.exe's ability to create a .def symbol export file from compiled object files, and [http://hackage.haskell.org/package/shake-0.15.4/docs/Development-Shake-Util.html#v:parseMakefile Shake's makefile parser]. <br />
<br />
First the makefile is created:<br />
ghc -M -dep-suffix . dep-makefile ./<make> MyMain.hs<br />
<br />
Then dlltool.exe extracts all exported symbols from the compiled object files (.o). <br />
<br />
dlltool.exe -z dll.def -D MyDll.dll --export-all-symbols hs/<file1>.o hs/<file2>.o ...<br />
<br />
Finally, a .dll can be output by including the .def file in the ghc command.<br />
<br />
ghc -static -shared -package base -package ... -o MyDll.dll cpp/<file.o> ... hs/<file1>.o hs/<file2>.o ... dll.def -lstdc++<br />
<br />
dlltool.exe is included in the MinGHC distribution of GHC. In 7.10.1, it is installed at "C:\Program Files\MinGHC-7.10.1\ghc-7.10.1\mingw\bin"<br />
<br />
A clumsy, but working [http://shakebuild.com/ Shake]file implementing this approach is available [https://gist.github.com/oconnore/7d874f23dc4a825f5bc4 here] for reference. <br />
<br />
=== Building DLL's with an older GHC ===<br />
<br />
To work with/produce DLL files with GHC < 7.0.1, you need dlltool.exe, from the [http://sourceforge.net/projects/mingw/files/ mingw-binutils] package and pexports.exe from the [http://sourceforge.net/projects/mingw/files/ mingw-utils] package. For more information see [http://www.cse.yorku.ca/tdb/_doc.php/userg/man/name/dlltool/section/1 the dlltool manual] and [http://www.willus.com/mingw/yongweiwu_stdcall.html Stdcall and DLL tools of MSVC and MinGW]<br />
<br />
== Libraries ==<br />
<br />
* GUI : [[wxHaskell]] - A binding of wxWidgets (formerly known as wxWindows) in Haskell. Note: see also [[wxHaskell/Windows]]<br />
<br />
* GUI : [[Gtk2Hs]] - A binding of GTK+ in Haskell. Note: this requires installing [http://www.gtk.org GTK+] on windows.<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Win32 Win32] - low levelish bindings to Windows API. Comes with GHC and non-minimal Hugs distribution. [https://github.com/haskell/win32 Win32 git repo]<br />
<br />
* [[HDBC-ODBC under Windows]] for database access.<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/winerror winerror]: Error handling for foreign calls to the Windows API<br />
<br />
== Special tips and tricks for Windows ==<br />
<br />
* If there are DLLs missing from your environment, you can find out which, using [http://cygwin.com/cygwin-ug-net/using-utils.html cygcheck] from the [http://www.cygwin.com/ Cygwin project]. Note, that you will get problems if you have both MinGW and Cygwin in your search path; it is best to specify the full path to cygcheck.exe, or copy cygcheck.exe to some location in the search path.<br />
: Another option is [http://www.dependencywalker.com/ Dependency Walker]; this tool can also be used to find out, in which DLL a crash occurs.<br />
<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2013-February/106436.html Terminal Win32/Building Haskeline/8.3 file issue] (Haskell-cafe)<br />
<br />
* darcs : http://wiki.darcs.net/WindowsConfiguration<br />
<br />
* Make sure your Haskell compiler (e.g. GHC) and tools are on your system path: http://www.computerhope.com/issues/ch000549.htm<br />
<br />
* Instead of using WinGHCi, one can also run GHCi in shell mode in Emacs &mdash; do 'M-x shell' in Emacs, then type 'ghci'.<br />
<br />
* GHCi on Cygwin: When running GHC under a Cygwin shell on Windows, Ctrl-C sometimes doesn't work. A workaround is to use the rlwrap program to invoke GHCi : In addition to proper Ctrl-C, you also get Emacs (or vi) key bindings and command history across sessions, which saves you a load of typing.<br />
<br />
* If a package depends (either directly or indirectly) on the <code>unix</code> package, you cannot compile it on Windows (except when using Cygwin).<br />
:A simple way to see, if a package X depends on <code>unix</code>, is giving the command:<br />
cabal install X --dry-run<br />
:This will list all packages that would be installed<br />
<br />
* If you are missing or need to distribute libraries with an application, the correct place to put them is *NOT* in \WINDOWS\System32 as once was the practice in the early days of Windows. All sane applications/installers keep their own private dependencies in the application directory. E.g., if the user has chosen to install your application to C:\Program Files\Foo then it is best to install any DLLs in the same location.<br />
<br />
* When compiling a program with GUI, use the compiler option -optl-mwindows to prevent a DOS-shell being displayed behind your GUI. (This passes the option -mwindows to the linker.)<br />
<br />
* Source files from Unix(-like) systems have lines terminated with Line Feed only; if your favorite editor cannot handle this, you can convert the files to MS-DOS format with the <code>unix2dos</code> command (from the [http://sourceforge.net/projects/mingw/files/ mingw-utils] package). For more information, give command: <code>unix2dos --help</code><br />
:Note, that GHC can handle source files in Unix format.<br />
<br />
* To convert a set of files to MS-DOS format (note: this might damage binary files):<br />
::<code>C:\MSYS\1.0\bin\find . -type f -exec unix2dos {} ;</code><br />
:Note: the <code>find</code> command included in MSYS is different from the MS-DOS <code>find</code> command, therefore, you need to specify the entire path to this command.<br />
<br />
== Binary downloads ==<br />
<br />
=== Haskell ===<br />
<br />
Below a list of binary packages for Windows. To be sure you get the most recent version of each, it is best to download the source from [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] and compile (except for the Haskell Platform).<br />
<br />
* [http://www.haskell.org/platform/windows.html The Haskell Platform] [[Haskell Platform | (HaskellWiki page)]], contains GHC and a set of libraries and tools <br />
* [https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-i386-unknown-mingw32.tar.xz GHC 7.8.3 for Windows x86], [https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-x86_64-unknown-mingw32.tar.xz GHC 7.8.3 for Windows 64 bit] [[GHC | (HaskellWiki page)]]<br />
* [http://leksah.org/download.html Leksah] [[Leksah | (HaskellWiki page)]]<br />
* [http://darcs.net/Binaries Darcs] [[Darcs | (HaskellWiki page)]]<br />
* [http://repetae.net/computer/haskell/DrIFT/drop/ Drift] [http://repetae.net/computer/haskell/DrIFT/ (website)] <br />
* [http://www.haskell.org/haddock/haddock-0.7-Win32.zip Haddock 0.7] (obsolete) [http://www.haskell.org/haddock/ (website)] <br />
* [http://www.haskell.org/happy/dist/1.13/happy-1-13.msi Happy 1.13] (obsolete) [http://www.haskell.org/happy/ (website)] <br />
* [ftp://ftp.cs.york.ac.uk/pub/haskell/contrib/hscolour-1.9.zip HsColour 1.9] [http://www.cs.york.ac.uk/fp/darcs/hscolour/ (website)] <br />
* [http://cvs.haskell.org/Hugs/pages/downloading.htm WinHugs September 2006] [http://www.haskell.org/hugs/ (website)] <br />
* [http://haskell.forkio.com/Home/curl-win32/curl-7.19.4-mingw32.zip?attredirects=0 cURL 7.19.4] [http://haskell.forkio.com/Home/curl-win32/ (website)]<br />
<br />
=== Development ===<br />
<br />
[https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Windows Setting up a Windows system for building GHC]<br />
<br />
== Shipping Installable Applications ==<br />
<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bamse bamse] lets you build windows installers for your Haskell app (MSI). N.B. <code>bamse</code> is not updated since 2009 and can not be compiled with recent compiler/packages; it depends on <code>com</code>, which also suffered bitrot.<br />
* [http://www.jrsoftware.org/isinfo.php Inno Setup] is another tool to create windows installers.<br />
* [http://wixtoolset.org/ WiX Toolset], builds Windows installation packages from XML source code<br />
* [http://zero-install.sourceforge.net/ Zero Install] creates packages for several platforms ("a decentralised cross-distribution software installation system")<br />
<br />
[[Category:OS]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=MinGHC&diff=63016MinGHC2019-08-28T13:34:32Z<p>Henk-Jan van Tuyl: Removed stub template; added "MinGHC is no longer supported"; removed dead link to "Downloads for Windows"</p>
<hr />
<div><br />
'''MinGHC is no longer supported. Please use [[Stack]].'''<br />
<br />
== Introduction ==<br />
<br />
MinGHC is a minimal installer for GHC and cabal; MinGHC contains a minimum number of packages, to prevent [http://www.well-typed.com/blog/9/ version problems] when installing packages with [[cabal-install]]. For an installer with more packages, see the [[Haskell Platform]].<br />
<br />
<br />
== Links ==<br />
<br />
* [https://github.com/fpco/minghc Windows installer for GHC, including MSYS] (GitHub, including links to packages)<br />
<br />
<br />
[[Category:Packages]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=GHC&diff=62984GHC2019-08-04T13:01:12Z<p>Henk-Jan van Tuyl: /* Collaborative documentation */ Added link to ''A Guide to GHC's Extensions''</p>
<hr />
<div>The '''Glasgow Haskell Compiler''' is a state-of-the-art, open source compiler and interactive environment for the functional language Haskell.<br />
<br />
* [http://www.haskell.org/ghc/ The GHC Home Page]<br />
<br />
== Documentation ==<br />
<br />
The documentation below relates to ''using'' GHC. For documentation about GHC's internals and building GHC, head over to the [https://gitlab.haskell.org/ghc/ghc/wikis/index GHC Developer Wiki].<br />
<br />
These documents relate to the ''latest released'' version of GHC.<br />
For ''earlier released'' versions click the relevant version on the<br />
[http://www.haskell.org/ghc/download downloads page]. <br />
For release candidates, look at <br />
[http://downloads.haskell.org/~ghc/ the GHC download directory].<br />
<br />
; [http://www.haskell.org/ghc/docs/latest/html/users_guide/index.html The User's Guide]: The User's Guide has all you need to know about using GHC: command line options, language extensions, GHCi, etc.<br />
: Download: | [http://www.haskell.org/ghc/docs/latest/users_guide.html.tar.xz HTML.tar.xz] | [http://www.haskell.org/ghc/docs/latest/users_guide.pdf PDF] |<br />
<br />
; [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Standard Libraries]: Documentation for the libraries that come with GHC.<br />
: Download: | [http://www.haskell.org/ghc/docs/latest/libraries.html.tar.xz HTML.tar.xz]<br />
<br />
; [http://www.haskell.org/cabal/users-guide/ Cabal]: An infrastructure for building and distributing Haskell software.<br />
<br />
== Collaborative documentation ==<br />
<br />
GHC is a big system. We try to document the core functionality (above), but<br />
you can help by writing documentation yourself. This section collects<br />
documentation written in a collaborative way, by users and developers together.<br />
Please help by adding new sections, and by clarifying and improving existing ones.<br />
<br />
* Using GHC<br />
** [[How_to_write_a_Haskell_program|How to write a Haskell program]]<br />
** [[/FAQ|GHC FAQ]]<br />
** [[/Error messages|Error messages]]<br />
** [[Upgrading_packages|Guidelines for upgrading your GHC]]<br />
** [[/GHCi|Using GHCi]]<br />
** [[/GHCi debugger| The GHCi debugger]]<br />
** [[Cabal|Using Cabal]] (including with DLLs)<br />
** The [[Performance|Haskell Performance Resource]], for advice on improving the performance of your code<br />
** [[Mutually recursive modules]]<br />
** [[/Memory_Management| Memory management and garbage collection]]<br />
** [[/Memory Footprint|Memory footprint on the heap of common data-structures]]<br />
** [[Evaluation order and state tokens]]<br />
** [[Inlining and Specialisation]]<br />
* Platform related matters<br />
** [[GHC under WINE|Running GHC under Wine]]<br />
** [[Mac OS X]]<br />
** [[Windows]]<br />
*** [http://haskell.forkio.com/dotnet Using GHC with .NET]<br />
*** [http://haskell.forkio.com/gmpwindows Dynamically linking GMP on Windows]<br />
<br />
* GHC extensions<br />
** [https://limperg.de/ghc-extensions/ A Guide to GHC's Extensions]<br />
** [[/Type system|Type system extensions in GHC]]<br />
** [[/As a library|Using GHC as a library]]<br />
** [[/Concurrency|Concurrent programming in GHC]]<br />
** [https://ocharles.org.uk/blog/pages/2014-12-01-24-days-of-ghc-extensions.html 24 Days of GHC Extensions], a series of blog articles.<br />
** [[Template Haskell]] is a (GHC) extension to Haskell that adds compile-time metaprogramming facilities.<br />
** [[Quasiquotation]] allows the ability for user-definable parsers to provide new concrete syntax for any datatype.<br />
** [https://web.archive.org/web/20110429002539/http://www.cse.unsw.edu.au:80/~dons/hs-plugins/ Dynamically loaded Haskell modules]: Don Stewart's <tt>hs-plugins</tt> library (Web Archive)<br />
** [[/Using the FFI|Using the Foreign Function Interface]]<br />
** [[/GUI programming|GUI programming in GHC]]<br />
** [[/Using rules|Using RULES in GHC]]<br />
** [[GHC/Data Parallel Haskell|Data Parallel Haskell: using nested data parallelism in GHC]]<br />
** [[Roles]] are GHC's way of discerning the difference between compile-time type equality (created by type synonyms and type families) and runtime type equality (created by newtypes).<br />
<br />
* [[Correctness of short cut fusion]]<br />
<br />
== Development of GHC ==<br />
<br />
See the [http://gitlab.haskell.org/ghc/ghc/wikis/home GHC Developer Wiki]. The latest snapshot of the documentation for the next version can be found [http://haskell.org/ghc/dist/current/docs/ here].<br />
<br />
* [http://takenobu-hs.github.io/downloads/ghc_development_flow.pdf GHC development flow] ([https://github.com/takenobu-hs/ghc-development-flow GitHub])<br />
<br />
[[Category:Implementations]]<br />
[[Category:GHC]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Dependent_type&diff=62679Dependent type2018-12-22T11:37:31Z<p>Henk-Jan van Tuyl: /* Epigram */ Added the link to the Epigram site again</p>
<hr />
<div>__TOC__<br />
<br />
== The concept of dependent types ==<br />
<br />
=== General ===<br />
<br />
* [http://en.wikipedia.org/wiki/Dependent_types Wikipedia]<br />
* [http://www-sop.inria.fr/oasis/Caminha00/abstract.html Dependent Types in Programming] abstract in APPSEM'2000<br />
* [http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?] by Daniel Fridlender and Mia Indrika, 2001.<br />
<br />
<br />
=== Type theory ===<br />
<br />
Simon Thompson: [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ Type Theory and Functional Programming]. Section 6.3 deals with dependent types, but because of the strong emphasis on [http://en.wikipedia.org/wiki/Curry_Howard_isomorphism Curry-Howard isomorphism] and the connections between logic and programming,<br />
the book seemed cathartic for me even from its beginning.<br />
<br />
Another interesting approach to Curry-Howard isomorphism and the concept of dependent type: [http://www.cs.chalmers.se/~aarne/course-langtech/lectures/lang09.html Lecture 9. Semantics and pragmatics of text and dialogue] dicsusses these concepts in the context of linguistics. Written by [http://www.cs.chalmers.se/~aarne/ Arne Ranta], see also [[Libraries and tools/Linguistics#Other functional or Haskell-related approaches to linguistics|his online course and other linguistical materials on the Linguistics wikipage]].<br />
<br />
[http://lists.seas.upenn.edu/mailman/listinfo/types-list Types Forum]<br />
<br />
=== Illative combinatory logic ===<br />
<br />
To see how Illative [[Combinatory logic]] deals with dependent types, see combinator '''G''' described in [http://citeseer.ist.psu.edu/246934.html Systems of Illative Combinatory Logic complete for first-order propositional and predicate calculus] by Henk Barendregt, Martin Bunder, Wil Dekkers.<br />
It seems to me that the dependent type construct<br />
<math>\forall x : S \Rightarrow T</math><br />
of Epigram corresponds to<br />
<math>\mathbf G\;S\;(\lambda x . T)</math><br />
in Illative Combinatory Logic. I think e.g. the followings should correspond to each other:<br />
* <math>\mathrm{realNullvector} :\;\;\;\forall n: \mathrm{Nat} \Rightarrow \mathrm{RealVector}\;n</math><br />
* <math>\mathbf G\;\,\mathrm{Nat}\;\,\mathrm{RealVector}\;\,\mathrm{realNullvector}</math><br />
<br />
<br />
== Dependently typed languages ==<br />
<br />
=== Epigram ===<br />
<br />
[http://www.e-pig.org/ Epigram] is a full dependently typed programming language, see especially<br />
* [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.9718&rep=rep1&type=pdf Epigram Tutorial] by Conor McBride<br />
* and [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.8190&rep=rep1&type=pdf Why dependent types matter] by Thorsten Altenkirch, Conor McBride and James McKinna).<br />
<br />
Dependent types (of this language) also provide a not-forgetful concept of '''views''' (already mentioned in the Haskell [[Future of Haskell#Extensions of Haskell]];<br />
the connection between these concepts is described in p. 32 of Epigram Tutorial (section ''4.6 Patterns Forget; Matching Is Remembering'').<br />
<br />
See Epigram also as [[Libraries and tools/Theorem provers|theorem prover]].<br />
<br />
=== Agda ===<br />
<br />
[http://www.cs.chalmers.se/~ulfn/Agda/ Agda] is a system for incrementally developing proofs and programs. Agda is also a functional language with dependent types. This language is similar to Epigram but has a more Haskell-like syntax.<br />
<br />
People who are interested also in theorem proving may see the [[Libraries and tools/Theorem provers|theorem provers]] page.<br />
<br />
=== Idris ===<br />
<br />
[http://idris-lang.org/ Idris] is a general purpose pure functional programming language with dependent types, eager evaluation, and optional lazy evaluation via laziness annotations. It has a very Haskell-like syntax and is available on [http://hackage.haskell.org/package/idris Hackage].<br />
<br />
Idris is actively developed by [http://edwinb.wordpress.com/ Edwin Brady] at the [http://www.cs.st-andrews.ac.uk/ University of St. Andrews].<br />
<br />
=== Cayenne ===<br />
<br />
[https://en.wikipedia.org/wiki/Cayenne_(programming_language) Cayenne] is influenced also by [http://en.wikipedia.org/wiki/Constructive_type_theory constructive type theory]. The compiler can be found at [https://github.com/csgordon/cayenne GitHub]<br />
<br />
Dependent types make it possible not to have a separate module language and a core language. This idea may concern Haskell too, see [[First-class module]] page.<br />
<br />
Dependent types make it useful also as a [[Applications and libraries/Theorem provers|theorem prover]].<br />
<br />
== Dependent types in Haskell programming ==<br />
<br />
=== Lightweight Dependent Typing ===<br />
[http://okmij.org/ftp/Computation/lightweight-dependent-typing.html This web page] describes the lightweight approach<br />
and its applications, e.g., statically safe head/tail functions and<br />
the elimination<br />
of array bound check (even in such complex algorithms as Knuth-Morris-Pratt<br />
string search). The page also briefly describes `singleton types' (Hayashi and<br />
Xi).<br />
<br />
=== Library ===<br />
<br />
[http://www.cs.st-and.ac.uk/~eb/ivor.php Ivor] is type theory based theorem proving library -- written by [http://www.dcs.st-and.ac.uk/~eb/index.php Edwin Brady] (see also the author's homepage, there are a lot of materials concerning dependent type theory there).<br />
<br />
=== Proposals ===<br />
* Richard A. Eisenberg: [https://arxiv.org/pdf/1610.07978.pdf Dependent Types in Haskell: Theory and Practice]<br />
* John Hughes: <s> [http://www.coverproject.org/TalksUntilSpring2004/DependentTypesInHaskell.pdf Dependent Types in Haskell (some ideas)]</s> (404).<br />
<br />
=== Simulating them ===<br />
* [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.2636 Faking it: Simulating Dependent Types in Haskell], by Conor McBride<br />
* [https://web.archive.org/web/20060203083622/http://www.haskell.org:80/hawiki/SimulatingDependentTypes SimulatingDependentTypes] of HaWiki (Web Archive)<br />
* The [[Type#See also|''See also'' section of Type]] page contains links to many related idioms. Especially [[type arithmetic]] seems to me also a way yielding some tastes from dependent type theory.<br />
* On the usefulness of such idioms in practice, see HaskellDB's pages<br />
** [http://haskelldb.sourceforge.net/ updated] page (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
** which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ original] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Category:Theoretical foundations]]<br />
<br />
[[Category:Type-level programming]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Dependent_type&diff=62678Dependent type2018-12-22T11:34:05Z<p>Henk-Jan van Tuyl: /* Simulating them */ SimulatingDependentTypes now points the copy of the page on the Web Archive</p>
<hr />
<div>__TOC__<br />
<br />
== The concept of dependent types ==<br />
<br />
=== General ===<br />
<br />
* [http://en.wikipedia.org/wiki/Dependent_types Wikipedia]<br />
* [http://www-sop.inria.fr/oasis/Caminha00/abstract.html Dependent Types in Programming] abstract in APPSEM'2000<br />
* [http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?] by Daniel Fridlender and Mia Indrika, 2001.<br />
<br />
<br />
=== Type theory ===<br />
<br />
Simon Thompson: [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ Type Theory and Functional Programming]. Section 6.3 deals with dependent types, but because of the strong emphasis on [http://en.wikipedia.org/wiki/Curry_Howard_isomorphism Curry-Howard isomorphism] and the connections between logic and programming,<br />
the book seemed cathartic for me even from its beginning.<br />
<br />
Another interesting approach to Curry-Howard isomorphism and the concept of dependent type: [http://www.cs.chalmers.se/~aarne/course-langtech/lectures/lang09.html Lecture 9. Semantics and pragmatics of text and dialogue] dicsusses these concepts in the context of linguistics. Written by [http://www.cs.chalmers.se/~aarne/ Arne Ranta], see also [[Libraries and tools/Linguistics#Other functional or Haskell-related approaches to linguistics|his online course and other linguistical materials on the Linguistics wikipage]].<br />
<br />
[http://lists.seas.upenn.edu/mailman/listinfo/types-list Types Forum]<br />
<br />
=== Illative combinatory logic ===<br />
<br />
To see how Illative [[Combinatory logic]] deals with dependent types, see combinator '''G''' described in [http://citeseer.ist.psu.edu/246934.html Systems of Illative Combinatory Logic complete for first-order propositional and predicate calculus] by Henk Barendregt, Martin Bunder, Wil Dekkers.<br />
It seems to me that the dependent type construct<br />
<math>\forall x : S \Rightarrow T</math><br />
of Epigram corresponds to<br />
<math>\mathbf G\;S\;(\lambda x . T)</math><br />
in Illative Combinatory Logic. I think e.g. the followings should correspond to each other:<br />
* <math>\mathrm{realNullvector} :\;\;\;\forall n: \mathrm{Nat} \Rightarrow \mathrm{RealVector}\;n</math><br />
* <math>\mathbf G\;\,\mathrm{Nat}\;\,\mathrm{RealVector}\;\,\mathrm{realNullvector}</math><br />
<br />
<br />
== Dependently typed languages ==<br />
<br />
=== Epigram ===<br />
<br />
Epigram is a full dependently typed programming language, see especially<br />
* [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.9718&rep=rep1&type=pdf Epigram Tutorial] by Conor McBride<br />
* and [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.8190&rep=rep1&type=pdf Why dependent types matter] by Thorsten Altenkirch, Conor McBride and James McKinna).<br />
<br />
Dependent types (of this language) also provide a not-forgetful concept of '''views''' (already mentioned in the Haskell [[Future of Haskell#Extensions of Haskell]];<br />
the connection between these concepts is described in p. 32 of Epigram Tutorial (section ''4.6 Patterns Forget; Matching Is Remembering'').<br />
<br />
See Epigram also as [[Libraries and tools/Theorem provers|theorem prover]].<br />
<br />
=== Agda ===<br />
<br />
[http://www.cs.chalmers.se/~ulfn/Agda/ Agda] is a system for incrementally developing proofs and programs. Agda is also a functional language with dependent types. This language is similar to Epigram but has a more Haskell-like syntax.<br />
<br />
People who are interested also in theorem proving may see the [[Libraries and tools/Theorem provers|theorem provers]] page.<br />
<br />
=== Idris ===<br />
<br />
[http://idris-lang.org/ Idris] is a general purpose pure functional programming language with dependent types, eager evaluation, and optional lazy evaluation via laziness annotations. It has a very Haskell-like syntax and is available on [http://hackage.haskell.org/package/idris Hackage].<br />
<br />
Idris is actively developed by [http://edwinb.wordpress.com/ Edwin Brady] at the [http://www.cs.st-andrews.ac.uk/ University of St. Andrews].<br />
<br />
=== Cayenne ===<br />
<br />
[https://en.wikipedia.org/wiki/Cayenne_(programming_language) Cayenne] is influenced also by [http://en.wikipedia.org/wiki/Constructive_type_theory constructive type theory]. The compiler can be found at [https://github.com/csgordon/cayenne GitHub]<br />
<br />
Dependent types make it possible not to have a separate module language and a core language. This idea may concern Haskell too, see [[First-class module]] page.<br />
<br />
Dependent types make it useful also as a [[Applications and libraries/Theorem provers|theorem prover]].<br />
<br />
== Dependent types in Haskell programming ==<br />
<br />
=== Lightweight Dependent Typing ===<br />
[http://okmij.org/ftp/Computation/lightweight-dependent-typing.html This web page] describes the lightweight approach<br />
and its applications, e.g., statically safe head/tail functions and<br />
the elimination<br />
of array bound check (even in such complex algorithms as Knuth-Morris-Pratt<br />
string search). The page also briefly describes `singleton types' (Hayashi and<br />
Xi).<br />
<br />
=== Library ===<br />
<br />
[http://www.cs.st-and.ac.uk/~eb/ivor.php Ivor] is type theory based theorem proving library -- written by [http://www.dcs.st-and.ac.uk/~eb/index.php Edwin Brady] (see also the author's homepage, there are a lot of materials concerning dependent type theory there).<br />
<br />
=== Proposals ===<br />
* Richard A. Eisenberg: [https://arxiv.org/pdf/1610.07978.pdf Dependent Types in Haskell: Theory and Practice]<br />
* John Hughes: <s> [http://www.coverproject.org/TalksUntilSpring2004/DependentTypesInHaskell.pdf Dependent Types in Haskell (some ideas)]</s> (404).<br />
<br />
=== Simulating them ===<br />
* [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.2636 Faking it: Simulating Dependent Types in Haskell], by Conor McBride<br />
* [https://web.archive.org/web/20060203083622/http://www.haskell.org:80/hawiki/SimulatingDependentTypes SimulatingDependentTypes] of HaWiki (Web Archive)<br />
* The [[Type#See also|''See also'' section of Type]] page contains links to many related idioms. Especially [[type arithmetic]] seems to me also a way yielding some tastes from dependent type theory.<br />
* On the usefulness of such idioms in practice, see HaskellDB's pages<br />
** [http://haskelldb.sourceforge.net/ updated] page (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
** which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ original] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Category:Theoretical foundations]]<br />
<br />
[[Category:Type-level programming]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Dependent_type&diff=62677Dependent type2018-12-22T11:30:00Z<p>Henk-Jan van Tuyl: /* Proposals */ Added "Dependent Types in Haskell: Theory and Practice"</p>
<hr />
<div>__TOC__<br />
<br />
== The concept of dependent types ==<br />
<br />
=== General ===<br />
<br />
* [http://en.wikipedia.org/wiki/Dependent_types Wikipedia]<br />
* [http://www-sop.inria.fr/oasis/Caminha00/abstract.html Dependent Types in Programming] abstract in APPSEM'2000<br />
* [http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?] by Daniel Fridlender and Mia Indrika, 2001.<br />
<br />
<br />
=== Type theory ===<br />
<br />
Simon Thompson: [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ Type Theory and Functional Programming]. Section 6.3 deals with dependent types, but because of the strong emphasis on [http://en.wikipedia.org/wiki/Curry_Howard_isomorphism Curry-Howard isomorphism] and the connections between logic and programming,<br />
the book seemed cathartic for me even from its beginning.<br />
<br />
Another interesting approach to Curry-Howard isomorphism and the concept of dependent type: [http://www.cs.chalmers.se/~aarne/course-langtech/lectures/lang09.html Lecture 9. Semantics and pragmatics of text and dialogue] dicsusses these concepts in the context of linguistics. Written by [http://www.cs.chalmers.se/~aarne/ Arne Ranta], see also [[Libraries and tools/Linguistics#Other functional or Haskell-related approaches to linguistics|his online course and other linguistical materials on the Linguistics wikipage]].<br />
<br />
[http://lists.seas.upenn.edu/mailman/listinfo/types-list Types Forum]<br />
<br />
=== Illative combinatory logic ===<br />
<br />
To see how Illative [[Combinatory logic]] deals with dependent types, see combinator '''G''' described in [http://citeseer.ist.psu.edu/246934.html Systems of Illative Combinatory Logic complete for first-order propositional and predicate calculus] by Henk Barendregt, Martin Bunder, Wil Dekkers.<br />
It seems to me that the dependent type construct<br />
<math>\forall x : S \Rightarrow T</math><br />
of Epigram corresponds to<br />
<math>\mathbf G\;S\;(\lambda x . T)</math><br />
in Illative Combinatory Logic. I think e.g. the followings should correspond to each other:<br />
* <math>\mathrm{realNullvector} :\;\;\;\forall n: \mathrm{Nat} \Rightarrow \mathrm{RealVector}\;n</math><br />
* <math>\mathbf G\;\,\mathrm{Nat}\;\,\mathrm{RealVector}\;\,\mathrm{realNullvector}</math><br />
<br />
<br />
== Dependently typed languages ==<br />
<br />
=== Epigram ===<br />
<br />
Epigram is a full dependently typed programming language, see especially<br />
* [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.9718&rep=rep1&type=pdf Epigram Tutorial] by Conor McBride<br />
* and [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.8190&rep=rep1&type=pdf Why dependent types matter] by Thorsten Altenkirch, Conor McBride and James McKinna).<br />
<br />
Dependent types (of this language) also provide a not-forgetful concept of '''views''' (already mentioned in the Haskell [[Future of Haskell#Extensions of Haskell]];<br />
the connection between these concepts is described in p. 32 of Epigram Tutorial (section ''4.6 Patterns Forget; Matching Is Remembering'').<br />
<br />
See Epigram also as [[Libraries and tools/Theorem provers|theorem prover]].<br />
<br />
=== Agda ===<br />
<br />
[http://www.cs.chalmers.se/~ulfn/Agda/ Agda] is a system for incrementally developing proofs and programs. Agda is also a functional language with dependent types. This language is similar to Epigram but has a more Haskell-like syntax.<br />
<br />
People who are interested also in theorem proving may see the [[Libraries and tools/Theorem provers|theorem provers]] page.<br />
<br />
=== Idris ===<br />
<br />
[http://idris-lang.org/ Idris] is a general purpose pure functional programming language with dependent types, eager evaluation, and optional lazy evaluation via laziness annotations. It has a very Haskell-like syntax and is available on [http://hackage.haskell.org/package/idris Hackage].<br />
<br />
Idris is actively developed by [http://edwinb.wordpress.com/ Edwin Brady] at the [http://www.cs.st-andrews.ac.uk/ University of St. Andrews].<br />
<br />
=== Cayenne ===<br />
<br />
[https://en.wikipedia.org/wiki/Cayenne_(programming_language) Cayenne] is influenced also by [http://en.wikipedia.org/wiki/Constructive_type_theory constructive type theory]. The compiler can be found at [https://github.com/csgordon/cayenne GitHub]<br />
<br />
Dependent types make it possible not to have a separate module language and a core language. This idea may concern Haskell too, see [[First-class module]] page.<br />
<br />
Dependent types make it useful also as a [[Applications and libraries/Theorem provers|theorem prover]].<br />
<br />
== Dependent types in Haskell programming ==<br />
<br />
=== Lightweight Dependent Typing ===<br />
[http://okmij.org/ftp/Computation/lightweight-dependent-typing.html This web page] describes the lightweight approach<br />
and its applications, e.g., statically safe head/tail functions and<br />
the elimination<br />
of array bound check (even in such complex algorithms as Knuth-Morris-Pratt<br />
string search). The page also briefly describes `singleton types' (Hayashi and<br />
Xi).<br />
<br />
=== Library ===<br />
<br />
[http://www.cs.st-and.ac.uk/~eb/ivor.php Ivor] is type theory based theorem proving library -- written by [http://www.dcs.st-and.ac.uk/~eb/index.php Edwin Brady] (see also the author's homepage, there are a lot of materials concerning dependent type theory there).<br />
<br />
=== Proposals ===<br />
* Richard A. Eisenberg: [https://arxiv.org/pdf/1610.07978.pdf Dependent Types in Haskell: Theory and Practice]<br />
* John Hughes: <s> [http://www.coverproject.org/TalksUntilSpring2004/DependentTypesInHaskell.pdf Dependent Types in Haskell (some ideas)]</s> (404).<br />
<br />
=== Simulating them ===<br />
* [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.2636 Faking it: Simulating Dependent Types in Haskell], by Conor McBride<br />
* <s>[http://haskell.org/hawiki/SimulatingDependentTypes SimulatingDependentTypes] of HaWiki</s> (404 Error)<br />
* The [[Type#See also|''See also'' section of Type]] page contains links to many related idioms. Especially [[type arithmetic]] seems to me also a way yielding some tastes from dependent type theory.<br />
* On the usefulness of such idioms in practice, see HaskellDB's pages<br />
** [http://haskelldb.sourceforge.net/ updated] page (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
** which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ original] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Category:Theoretical foundations]]<br />
<br />
[[Category:Type-level programming]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Dependent_type&diff=62676Dependent type2018-12-22T11:04:11Z<p>Henk-Jan van Tuyl: /* Lightweight Dependent Typing */ Link updated</p>
<hr />
<div>__TOC__<br />
<br />
== The concept of dependent types ==<br />
<br />
=== General ===<br />
<br />
* [http://en.wikipedia.org/wiki/Dependent_types Wikipedia]<br />
* [http://www-sop.inria.fr/oasis/Caminha00/abstract.html Dependent Types in Programming] abstract in APPSEM'2000<br />
* [http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?] by Daniel Fridlender and Mia Indrika, 2001.<br />
<br />
<br />
=== Type theory ===<br />
<br />
Simon Thompson: [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ Type Theory and Functional Programming]. Section 6.3 deals with dependent types, but because of the strong emphasis on [http://en.wikipedia.org/wiki/Curry_Howard_isomorphism Curry-Howard isomorphism] and the connections between logic and programming,<br />
the book seemed cathartic for me even from its beginning.<br />
<br />
Another interesting approach to Curry-Howard isomorphism and the concept of dependent type: [http://www.cs.chalmers.se/~aarne/course-langtech/lectures/lang09.html Lecture 9. Semantics and pragmatics of text and dialogue] dicsusses these concepts in the context of linguistics. Written by [http://www.cs.chalmers.se/~aarne/ Arne Ranta], see also [[Libraries and tools/Linguistics#Other functional or Haskell-related approaches to linguistics|his online course and other linguistical materials on the Linguistics wikipage]].<br />
<br />
[http://lists.seas.upenn.edu/mailman/listinfo/types-list Types Forum]<br />
<br />
=== Illative combinatory logic ===<br />
<br />
To see how Illative [[Combinatory logic]] deals with dependent types, see combinator '''G''' described in [http://citeseer.ist.psu.edu/246934.html Systems of Illative Combinatory Logic complete for first-order propositional and predicate calculus] by Henk Barendregt, Martin Bunder, Wil Dekkers.<br />
It seems to me that the dependent type construct<br />
<math>\forall x : S \Rightarrow T</math><br />
of Epigram corresponds to<br />
<math>\mathbf G\;S\;(\lambda x . T)</math><br />
in Illative Combinatory Logic. I think e.g. the followings should correspond to each other:<br />
* <math>\mathrm{realNullvector} :\;\;\;\forall n: \mathrm{Nat} \Rightarrow \mathrm{RealVector}\;n</math><br />
* <math>\mathbf G\;\,\mathrm{Nat}\;\,\mathrm{RealVector}\;\,\mathrm{realNullvector}</math><br />
<br />
<br />
== Dependently typed languages ==<br />
<br />
=== Epigram ===<br />
<br />
Epigram is a full dependently typed programming language, see especially<br />
* [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.9718&rep=rep1&type=pdf Epigram Tutorial] by Conor McBride<br />
* and [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.8190&rep=rep1&type=pdf Why dependent types matter] by Thorsten Altenkirch, Conor McBride and James McKinna).<br />
<br />
Dependent types (of this language) also provide a not-forgetful concept of '''views''' (already mentioned in the Haskell [[Future of Haskell#Extensions of Haskell]];<br />
the connection between these concepts is described in p. 32 of Epigram Tutorial (section ''4.6 Patterns Forget; Matching Is Remembering'').<br />
<br />
See Epigram also as [[Libraries and tools/Theorem provers|theorem prover]].<br />
<br />
=== Agda ===<br />
<br />
[http://www.cs.chalmers.se/~ulfn/Agda/ Agda] is a system for incrementally developing proofs and programs. Agda is also a functional language with dependent types. This language is similar to Epigram but has a more Haskell-like syntax.<br />
<br />
People who are interested also in theorem proving may see the [[Libraries and tools/Theorem provers|theorem provers]] page.<br />
<br />
=== Idris ===<br />
<br />
[http://idris-lang.org/ Idris] is a general purpose pure functional programming language with dependent types, eager evaluation, and optional lazy evaluation via laziness annotations. It has a very Haskell-like syntax and is available on [http://hackage.haskell.org/package/idris Hackage].<br />
<br />
Idris is actively developed by [http://edwinb.wordpress.com/ Edwin Brady] at the [http://www.cs.st-andrews.ac.uk/ University of St. Andrews].<br />
<br />
=== Cayenne ===<br />
<br />
[https://en.wikipedia.org/wiki/Cayenne_(programming_language) Cayenne] is influenced also by [http://en.wikipedia.org/wiki/Constructive_type_theory constructive type theory]. The compiler can be found at [https://github.com/csgordon/cayenne GitHub]<br />
<br />
Dependent types make it possible not to have a separate module language and a core language. This idea may concern Haskell too, see [[First-class module]] page.<br />
<br />
Dependent types make it useful also as a [[Applications and libraries/Theorem provers|theorem prover]].<br />
<br />
== Dependent types in Haskell programming ==<br />
<br />
=== Lightweight Dependent Typing ===<br />
[http://okmij.org/ftp/Computation/lightweight-dependent-typing.html This web page] describes the lightweight approach<br />
and its applications, e.g., statically safe head/tail functions and<br />
the elimination<br />
of array bound check (even in such complex algorithms as Knuth-Morris-Pratt<br />
string search). The page also briefly describes `singleton types' (Hayashi and<br />
Xi).<br />
<br />
=== Library ===<br />
<br />
[http://www.cs.st-and.ac.uk/~eb/ivor.php Ivor] is type theory based theorem proving library -- written by [http://www.dcs.st-and.ac.uk/~eb/index.php Edwin Brady] (see also the author's homepage, there are a lot of materials concerning dependent type theory there).<br />
<br />
=== Proposals ===<br />
John Hughes: <s>[http://www.coverproject.org/TalksUntilSpring2004/DependentTypesInHaskell.pdf Dependent Types in Haskell (some ideas)]</s> (404).<br />
<br />
=== Simulating them ===<br />
* [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.2636 Faking it: Simulating Dependent Types in Haskell], by Conor McBride<br />
* <s>[http://haskell.org/hawiki/SimulatingDependentTypes SimulatingDependentTypes] of HaWiki</s> (404 Error)<br />
* The [[Type#See also|''See also'' section of Type]] page contains links to many related idioms. Especially [[type arithmetic]] seems to me also a way yielding some tastes from dependent type theory.<br />
* On the usefulness of such idioms in practice, see HaskellDB's pages<br />
** [http://haskelldb.sourceforge.net/ updated] page (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
** which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ original] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Category:Theoretical foundations]]<br />
<br />
[[Category:Type-level programming]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template:Main/Headlines&diff=62638Template:Main/Headlines2018-11-13T11:01:31Z<p>Henk-Jan van Tuyl: Added "GHC 8.6.2 is released"</p>
<hr />
<div><div class="subtitle">Headlines</div><br />
* ''2018:''<br />
** [https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.2-released GHC 8.6.2] is released<br />
** [https://ghc.haskell.org/trac/ghc/blog/ghc-8.6.1-released GHC 8.6.1] is released<br />
** [https://www.haskell.org/ghc/download_ghc_8_4_3.html GHC 8.4.3] is released<br />
** The '''[https://www.haskell.org/platform/ Haskell Platform 8.4.3]''' is [https://mail.haskell.org/pipermail/haskell-cafe/2018-June/129256.html announced] and ready for [https://downloads.haskell.org/~platform/8.4.3/ download]<br />
<br />
* ''2017:''<br />
** [https://www.haskell.org/ghc/ GHC 8.2.1] is released<br />
** The [https://www.haskell.org/platform/ Haskell Platform 8.2.1] is released<br />
<br />
* ''2016:''<br />
** [https://www.haskell.org/ghc/ GHC 8.0.1] is released<br />
<br />
* ''2015:''<br />
** [http://www.haskell.org/ghc/ GHC 7.10.1] is released<br />
<br />
* ''2014:''<br />
** [http://www.haskell.org/ghc/ GHC 7.8.4] is released<br />
** The '''[http://www.haskell.org/platform/ Haskell Platform 2014.2]''' has been [http://www.haskell.org/pipermail/haskell/2014-August/024284.html released]<br />
<br />
* ''2013:''<br />
** '''[http://hackage.haskell.org/ Hackage 2]''' is now live, powered by Haskell.<br />
** '''[https://www.fpcomplete.com/business/haskell-center/overview/ FP Haskell Center]''', the commercial in-browser IDE by FP Complete '''[https://www.fpcomplete.com/business/blog/fp-complete-launches-fp-haskell-center-the-worlds-1st-haskell-ide-and-deployment-platform/ has been released]'''.<br />
** '''[http://www.haskell.org/pipermail/haskell/2013-September/039154.html Cabal 1.18]''' has been released.<br />
** The '''[http://haskell.org/platform?2013.2 Haskell Platform 2013.2]''' is now available<br />
** '''[http://www.fpcomplete.com FP Complete]''' has compiled a short '''[https://docs.google.com/forms/d/1dZVuT_2-x2C515YeXnAzXwddIvftALwgSoz2NYjS4aE/viewform survey]''' to help build the Haskell user community.<br />
<br />
* ''2012:''<br />
** The '''[http://haskell.org/platform Haskell Platform 2012.4]''' is now available<br />
** [http://www.haskell.org/ghc/ GHC 7.6] is released<br />
** The '''[http://haskell.org/platform Haskell Platform 2012.2]''' is now available<br />
** [http://www.yesodweb.com/blog/2012/04/announcing-yesod-1-0 Yesod 1.0] is now available<br />
** [http://www.haskell.org/ghc/ GHC 7.4] is released<br />
** O'Reilly have announced a forthcoming book on [http://www.haskell.org/pipermail/haskell/2012-May/023328.html Parallel and Concurrent Haskell]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Headlines&diff=62637Headlines2018-11-13T11:00:10Z<p>Henk-Jan van Tuyl: Now points to Headlines</p>
<hr />
<div>#REDIRECT [[Template:Main/Headlines]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=WxHaskell/Linux&diff=62604WxHaskell/Linux2018-09-08T18:51:38Z<p>Henk-Jan van Tuyl: /* Sources */ Updated link to wxWidgets sources</p>
<hr />
<div>{{Template:Stub}}<br />
This page records some user experiences building wxHaskell on Linux. It should be fleshed out now that wxHaskell 0.12 has been released.<br />
<br />
==== Sources ====<br />
<br />
The sources for wxWidgets can be found at https://www.wxwidgets.org/downloads/ . To compile the source, see [http://wiki.wxwidgets.org/Compiling_and_getting_started Compiling and getting started].<br />
<br />
The sources of most recent release of wxHaskell can be downloaded with the command<br />
<pre><br />
cabal unpack wx wxcore wxdirect wxc<br />
</pre><br />
Sources from the repository can be downloaded with:<br />
<pre><br />
git clone git://github.com/wxHaskell/wxHaskell.git<br />
</pre><br />
or by clicking the button "download ZIP" on page http://www.github.com/wxHaskell/wxHaskell<br />
<br />
==== Debian and Ubuntu ====<br />
<br />
<code><br />
sudo apt-get install g++<br /><br />
sudo apt-get install libglu-dev<br /><br />
sudo apt-get install libwxgtk2.8-dev<br /> <!-- newer version needed --><br />
</code><br />
<br />
Debian has removed a dependency on gstreamer and gconf2.0 in their WxWidgets packages.<br />
<br />
This may be the cause of your error when building `wxcore` if the build fails when unable to find<br />
<br />
<code><br />
libwx_gtk2u_media<br />
</code><br />
<br />
Install the WxWidgets library as instructed in [http://codelite.org/LiteEditor/WxWidgets30Binaries#toc2 wxWidgets 3.0 (and 2.9) Packages and Repositories - Ubuntu and debian]<br />
<br />
==== [[Gentoo]] ====<br />
<code>emerge -a dev-haskell/wxhaskell</code><br />
<br />
==== Fedora Core 6 ====<br />
<br />
==== Arch Linux ====<br />
The PKGBUILD file for wxgtk-2.9 on AUR passes <code>--disable-compat28</code> to configure which breaks <code>wxc-0.90.0.3</code>. After removing that option, everything builds fine. (as of 2012-06-14)<br />
<br />
[[Category:wxHaskell|Linux]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template:Main/Events&diff=62603Template:Main/Events2018-09-06T13:38:11Z<p>Henk-Jan van Tuyl: Moved ZuriHac and BayHac to Recent Events</p>
<hr />
<div><!-- NOTE: When adding a new event, please also remove "Recent Events" older than 6 months. Please also keep this comment. --><br />
<div class="subtitle">Upcoming Events</div><br />
<br />
;[http://www.composeconference.org/2018-melbourne/ Compose :: Melbourne 2018]<br />
:August 27-28, 2018, Melbourne, Australia<br />
<br />
;[https://conf.researchr.org/home/icfp-2018 ICFP 2018]<br />
:September 23-29, 2018, St. Louis, Missouri, United States<br />
<br />
<br />
<div class="subtitle">Recent Events</div><br />
<br />
;[https://zurihac.info/ ZuriHac 2018]<br />
:June 8-10, 2018, Zurich, Switzerland<br />
<br />
;[https://wiki.haskell.org/BayHac2018 BayHac 2018]<br />
:April 27-29, 2018, San Francisco, California, USA<br />
<br />
;[https://mail.haskell.org/pipermail/haskell-cafe/2017-October/127949.html Dutch Functional Programming day 2018]<br />
:January 5, 2018, Apeldoorn, The Netherlands<br />
<br />
;[https://hal2017.softbase.org/ Haskell in Leipzig 2017]<br />
:October 26–28, 2017, Leipzig, Germany<br />
<br />
;[http://icfp17.sigplan.org/ ICFP 2017]<br />
:September 3-9, 2017, Oxford, England<br />
<br />
;[https://wiki.haskell.org/Budapest_Hackathon_2017 Budapest Haskell Hackathon 2017]<br />
:July 29-30, 2017, Budapest, Hungary</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Learning_Haskell&diff=62602Learning Haskell2018-08-27T00:00:40Z<p>Henk-Jan van Tuyl: /* Popular libraries */ Updated link</p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
This portal points to places where you can go if you want to learn Haskell. <br />
<br />
The [[Introduction|Introduction to Haskell]] on the Haskell website tells you what Haskell gives you: substantially increased programmer productivity, shorter, clearer, and more maintainable code, fewer errors, higher reliability, a smaller semantic gap between the programmer and the language, shorter lead times. There is an old but still relevant paper about [http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters] (PDF) by John Hughes. More recently, Sebastian Sylvan wrote an article about [[Why Haskell Matters]].<br />
<br />
Join the [http://www.reddit.com/r/haskell Haskell subreddit], where we do regular Q&A threads called [[Hask Anything]] (that's the archive).<br />
<br />
There is also a [http://www.haskell.org/haskellwiki/Comparison table comparing Haskell to other functional languages]. Many questions about functional programming are answered by the [http://www.cs.nott.ac.uk/~gmh//faq.html comp.lang.functional FAQ].<br />
<br />
You can ask questions to members of the Haskell community on mailing lists, IRC, or StackOverflow. We recommend installing the [http://www.haskell.org/platform/ Haskell Platform].<br />
<br />
== Training courses ==<br />
<br />
Short training courses aimed at existing programmers<br />
<br />
* [http://www.well-typed.com/services_training On-site and public training courses] by Well-Typed (2-day intro, 2-day advanced, custom on-site courses)<br />
* [http://www.nobleprog.co.uk/haskell/training Public training courses] by NobleProg and Nilcons<br />
* [http://www.cs.ox.ac.uk/softeng/subjects/FPR.html Software Engineering course on Functional Programming] at the University of Oxford (1-week course)<br />
* [https://www.utrechtsummerschool.nl/courses/science/intermediate-functional-programming Summerschool on Advanced Functional Programming] at Utrecht University (1-week course)<br />
<br />
== Material for self-study ==<br />
<br />
Below there are links to certain introductory material. If you want to dig deeper, see [[Books and tutorials]].<br />
<br />
=== Textbooks ===<br />
<br />
* [http://www.haskellbook.com/ Haskell Programming from first principles]<br />
* [http://www.cs.yale.edu/homes/hudak/SOE/ The Haskell School of Expression]<br />
* [http://www.haskellcraft.com/ Haskell: the Craft of Functional Programming]<br />
* [https://www.pearson.com/us/higher-education/program/Bird-Introduction-Functional-Programming-2nd-Edition/PGM144889.html Introduction to Functional Programming using Haskell]<br />
* [http://www.cambridge.org/us/knowledge/isbn/item1129654/Introduction%20to%20Functional%20Programming%20Systems%20Using%20Haskell/?site_locale=en_US An Introduction to Functional Programming Systems Using Haskell]<br />
* [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html Algorithms: A functional programming approach]<br />
* [http://homepages.cwi.nl/~jve/HR/ The Haskell Road to Logic, Maths, and Programming] (also freely [http://fldit-www.cs.uni-dortmund.de/~peter/PS07/HR.pdf available online]). <br />
* [http://www.cs.nott.ac.uk/~gmh/book.html Programming in Haskell]<br />
* [http://book.realworldhaskell.org/ Real World Haskell]<br />
* [http://learnyouahaskell.com Learn You a Haskell for Great Good!]<br />
* [http://happylearnhaskelltutorial.com Happy Learn Haskell Tutorial]<br />
<br />
=== Online tutorials ===<br />
<br />
* [[Meta-tutorial]]<br />
* [http://pluralsight.com/training/Courses/Find?highlight=true&searchTerm=haskell Haskell Fundamentals - get started and learn key concepts] at Pluralsight (2-part, 5 hour online course)<br />
* [http://en.wikibooks.org/wiki/Haskell Haskell Wikibook] A thorough textbook with a step-by-step beginners track assuming no programming background. Also includes many advanced concepts, and adaptations of "Yet Another Haskell Tutorial", "Write Yourself a Scheme in 48 Hours", and "All about monads".<br />
* [http://pub.hal3.name/daume02yaht.pdf YAHT - Yet Another Haskell Tutorial] (good tutorial available online)<br />
* [http://www.cs.ou.edu/~rlpage/fpclassCurrent/textbook/haskell.shtml Two dozen short lessons]<br />
* [http://www.haskell.org/tutorial/ A Gentle Introduction to Haskell] - classic text, but not so gentle really :D<br />
* [ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf Haskell-Tutorial]<br />
* [https://web.archive.org/web/20130515011818/lasche.codingcrew.de/kurse/haskell/hskurs_index.htm Online Haskell Course] (German)<br />
* [http://collection.openlibra.com.s3.amazonaws.com/pdf/haskell_tutorial_for_c_programmers_en.pdf Haskell tutorial for C Programmers]<br />
* [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!] Beautiful, illustrated Haskell tutorial for programmers with less of a functional programming background.<br />
* [http://happylearnhaskelltutorial.com/ Happy Learn Haskell Tutorial] Up to date complete beginner illustrated tutorial that uses many basic examples and exercises , going very slowly step by step.<br />
* [http://www.youtube.com/playlist?list=PL2672EBC57C1F5F9B Learning Haskell] Ongoing tutorial in the form of YouTube videos; updates slowly.<br />
*[https://stevekrouse.github.io/hs.js/ Pattern matching, first-class functions, and abstracting over recursion in Haskell], a simulation of the evaluation of map, foldr and foldl.<br />
* [https://www.schoolofhaskell.com/ School of Haskell]<br />
* [http://learn.hfm.io/ Learning Haskell] — a tutorial combining clear explanations, graphics programming, and hands-on screencasts to teach you the essential concepts of functional programming in Haskell.<br />
<br />
=== Advanced tutorials ===<br />
<br />
* [[Hitchhikers guide to Haskell]]<br />
* [http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours Write Yourself a Scheme in 48 Hours]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ Tackling the Awkward Squad] (on I/O, interfacing to C, concurrency and exceptions)<br />
<br />
=== Debugging/profiling/optimization ===<br />
<br />
=== Monads ===<br />
<br />
* [http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html You Could Have Invented Monads! (And Maybe You Already Have.)]<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Monads for Functional Programming]<br />
* [http://www.haskell.org/haskellwiki/All_About_Monads All about monads]<br />
* [[IO inside|IO inside: down the Rabbit Hole]]<br />
<br />
=== Type classes ===<br />
<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz The paper that for the first time introduced type classes and their implementation using dictionaries]<br />
* [[Research papers/Type systems#Type classes|More papers on the type classes]]<br />
<br />
=== Generic programming ===<br />
<br />
* [[Scrap your boilerplate]]<br />
<br />
=== Popular libraries ===<br />
<br />
* ByteStrings?<br />
* [https://web.archive.org/web/20140624104743/legacy.cs.uu.nl/daan/download/parsec/parsec.html Parsec, a fast combinator parser]<br />
* [[Modern array libraries]]<br />
* [http://www.haskell.org/haskellwiki/Gtk2Hs/Tutorials Gtk2Hs, the GUI library]<br />
* [https://ocharles.org.uk/blog/ 24 Days of Hackage] (blog posts about many popular libraries)<br />
<br />
=== Reference ===<br />
<br />
* The official language definition: [[Language and library specification]]<br />
* [http://www.letu.edu/people/jaytevis/Programming-Languages/Haskell/tourofprelude.html Tour of the Haskell Prelude]<br />
* [http://zvon.org/other/haskell/Outputglobal/index.html Haskell Reference]<br />
* Haskell [[Reference card]]<br />
* [http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions]<br />
* [http://www.cs.uu.nl/wiki/bin/view/Helium/ATourOfTheHeliumPrelude Tour of the Helium Prelude]<br />
* [http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/errors/allErrors.html Some common Hugs error messages]<br />
* [http://cheatsheet.codeslower.com/ The Haskell Cheatsheet] - A reference card and mini-tutorial in one.<br />
* A [http://www.haskell.org/haskellwiki/Category:Glossary Glossary] of common terminology.<br />
* [http://dev.stephendiehl.com/hask/#intro What I Wish I Knew When Learning Haskell] by Stephen Diehl<br />
<br />
=== Course material ===<br />
* [http://www.cse.chalmers.se/edu/course/TDA555/ Introduction to Functional Programming, Chalmers] (for beginners at programming)<br />
* [http://www.cse.chalmers.se/edu/course/TDA452/ Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/afp/ Advanced Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/pfp/ Parallel Functional Programming, Chalmers]<br />
* [http://www.shuklan.com/haskell Introduction to Haskell], University of Virginia CS 1501<br />
* [http://www.cs.caltech.edu/courses/cs11/material/haskell/index.html CS 11 Caltech]<br />
* [http://www.cs.uu.nl/docs/vakken/lfp/ Functional programming]: course notes ([http://www.staff.science.uu.nl/~fokke101/courses/fp-eng.pdf English], [http://www.staff.science.uu.nl/~fokke101/courses/fp-nl.pdf Dutch], [http://www.staff.science.uu.nl/~fokke101/courses/fp-sp.pdf Spanish]), slides in Dutch<br />
* [http://www.cse.unsw.edu.au/~cs1011/05s2/ CS1011]: Tutorials, lab exercises and solutions<br />
* Stanford - [http://www.scs.stanford.edu/11au-cs240h/ Functional Systems in Haskell]<br />
* [http://www.seas.upenn.edu/~cis194/spring13/lectures.html CIS 194 Introduction to Haskell], University of Pennsylvania<br />
<br />
== Trying Haskell online ==<br />
<br />
There are several websites where you can enter a Haskell program and run it. They are (in no particular order):<br />
* [https://cocalc.com/app CoCalc app], formerly SageMathCloud<br />
* [https://www.fpcomplete.com/school/using-fphc FP Haskell Center]<br />
* [http://tryhaskell.org/ Try Haskell]<br />
* [http://www.code.world/haskell CodeWorld]<br />
* [http://chrisuehlinger.com/LambdaBubblePop/ Bubble Pop!], the satisfaction of popping bubble wrap, combined with the satisfaction of really elegant functional programming!<br />
* [http://tryplayg.herokuapp.com/ Try Haste & HPlayground client-side framework]; the source code is on [https://github.com/agocorona/tryhplay GitHub]<br />
* [https://koding.com/ Koding] is a cloud based IDE which supports Haskell and several other languages. Free accounts allow one virtual machine.<br />
<br />
To create a browser based environment yourself:<br />
* [http://gibiansky.github.io/IHaskell/ IHaskell]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Learning_Haskell&diff=62601Learning Haskell2018-08-26T23:54:23Z<p>Henk-Jan van Tuyl: /* Online tutorials */ Updated link</p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
This portal points to places where you can go if you want to learn Haskell. <br />
<br />
The [[Introduction|Introduction to Haskell]] on the Haskell website tells you what Haskell gives you: substantially increased programmer productivity, shorter, clearer, and more maintainable code, fewer errors, higher reliability, a smaller semantic gap between the programmer and the language, shorter lead times. There is an old but still relevant paper about [http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters] (PDF) by John Hughes. More recently, Sebastian Sylvan wrote an article about [[Why Haskell Matters]].<br />
<br />
Join the [http://www.reddit.com/r/haskell Haskell subreddit], where we do regular Q&A threads called [[Hask Anything]] (that's the archive).<br />
<br />
There is also a [http://www.haskell.org/haskellwiki/Comparison table comparing Haskell to other functional languages]. Many questions about functional programming are answered by the [http://www.cs.nott.ac.uk/~gmh//faq.html comp.lang.functional FAQ].<br />
<br />
You can ask questions to members of the Haskell community on mailing lists, IRC, or StackOverflow. We recommend installing the [http://www.haskell.org/platform/ Haskell Platform].<br />
<br />
== Training courses ==<br />
<br />
Short training courses aimed at existing programmers<br />
<br />
* [http://www.well-typed.com/services_training On-site and public training courses] by Well-Typed (2-day intro, 2-day advanced, custom on-site courses)<br />
* [http://www.nobleprog.co.uk/haskell/training Public training courses] by NobleProg and Nilcons<br />
* [http://www.cs.ox.ac.uk/softeng/subjects/FPR.html Software Engineering course on Functional Programming] at the University of Oxford (1-week course)<br />
* [https://www.utrechtsummerschool.nl/courses/science/intermediate-functional-programming Summerschool on Advanced Functional Programming] at Utrecht University (1-week course)<br />
<br />
== Material for self-study ==<br />
<br />
Below there are links to certain introductory material. If you want to dig deeper, see [[Books and tutorials]].<br />
<br />
=== Textbooks ===<br />
<br />
* [http://www.haskellbook.com/ Haskell Programming from first principles]<br />
* [http://www.cs.yale.edu/homes/hudak/SOE/ The Haskell School of Expression]<br />
* [http://www.haskellcraft.com/ Haskell: the Craft of Functional Programming]<br />
* [https://www.pearson.com/us/higher-education/program/Bird-Introduction-Functional-Programming-2nd-Edition/PGM144889.html Introduction to Functional Programming using Haskell]<br />
* [http://www.cambridge.org/us/knowledge/isbn/item1129654/Introduction%20to%20Functional%20Programming%20Systems%20Using%20Haskell/?site_locale=en_US An Introduction to Functional Programming Systems Using Haskell]<br />
* [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html Algorithms: A functional programming approach]<br />
* [http://homepages.cwi.nl/~jve/HR/ The Haskell Road to Logic, Maths, and Programming] (also freely [http://fldit-www.cs.uni-dortmund.de/~peter/PS07/HR.pdf available online]). <br />
* [http://www.cs.nott.ac.uk/~gmh/book.html Programming in Haskell]<br />
* [http://book.realworldhaskell.org/ Real World Haskell]<br />
* [http://learnyouahaskell.com Learn You a Haskell for Great Good!]<br />
* [http://happylearnhaskelltutorial.com Happy Learn Haskell Tutorial]<br />
<br />
=== Online tutorials ===<br />
<br />
* [[Meta-tutorial]]<br />
* [http://pluralsight.com/training/Courses/Find?highlight=true&searchTerm=haskell Haskell Fundamentals - get started and learn key concepts] at Pluralsight (2-part, 5 hour online course)<br />
* [http://en.wikibooks.org/wiki/Haskell Haskell Wikibook] A thorough textbook with a step-by-step beginners track assuming no programming background. Also includes many advanced concepts, and adaptations of "Yet Another Haskell Tutorial", "Write Yourself a Scheme in 48 Hours", and "All about monads".<br />
* [http://pub.hal3.name/daume02yaht.pdf YAHT - Yet Another Haskell Tutorial] (good tutorial available online)<br />
* [http://www.cs.ou.edu/~rlpage/fpclassCurrent/textbook/haskell.shtml Two dozen short lessons]<br />
* [http://www.haskell.org/tutorial/ A Gentle Introduction to Haskell] - classic text, but not so gentle really :D<br />
* [ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf Haskell-Tutorial]<br />
* [https://web.archive.org/web/20130515011818/lasche.codingcrew.de/kurse/haskell/hskurs_index.htm Online Haskell Course] (German)<br />
* [http://collection.openlibra.com.s3.amazonaws.com/pdf/haskell_tutorial_for_c_programmers_en.pdf Haskell tutorial for C Programmers]<br />
* [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!] Beautiful, illustrated Haskell tutorial for programmers with less of a functional programming background.<br />
* [http://happylearnhaskelltutorial.com/ Happy Learn Haskell Tutorial] Up to date complete beginner illustrated tutorial that uses many basic examples and exercises , going very slowly step by step.<br />
* [http://www.youtube.com/playlist?list=PL2672EBC57C1F5F9B Learning Haskell] Ongoing tutorial in the form of YouTube videos; updates slowly.<br />
*[https://stevekrouse.github.io/hs.js/ Pattern matching, first-class functions, and abstracting over recursion in Haskell], a simulation of the evaluation of map, foldr and foldl.<br />
* [https://www.schoolofhaskell.com/ School of Haskell]<br />
* [http://learn.hfm.io/ Learning Haskell] — a tutorial combining clear explanations, graphics programming, and hands-on screencasts to teach you the essential concepts of functional programming in Haskell.<br />
<br />
=== Advanced tutorials ===<br />
<br />
* [[Hitchhikers guide to Haskell]]<br />
* [http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours Write Yourself a Scheme in 48 Hours]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ Tackling the Awkward Squad] (on I/O, interfacing to C, concurrency and exceptions)<br />
<br />
=== Debugging/profiling/optimization ===<br />
<br />
=== Monads ===<br />
<br />
* [http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html You Could Have Invented Monads! (And Maybe You Already Have.)]<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Monads for Functional Programming]<br />
* [http://www.haskell.org/haskellwiki/All_About_Monads All about monads]<br />
* [[IO inside|IO inside: down the Rabbit Hole]]<br />
<br />
=== Type classes ===<br />
<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz The paper that for the first time introduced type classes and their implementation using dictionaries]<br />
* [[Research papers/Type systems#Type classes|More papers on the type classes]]<br />
<br />
=== Generic programming ===<br />
<br />
* [[Scrap your boilerplate]]<br />
<br />
=== Popular libraries ===<br />
<br />
* ByteStrings?<br />
* [http://legacy.cs.uu.nl/daan/download/parsec/parsec.html Parsec, a fast combinator parser]<br />
* [[Modern array libraries]]<br />
* [http://www.haskell.org/haskellwiki/Gtk2Hs/Tutorials Gtk2Hs, the GUI library]<br />
* [https://ocharles.org.uk/blog/ 24 Days of Hackage] (blog posts about many popular libraries)<br />
<br />
=== Reference ===<br />
<br />
* The official language definition: [[Language and library specification]]<br />
* [http://www.letu.edu/people/jaytevis/Programming-Languages/Haskell/tourofprelude.html Tour of the Haskell Prelude]<br />
* [http://zvon.org/other/haskell/Outputglobal/index.html Haskell Reference]<br />
* Haskell [[Reference card]]<br />
* [http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions]<br />
* [http://www.cs.uu.nl/wiki/bin/view/Helium/ATourOfTheHeliumPrelude Tour of the Helium Prelude]<br />
* [http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/errors/allErrors.html Some common Hugs error messages]<br />
* [http://cheatsheet.codeslower.com/ The Haskell Cheatsheet] - A reference card and mini-tutorial in one.<br />
* A [http://www.haskell.org/haskellwiki/Category:Glossary Glossary] of common terminology.<br />
* [http://dev.stephendiehl.com/hask/#intro What I Wish I Knew When Learning Haskell] by Stephen Diehl<br />
<br />
=== Course material ===<br />
* [http://www.cse.chalmers.se/edu/course/TDA555/ Introduction to Functional Programming, Chalmers] (for beginners at programming)<br />
* [http://www.cse.chalmers.se/edu/course/TDA452/ Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/afp/ Advanced Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/pfp/ Parallel Functional Programming, Chalmers]<br />
* [http://www.shuklan.com/haskell Introduction to Haskell], University of Virginia CS 1501<br />
* [http://www.cs.caltech.edu/courses/cs11/material/haskell/index.html CS 11 Caltech]<br />
* [http://www.cs.uu.nl/docs/vakken/lfp/ Functional programming]: course notes ([http://www.staff.science.uu.nl/~fokke101/courses/fp-eng.pdf English], [http://www.staff.science.uu.nl/~fokke101/courses/fp-nl.pdf Dutch], [http://www.staff.science.uu.nl/~fokke101/courses/fp-sp.pdf Spanish]), slides in Dutch<br />
* [http://www.cse.unsw.edu.au/~cs1011/05s2/ CS1011]: Tutorials, lab exercises and solutions<br />
* Stanford - [http://www.scs.stanford.edu/11au-cs240h/ Functional Systems in Haskell]<br />
* [http://www.seas.upenn.edu/~cis194/spring13/lectures.html CIS 194 Introduction to Haskell], University of Pennsylvania<br />
<br />
== Trying Haskell online ==<br />
<br />
There are several websites where you can enter a Haskell program and run it. They are (in no particular order):<br />
* [https://cocalc.com/app CoCalc app], formerly SageMathCloud<br />
* [https://www.fpcomplete.com/school/using-fphc FP Haskell Center]<br />
* [http://tryhaskell.org/ Try Haskell]<br />
* [http://www.code.world/haskell CodeWorld]<br />
* [http://chrisuehlinger.com/LambdaBubblePop/ Bubble Pop!], the satisfaction of popping bubble wrap, combined with the satisfaction of really elegant functional programming!<br />
* [http://tryplayg.herokuapp.com/ Try Haste & HPlayground client-side framework]; the source code is on [https://github.com/agocorona/tryhplay GitHub]<br />
* [https://koding.com/ Koding] is a cloud based IDE which supports Haskell and several other languages. Free accounts allow one virtual machine.<br />
<br />
To create a browser based environment yourself:<br />
* [http://gibiansky.github.io/IHaskell/ IHaskell]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Learning_Haskell&diff=62600Learning Haskell2018-08-26T23:51:51Z<p>Henk-Jan van Tuyl: /* Training courses */ Updated Utrecht University course info</p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
This portal points to places where you can go if you want to learn Haskell. <br />
<br />
The [[Introduction|Introduction to Haskell]] on the Haskell website tells you what Haskell gives you: substantially increased programmer productivity, shorter, clearer, and more maintainable code, fewer errors, higher reliability, a smaller semantic gap between the programmer and the language, shorter lead times. There is an old but still relevant paper about [http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html Why Functional Programming Matters] (PDF) by John Hughes. More recently, Sebastian Sylvan wrote an article about [[Why Haskell Matters]].<br />
<br />
Join the [http://www.reddit.com/r/haskell Haskell subreddit], where we do regular Q&A threads called [[Hask Anything]] (that's the archive).<br />
<br />
There is also a [http://www.haskell.org/haskellwiki/Comparison table comparing Haskell to other functional languages]. Many questions about functional programming are answered by the [http://www.cs.nott.ac.uk/~gmh//faq.html comp.lang.functional FAQ].<br />
<br />
You can ask questions to members of the Haskell community on mailing lists, IRC, or StackOverflow. We recommend installing the [http://www.haskell.org/platform/ Haskell Platform].<br />
<br />
== Training courses ==<br />
<br />
Short training courses aimed at existing programmers<br />
<br />
* [http://www.well-typed.com/services_training On-site and public training courses] by Well-Typed (2-day intro, 2-day advanced, custom on-site courses)<br />
* [http://www.nobleprog.co.uk/haskell/training Public training courses] by NobleProg and Nilcons<br />
* [http://www.cs.ox.ac.uk/softeng/subjects/FPR.html Software Engineering course on Functional Programming] at the University of Oxford (1-week course)<br />
* [https://www.utrechtsummerschool.nl/courses/science/intermediate-functional-programming Summerschool on Advanced Functional Programming] at Utrecht University (1-week course)<br />
<br />
== Material for self-study ==<br />
<br />
Below there are links to certain introductory material. If you want to dig deeper, see [[Books and tutorials]].<br />
<br />
=== Textbooks ===<br />
<br />
* [http://www.haskellbook.com/ Haskell Programming from first principles]<br />
* [http://www.cs.yale.edu/homes/hudak/SOE/ The Haskell School of Expression]<br />
* [http://www.haskellcraft.com/ Haskell: the Craft of Functional Programming]<br />
* [https://www.pearson.com/us/higher-education/program/Bird-Introduction-Functional-Programming-2nd-Edition/PGM144889.html Introduction to Functional Programming using Haskell]<br />
* [http://www.cambridge.org/us/knowledge/isbn/item1129654/Introduction%20to%20Functional%20Programming%20Systems%20Using%20Haskell/?site_locale=en_US An Introduction to Functional Programming Systems Using Haskell]<br />
* [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html Algorithms: A functional programming approach]<br />
* [http://homepages.cwi.nl/~jve/HR/ The Haskell Road to Logic, Maths, and Programming] (also freely [http://fldit-www.cs.uni-dortmund.de/~peter/PS07/HR.pdf available online]). <br />
* [http://www.cs.nott.ac.uk/~gmh/book.html Programming in Haskell]<br />
* [http://book.realworldhaskell.org/ Real World Haskell]<br />
* [http://learnyouahaskell.com Learn You a Haskell for Great Good!]<br />
* [http://happylearnhaskelltutorial.com Happy Learn Haskell Tutorial]<br />
<br />
=== Online tutorials ===<br />
<br />
* [[Meta-tutorial]]<br />
* [http://pluralsight.com/training/Courses/Find?highlight=true&searchTerm=haskell Haskell Fundamentals - get started and learn key concepts] at Pluralsight (2-part, 5 hour online course)<br />
* [http://en.wikibooks.org/wiki/Haskell Haskell Wikibook] A thorough textbook with a step-by-step beginners track assuming no programming background. Also includes many advanced concepts, and adaptations of "Yet Another Haskell Tutorial", "Write Yourself a Scheme in 48 Hours", and "All about monads".<br />
* [http://pub.hal3.name/daume02yaht.pdf YAHT - Yet Another Haskell Tutorial] (good tutorial available online)<br />
* [http://www.cs.ou.edu/~rlpage/fpclassCurrent/textbook/haskell.shtml Two dozen short lessons]<br />
* [http://www.haskell.org/tutorial/ A Gentle Introduction to Haskell] - classic text, but not so gentle really :D<br />
* [ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf Haskell-Tutorial]<br />
* [http://lasche.codingcrew.de/kurse/haskell/hskurs_index.htm Online Haskell Course] (German)<br />
* [http://collection.openlibra.com.s3.amazonaws.com/pdf/haskell_tutorial_for_c_programmers_en.pdf Haskell tutorial for C Programmers]<br />
* [http://learnyouahaskell.com/ Learn You a Haskell for Great Good!] Beautiful, illustrated Haskell tutorial for programmers with less of a functional programming background.<br />
* [http://happylearnhaskelltutorial.com/ Happy Learn Haskell Tutorial] Up to date complete beginner illustrated tutorial that uses many basic examples and exercises , going very slowly step by step.<br />
* [http://www.youtube.com/playlist?list=PL2672EBC57C1F5F9B Learning Haskell] Ongoing tutorial in the form of YouTube videos; updates slowly.<br />
*[https://stevekrouse.github.io/hs.js/ Pattern matching, first-class functions, and abstracting over recursion in Haskell], a simulation of the evaluation of map, foldr and foldl.<br />
* [https://www.schoolofhaskell.com/ School of Haskell]<br />
* [http://learn.hfm.io/ Learning Haskell] — a tutorial combining clear explanations, graphics programming, and hands-on screencasts to teach you the essential concepts of functional programming in Haskell.<br />
<br />
=== Advanced tutorials ===<br />
<br />
* [[Hitchhikers guide to Haskell]]<br />
* [http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours Write Yourself a Scheme in 48 Hours]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ Tackling the Awkward Squad] (on I/O, interfacing to C, concurrency and exceptions)<br />
<br />
=== Debugging/profiling/optimization ===<br />
<br />
=== Monads ===<br />
<br />
* [http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html You Could Have Invented Monads! (And Maybe You Already Have.)]<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Monads for Functional Programming]<br />
* [http://www.haskell.org/haskellwiki/All_About_Monads All about monads]<br />
* [[IO inside|IO inside: down the Rabbit Hole]]<br />
<br />
=== Type classes ===<br />
<br />
* [http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz The paper that for the first time introduced type classes and their implementation using dictionaries]<br />
* [[Research papers/Type systems#Type classes|More papers on the type classes]]<br />
<br />
=== Generic programming ===<br />
<br />
* [[Scrap your boilerplate]]<br />
<br />
=== Popular libraries ===<br />
<br />
* ByteStrings?<br />
* [http://legacy.cs.uu.nl/daan/download/parsec/parsec.html Parsec, a fast combinator parser]<br />
* [[Modern array libraries]]<br />
* [http://www.haskell.org/haskellwiki/Gtk2Hs/Tutorials Gtk2Hs, the GUI library]<br />
* [https://ocharles.org.uk/blog/ 24 Days of Hackage] (blog posts about many popular libraries)<br />
<br />
=== Reference ===<br />
<br />
* The official language definition: [[Language and library specification]]<br />
* [http://www.letu.edu/people/jaytevis/Programming-Languages/Haskell/tourofprelude.html Tour of the Haskell Prelude]<br />
* [http://zvon.org/other/haskell/Outputglobal/index.html Haskell Reference]<br />
* Haskell [[Reference card]]<br />
* [http://members.chello.nl/hjgtuyl/tourdemonad.html A tour of the Haskell Monad functions]<br />
* [http://www.cs.uu.nl/wiki/bin/view/Helium/ATourOfTheHeliumPrelude Tour of the Helium Prelude]<br />
* [http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/errors/allErrors.html Some common Hugs error messages]<br />
* [http://cheatsheet.codeslower.com/ The Haskell Cheatsheet] - A reference card and mini-tutorial in one.<br />
* A [http://www.haskell.org/haskellwiki/Category:Glossary Glossary] of common terminology.<br />
* [http://dev.stephendiehl.com/hask/#intro What I Wish I Knew When Learning Haskell] by Stephen Diehl<br />
<br />
=== Course material ===<br />
* [http://www.cse.chalmers.se/edu/course/TDA555/ Introduction to Functional Programming, Chalmers] (for beginners at programming)<br />
* [http://www.cse.chalmers.se/edu/course/TDA452/ Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/afp/ Advanced Functional Programming, Chalmers]<br />
* [http://www.cse.chalmers.se/edu/course/pfp/ Parallel Functional Programming, Chalmers]<br />
* [http://www.shuklan.com/haskell Introduction to Haskell], University of Virginia CS 1501<br />
* [http://www.cs.caltech.edu/courses/cs11/material/haskell/index.html CS 11 Caltech]<br />
* [http://www.cs.uu.nl/docs/vakken/lfp/ Functional programming]: course notes ([http://www.staff.science.uu.nl/~fokke101/courses/fp-eng.pdf English], [http://www.staff.science.uu.nl/~fokke101/courses/fp-nl.pdf Dutch], [http://www.staff.science.uu.nl/~fokke101/courses/fp-sp.pdf Spanish]), slides in Dutch<br />
* [http://www.cse.unsw.edu.au/~cs1011/05s2/ CS1011]: Tutorials, lab exercises and solutions<br />
* Stanford - [http://www.scs.stanford.edu/11au-cs240h/ Functional Systems in Haskell]<br />
* [http://www.seas.upenn.edu/~cis194/spring13/lectures.html CIS 194 Introduction to Haskell], University of Pennsylvania<br />
<br />
== Trying Haskell online ==<br />
<br />
There are several websites where you can enter a Haskell program and run it. They are (in no particular order):<br />
* [https://cocalc.com/app CoCalc app], formerly SageMathCloud<br />
* [https://www.fpcomplete.com/school/using-fphc FP Haskell Center]<br />
* [http://tryhaskell.org/ Try Haskell]<br />
* [http://www.code.world/haskell CodeWorld]<br />
* [http://chrisuehlinger.com/LambdaBubblePop/ Bubble Pop!], the satisfaction of popping bubble wrap, combined with the satisfaction of really elegant functional programming!<br />
* [http://tryplayg.herokuapp.com/ Try Haste & HPlayground client-side framework]; the source code is on [https://github.com/agocorona/tryhplay GitHub]<br />
* [https://koding.com/ Koding] is a cloud based IDE which supports Haskell and several other languages. Free accounts allow one virtual machine.<br />
<br />
To create a browser based environment yourself:<br />
* [http://gibiansky.github.io/IHaskell/ IHaskell]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Introduction&diff=62599Introduction2018-08-26T23:47:52Z<p>Henk-Jan van Tuyl: /* Aren't functional programs very slow? */ Updated link and remark about relative speed</p>
<hr />
<div>[[Category:Tutorials]] [[Category:Language]]<br />
Haskell is a computer programming language. In particular, it is a<br />
'' [[Polymorphism|polymorphically]] [[typing|statically typed]], [[Lazy evaluation|lazy]], [[functional programming|purely functional]] '' language,<br />
quite different from most other programming languages. <br />
The language is named for [[Haskell Brooks Curry]], whose work in mathematical logic serves as a foundation for<br />
functional languages. <br />
Haskell is based on the ''[[lambda calculus]]'', hence the lambda we use as a logo.<br />
<br />
<br />
==Why use Haskell?==<br />
Writing large software systems that<br />
work is difficult and expensive. Maintaining those systems is even<br />
more difficult and expensive. Functional programming languages, such<br />
as Haskell, can make it easier and cheaper. For example, a new user who<br />
wrote a small relational DBMS in Haskell had this to say:<br />
<blockquote><br />
WOW! I basically wrote this without testing just thinking about my<br />
program in terms of transformations between types. I wrote the<br />
test/example code and had almost no implementation errors in the code! The<br />
compiler/type-system is really really good at preventing you from<br />
making coding mistakes! I've never in my life had a block of code<br />
this big work on the first try. I am WAY impressed.<br />
</blockquote><br />
Even if you are not in a position to use Haskell in your programming projects, learning Haskell can make you a better programmer in any language. <br />
<blockquote><br />
I learned Haskell a couple of years ago, having previously programmed in<br />
Python and (many) other languages. Recently, I've been using Python for a<br />
project (the choice being determined by both technical and non-technical<br />
issues), and find my Python programming style is now heavily influenced (for the better, I hope ;-) by my Haskell programming experience.<br><br><br />
Graham Klyne<br />
</blockquote><br />
<br />
<br />
Haskell offers you:<br />
<br />
*Substantially increased programmer productivity (Ericsson measured an improvement factor of between 9 and 25 using Erlang, a functional programming language similar to Haskell, in one set of experiments on telephony software).<br />
*Shorter, clearer, and more maintainable code.<br />
*Fewer errors, higher reliability.<br />
*A smaller &quot;semantic gap&quot; between the programmer and the language.<br />
*Shorter lead times.<br />
<br />
Haskell is a wide-spectrum language, suitable for a variety of<br />
applications. It is particularly suitable for programs which need to<br />
be highly modifiable and maintainable.<br />
<br />
Much of a software product's life is spent in ''specification'',<br />
''design'' and ''maintenance'', and not in ''programming''.<br />
Functional languages are superb for writing specifications which can<br />
actually be executed (and hence tested and debugged). Such a<br />
specification then ''is'' the first prototype of the final<br />
program.<br />
<br />
Functional programs are also relatively easy to maintain, because the<br />
code is shorter, clearer, and the rigorous control of side effects<br />
eliminates a huge class of unforeseen interactions.<br />
<br />
==What is functional programming?==<br />
C, Java, Pascal, Ada, and so on, are all ''imperative''<br />
languages. They are &quot;imperative&quot; in the sense that they<br />
consist of a sequence of commands, which are executed strictly one<br />
after the other. Haskell is a ''functional'' language. A<br />
functional program is a single expression, which is executed by<br />
evaluating the expression. <br />
<br />
Anyone who has used a spreadsheet has experience of functional<br />
programming. In a spreadsheet, one specifies the value of each cell<br />
in terms of the values of other cells. The focus is on ''what'' is<br />
to be computed, not ''how'' it should be computed. For<br />
example:<br />
*we do not specify the order in which the cells should be calculated -&nbsp;instead we take it for granted that the spreadsheet will compute cells in an order which respects their dependencies.<br />
*we do not tell the spreadsheet how to allocate its memory - rather, we expect it to present us with an apparently infinite plane of cells, and to allocate memory only to those cells which are actually in use.<br />
*for the most part, we specify the value of a cell by an ''expression'' (whose parts can be evaluated in any order), rather than by a ''sequence of commands '' which computes its value.<br />
<br />
An interesting consequence of the spreadsheet's unspecified order<br />
of re-calculation is that the notion of assignment is not very useful.<br />
After all, if you don't know exactly when an assignment will<br />
happen, you can't make much use of it! This contrasts strongly<br />
with programs in conventional languages like C, which consist<br />
essentially of a carefully-specified sequence of assignments, or Java,<br />
in which the ordering of method calls is crucial to the meaning of a<br />
program. <br />
<br />
This focus on the high-level &quot;what&quot; rather than the<br />
low-level &quot;how&quot; is a distinguishing characteristic of<br />
functional programming languages.<br />
<br />
Another well-known nearly-functional language is the standard database<br />
query language SQL. An SQL query is an expression involving<br />
projections, selections, joins and so forth. The query says what<br />
relation should be computed, without saying how it should be computed.<br />
Indeed, the query can be evaluated in any convenient order. SQL<br />
implementations often perform extensive query optimization which<br />
(among other things) figures out the best order in which to evaluate<br />
the expression.<br />
<br />
==What's good about functional programming?==<br />
<br />
Spreadsheets and SQL are both fairly specialized languages. Functional<br />
programming languages take the same ideas and move them into the realm<br />
of general-purpose programming. To get an idea of what a functional<br />
program is like, and the expressiveness of functional languages, look at<br />
the following quicksort programs. They both sort a sequence of numbers<br />
into ascending order using a standard method called "quicksort". The<br />
first program is written in Haskell and the second in C. <br />
<br />
Whereas the C program describes the particular steps the machine must<br />
make to perform a sort -- with most code dealing with the low-level<br />
details of data manipulation -- the Haskell program encodes the sorting<br />
algorithm at a much higher level, with improved brevity and clarity as<br />
a result (at the cost of efficiency unless compiled by a very smart compiler):<br />
<br />
===Quicksort in Haskell===<br />
<br />
The first thing to know about Haskell's syntax is that parentheses are used for grouping, and not for function application. The application of a function <hask>f</hask> to an argument <hask>x</hask> is written <hask>f x</hask>, not necessarily <hask>f(x)</hask>. It can be written as <hask>(f x)</hask> to separate it from its surroundings.<br />
<br />
<haskell><br />
quicksort :: Ord a => [a] -> [a]<br />
quicksort [] = []<br />
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)<br />
where<br />
lesser = filter (< p) xs<br />
greater = filter (>= p) xs<br />
<br />
</haskell><br />
The parentheses indicate the grouping of operands on the right-hand side of equations. On the left they indicate ''patterns'' of a function's argument(s). The parentheses around the two function calls <code>(quicksort lesser)</code> and <code>(quicksort greater)</code> are not necessary &ndash; because function application binds tighter than infix operators &ndash; and are there just for clarity.<br />
<br />
Here <code>[]</code> stands for empty list, <code>[p]</code> for a singleton list holding one element <code>p</code>, <code>++</code> is a built-in list concatenation operator, and the two <code>filter</code> calls use two on-the-fly built predicates, first for getting all the elements of <code>xs</code> that are smaller than the pivot element <code>p</code>, and the other - all those greater than, or equal to it.<br />
<br />
This definition uses Haskell's ability to define functions as equations with pattern-matching clauses: here the first one, with <code>[]</code> pattern for an empty list on its left-hand side, and the second, with <code>(p:xs)</code> pattern on its left-hand side standing for non-empty list with the head element <code>p</code> (used as a pivot element), and the tail <code>xs</code> (which is read, by convention, as ''axes'', suggesting that it is a list of several ''xs'', viz. elements ''"x"'').<br />
<br />
The very first line above is the function's ''type signature'': it says that <code>quicksort</code> transforms a list of elements of some type <code>a</code> (usually read "alpha") into a list of the same type, for a type <code>a</code> that is an instance of typeclass <hask>Ord</hask> (which means that comparison operations are defined for it, so elements of type <code>a</code> can be compared with one another).<br />
<br />
===Quicksort in C===<br />
<br />
True quicksort in C sorts in-place:<br />
<pre><br />
// To sort array a[] of size n: qsort(a,0,n-1)<br />
<br />
void qsort(int a[], int lo, int hi) <br />
{<br />
int h, l, p, t;<br />
<br />
if (lo &lt; hi) {<br />
l = lo;<br />
h = hi;<br />
p = a[hi];<br />
<br />
do {<br />
while ((l &lt; h) &amp;&amp; (a[l] &lt;= p)) <br />
l = l+1;<br />
while ((h &gt; l) &amp;&amp; (a[h] &gt;= p))<br />
h = h-1;<br />
if (l &lt; h) {<br />
t = a[l];<br />
a[l] = a[h];<br />
a[h] = t;<br />
}<br />
} while (l &lt; h);<br />
<br />
a[hi] = a[l];<br />
a[l] = p;<br />
<br />
qsort( a, lo, l-1 );<br />
qsort( a, l+1, hi );<br />
}<br />
}<br />
</pre><br />
<br />
A [[/Direct Translation | semi-direct translation]] of the C code is here.<br />
<br />
Let's examine some of the benefits of Haskell and functional programming.<br />
A more detailed case for functional programming can be found in <br />
<br />
<BLOCKQUOTE><br />
[http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf '''Why Functional Programming Matters'''] by [http://www.cse.chalmers.se/~rjmh/ John Hughes], The Computer<br />
Journal, Vol. 32, No. 2, 1989, pp. 98 - 107. Also in: David A. Turner<br />
(ed.): Research Topics in Functional Programming, Addison-Wesley,<br />
1990, pp. 17 - 42. <br />
</BLOCKQUOTE><br />
A slightly less formal essay inspired by the paper above can be found in<br />
<BLOCKQUOTE><br />
[[Why Haskell matters |'''Why Haskell Matters''']] originally by [mailto:sylvan@dtek.chalmers.se Sebastian Sylvan]<br />
</BLOCKQUOTE><br />
<br />
===Ease of understanding===<br />
Functional programs are often easier to '''understand''': it is usually possible to get their meaning at a glance. The same certainly cannot be said of the C program. It takes quite a while to understand, and even when you do understand it, it is extremely easy to make a small slip and end up with an incorrect program. <br />
<br />
Here is a detailed explanation of the Haskell quicksort:<br />
<br />
<haskell><br />
quicksort [] = []<br />
</haskell><br />
The first clause reads: "The result of sorting an empty list (<tt>[]</tt>) is just an empty list (<tt>[]</tt>)". <br />
<br />
<haskell><br />
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)<br />
where<br />
lesser = filter (< p) xs<br />
greater = filter (>= p) xs<br />
</haskell><br />
The second clause reads: "The result of sorting a non-empty list whose first element will be henceforth referred to as <tt>p</tt> and<br />
the rest of which will be referred to as <tt>xs</tt>, is a result of concatenating three sublists: first the result of sorting the elements of <tt>xs</tt> that are less than <tt>p</tt>, then <tt>p</tt> itself, and then the result of sorting the elements of <tt>xs</tt> that are greater than or equal to <tt>p</tt>."<br />
<br />
===Brevity===<br />
Functional programs tend to be much more '''concise''', shorter by a factor of two to ten usually, than their imperative counterparts. <br />
<br />
The above could be written even more concisely with the help of [[list comprehension]]s:<br />
<haskell><br />
qsort (p:xs) = qsort [x | x<-xs, x<p] ++ [p] ++ qsort [x | x<-xs, x>=p]<br />
</haskell><br />
<br />
The first sub-expression means, for <code>x</code> drawn from <code>xs</code> in order, such that <code>x < p</code>, collect <code>x</code>s in a list and call the <code>qsort</code> function with it, recursively. Similarly for the last one.<br />
<br />
===No core dumps===<br />
Most functional languages, and Haskell in particular, are '''strongly<br />
typed''', eliminating a huge class of easy-to-make errors at compile<br />
time. In particular, strong typing means '''no core dumps'''!<br />
There is simply no possibility of treating an integer as a pointer, or<br />
following a null pointer.<br />
<br />
===Code re-use===<br />
Of course, strong typing is available in many imperative languages, such as Ada or Pascal. However, Haskell's type system is much less restrictive than, say, Pascal's, because it uses '''[[polymorphism]]'''.<br />
<br />
For example, the qsort program given in Figure 1 will not only sort lists of integers, but also lists of floating point numbers, lists of characters, lists of lists; indeed, it will sort lists of ''anything'' for which it is meaningful to have "less-than" and "greater-than" operations. In contrast, the C version can only sort an array of integers, and nothing else.<br />
<br />
Polymorphism enhances re-usability.<br />
<br />
===Strong glue===<br />
"Non-strict" functional languages, such as Haskell, have another powerful feature: they<br />
only evaluate as much of the program as is required to get the answer<br />
- this is called [[Haskell/Lazy evaluation |'''lazy evaluation''']]. This feature is rather<br />
like Unix pipes. For example, the Unix command<br />
<pre><br />
grep printf Foo.c | wc<br />
</pre><br />
counts the number of lines in the file <tt> Foo.c </tt>that include the<br />
string <tt>printf</tt>.<br />
The command <br />
<pre><br />
grep printf Foo.c<br />
</pre><br />
produces all lines which contain the string &quot;<tt>printf</tt>&quot;,<br />
while the &quot;<tt>wc</tt>&quot; command counts them. The pipe,<br />
written &quot;<tt>|</tt>&quot;, takes the output from the first command<br />
and delivers it to the second. The two commands execute together, so<br />
that the output of the first is consumed more-or-less immediately by<br />
the second. In this way, no large intermediate files need be<br />
produced. You can think of <tt>wc</tt> &quot;demanding&quot;<br />
lines from the <tt>grep</tt>.<br />
<br />
If the second command only needs some of the output of the first, then<br />
execution of the first command might never need to be completed. For<br />
example,<br />
<br />
<pre><br />
grep printf Foo.c | head 5<br />
</pre><br />
just prints the first 5 lines which contain &quot;<tt>printf</tt>&quot;.<br />
There is no need to modify the <tt>grep</tt> command to take account of<br />
the fact that its execution might be abandoned.<br />
<br />
[[Lazy vs. non-strict |Non-strict]] languages provide exactly this kind of demand-driven<br />
evaluation. Data structures are evaluated just enough to deliver the<br />
answer, and parts of them may not be evaluated at all. As in the case<br />
of Unix commands, this provides powerful &quot;glue&quot; with which<br />
to compose existing programs together. What this means is that it is<br />
possible to '''re-use programs''', or pieces of programs, much more<br />
often than can be done in an imperative setting. [[Haskell/Lazy evaluation |Lazy evaluation]] allows us to write more '''[[modular programs]]'''.<br />
<br />
===Powerful abstractions===<br />
In general, functional languages offer powerful new ways to<br />
encapsulate '''abstractions'''. An abstraction allows you to define<br />
an object whose internal workings are hidden; a C procedure, for<br />
example, is an abstraction. Abstractions are ''the'' key to<br />
building modular, maintainable programs, so much so that a good<br />
question to ask of any new language is "what mechanisms for<br />
abstraction does it provide?". <br />
<br />
One powerful abstraction mechanism available in functional languages<br />
is the '''[[higher order function]]'''. In Haskell a function is a<br />
first-class citizen: it can freely be passed to other functions,<br />
returned as the result of a function, stored in a data structure, and<br />
so on. It turns out that the judicious use of higher order functions<br />
can substantially improve the structure and modularity of many<br />
programs.<br />
<br />
===Built-in memory management===<br />
Very many sophisticated programs need to allocate dynamic memory from a heap. In C this is done with a call to <tt> malloc</tt>, followed by code to initialize the store just allocated. The programmer is responsible for returning the store to the free pool when it isn't needed any more, a notorious source of "dangling-pointer" errors. To make matters worse, <tt>malloc</tt> is fairly expensive performance-wise, so programmers often <tt>malloc</tt> a single large chunk of store, and then allocate "by hand" out of this.<br />
<br />
Every functional language relieves the programmer of this storage management burden. Store is allocated and initialized implicitly, and recovered automatically by the garbage collector. The technology of storage allocation and garbage collection is now well developed, and the performance costs are rather slight.<br />
<br />
==When C is better==<br />
It isn't all roses, of course. The C quicksort uses an extremely<br />
ingenious technique, invented by Hoare, whereby it sorts the array<br />
''in place''; that is, without using any extra storage. As a<br />
result, it runs quickly, and in a small amount of memory. In<br />
contrast, the Haskell program allocates quite a lot of extra memory<br />
behind the scenes, and runs rather slower than the C program. <br />
<br />
In effect, the C quicksort does some very ingenious storage<br />
management, trading this algorithmic complexity for a reduction in<br />
run-time storage management costs.<br />
<br />
In applications where [[performance]] is required at any cost, or when the<br />
goal is detailed tuning of a low-level algorithm, an imperative<br />
language like C would probably be a better choice than Haskell,<br />
exactly because it provides more intimate control over the exact way<br />
in which the computation is carried out - that is, until sufficiently smart compiler appears that is able to derive the C equivalent from the Haskell one-liner, all by itself.<br />
<br />
===Functional vs imperative===<br />
But few programs require performance at any cost! After all, we all<br />
stopped writing assembly-language programs, except perhaps for key<br />
inner loops, long ago. The benefits of having a more supportive<br />
programming model (an arbitrary number of named, local variables<br />
instead of a fixed number of registers, for example) far outweigh the<br />
modest run-time costs.<br />
<br />
Similarly, we willingly accept the costs of a virtual memory paging<br />
system, in exchange for the more supportive programming model of an<br />
infinite virtual address space. The days of explicit memory overlays<br />
are over.<br />
<br />
Functional languages take another large step towards a higher-level<br />
programing model. Programs are easier to design, write and maintain,<br />
but the language offers the programmer less control over the machine.<br />
For most programs the result is perfectly acceptable.<br />
<br />
==What is Haskell?==<br />
Haskell is a modern, standard, non-strict, purely-functional<br />
programming language. It provides all the features sketched above,<br />
including polymorphic typing, lazy evaluation and higher-order<br />
functions. It also has an innovative type system which supports a<br />
systematic form of overloading and a module system.<br />
<br />
It is specifically designed to handle a wide range of applications,<br />
from numerical through to symbolic. To this end, Haskell has an<br />
expressive syntax, and a rich variety of built-in data types,<br />
including arbitrary-precision integers and rationals, as well as the<br />
more conventional integer, floating-point and boolean types.<br />
<br />
There are a number of [[implementations|compilers and interpreters]] available. All are<br />
free. The recommend way to install Haskell on your computer is through the the [http://hackage.haskell.org/platform/ Haskell Platform].<br />
<br />
See also the [[History of Haskell]].<br />
<br />
==Does anyone use functional programming?==<br />
Functional programming languages are used in substantial applications.<br />
For example:<br />
* Software AG, a major German software company, market an expert system (Natural Expert) which is programmed in a functional language. Their users find it easy to develop their applications in this language, through which they gain access to an underlying database system. It all runs on an IBM mainframe.<br />
*Ericsson have developed a new functional language, Erlang, to use in their future telephony applications. They have already written 130k-line Erlang applications, and find them very much shorter and faster to develop.<br />
*Amoco ran an experiment in which they re-coded in Miranda, a lazy functional language, a substantial fraction of their main oil-reservoir simulation code, a critical application. The resulting program was vastly shorter, and its production revealed a number of errors in the existing software. Amoco subsequently transcribed the functional program into C++ with encouraging results.<br />
*A researcher at the MITRE corporation is using Haskell to prototype his digital signal-processing applications.<br />
*Researchers at Durham University used Miranda, and later Haskell, in a seven-year project to build LOLITA, a 30,000-line program for natural-language understanding.<br />
*Query is the query language of the O2 object-oriented database system. O2Query is probably the most sophisticated commercially-available object-oriented database query language and it is a functional language.<br />
*ICAD Inc market a CAD system for mechanical and aeronautical engineers. The language in which the engineers describe their design is functional, and it uses lazy evaluation extensively to avoid recomputing parts of the design which are not currently visible on the screen. This results in substantial performance improvements.<br />
*An incestuous example: the Glasgow Haskell compiler is written in Haskell: a 100,000-line application.<br />
*[http://pugscode.org Pugs], which was the leading perl6 implementation, is written in Haskell<br />
*As is [http://darcs.net Darcs], a cutting edge distributed revision control system<br />
<br />
Some other examples of [[Haskell in practice]].<br />
<br />
Clifford Beshers, of [http://www.linspire.com/ Linspire Inc]., describes their experience with Haskell, and functional programming:<br />
<br />
<blockquote><br />
Linspire, Inc. has used functional programming since its inception in<br />
2001, beginning with extensive use of O'Caml, with a steady shift to<br />
Haskell as its implementations and libraries have matured. Hardware<br />
detection, software packaging and CGI web page generation are all areas<br />
where we have used functional programming extensively.<br />
</blockquote><br />
<br />
<blockquote><br />
Haskell's feature set lets us replace much of our use of little<br />
languages (e.g., bash or awk) and two-level languages (C or C++ bound to<br />
an interpreted language), allowing for faster development, better code<br />
sharing and ultimately faster implementations. Above all, we value<br />
static type checking for minimizing runtime errors in applications that<br />
run in unknown environments and for wrapping legacy programs in strongly<br />
typed functions to ensure that we pass valid arguments.<br />
</blockquote><br />
<br />
==Other frequently-asked questions==<br />
<br />
There is also a [[FAQ|larger FAQ]] in progress.<br />
<br />
===''Is functional programming hard to learn?''===<br />
<blockquote><br />
Functional programming does require a change in perspective, which<br />
some programmers find hard. But Ericsson's experience in training<br />
programmers in Erlang is that most find the transition easy -<br />
provided they take the training need seriously rather than assuming<br />
that they can "pick it up on the day".<br />
</blockquote><br />
===''Aren't functional programs very slow?''===<br />
<blockquote>They used to be, perhaps 20 years ago. But the compilers<br />
have long since caught up. Haskell programs run fast for all but the<br />
most performance-demanding applications. At the time of writing, Haskell<br />
compiled via GHC is doing quite well in the <br />
[https://benchmarksgame-team.pages.debian.net/benchmarksgame/ The Computer Language Benchmarks Game], with other functional languages also ranked highly.<br />
</blockquote><br />
<br />
===''I already have a large application in C or C++.''===<br />
Also worded as: ''Can I benefit from functional programming without rewriting my whole system?''<br />
<blockquote><br />
<br />
Haskell has been successfully integrated into existing applications in<br />
a number of ways. <br />
[http://www.haskell.org/hdirect/ HaskellDirect] is<br />
an IDL (Interface Description Language) based tool that allows Haskell<br />
programs to work with software components. Low level C/C++ interfaces<br />
can be generated with<br />
[http://hackage.haskell.org/package/greencard Green Card] or <br />
[http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ C->Haskell], allowing <br />
tight integration between Haskell and C. These tools have been used<br />
to build a large number of successful, mixed language systems.<br />
</blockquote><br />
<br />
==='' What libraries does Haskell support?''===<br />
<blockquote><br />
Many software libraries have been developed for Haskell. See the<br />
[[Libraries and tools| list of Haskell libraries]] for a list of much of<br />
what is available.<br />
<br />
</blockquote><br />
<br />
==='' What other software tools for Haskell are there? ''===<br />
<blockquote><br />
Glasgow Haskell comes with a profiler which allows you to find which<br />
parts of your program are consuming most time and space. Chalmers<br />
Haskell has a space-profiling tool, and a quasi-parallel simulator<br />
which allows you to experiment with running your program in<br />
parallel. Hugs also has some similar tools. For a complete list, check<br />
the [[Libraries and tools|tools page]].<br />
</blockquote><br />
<br />
===''How can I ask for help?''===<br />
There is a large community of Haskell users willing to help. They can be contacted on mailing lists, IRC, or Stack Overflow.<br />
<br />
===''Can I get a support contract or a help-line?''===<br />
<blockquote><br />
It used to be the case that if you wanted help, you had to persuade a<br />
Haskell research group that your problem was interesting enough or<br />
important enough that they should spend time helping you for free.<br />
<br><br />
Whilst that is still an option, there is now a<br />
[[Consultants|directory of Haskell Consultants]] who provide:<br />
<br />
*Support for compilers, tools and libraries.<br />
*Help with improving code quality (time, space, robustness, maintainability, etc.) using code reviews and tools.<br />
*Help with using libraries, tools and advanced Haskell features such as type system extensions, exception handling, the foreign function interface, test harnesses, and concurrency.<br />
*Library and application development.<br />
*Staff training.<br />
<br />
These companies and individuals tend to work closely with those<br />
developing Haskell (indeed, they have usually made major<br />
contributions to Haskell themselves). <br />
<br />
</blockquote><br />
===''How can I learn Haskell?''===<br />
<blockquote><br />
The easiest way to learn Haskell is with a [[Books|textbook]]. There are a lot of [[Tutorials|online tutorials]], but you'll have a much easier time to learn the basics from a book. After all, Haskell is very different from traditional mainstream languages, it's like learning programming anew.<br />
</blockquote><br />
<br />
===''Comparisons to other languages''===<br />
<blockquote><br />
[[Comparison of functional programming languages | Click to see a table comparing features of Haskell to similar languages]]<br />
</blockquote><br />
<br />
''Based on a paper by Simon Peyton Jones.''</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Foreign_Function_Interface&diff=62598Foreign Function Interface2018-08-26T22:48:36Z<p>Henk-Jan van Tuyl: /* Blog articles */ Updated link</p>
<hr />
<div>[[Category:FFI]]<br />
<br />
== Introduction ==<br />
<br />
The Foreign Function Interface (FFI) allows Haskell programs to cooperate with programs written with other languages. Haskell programs can call foreign functions and foreign functions can call Haskell code.<br />
<br />
Compared to many other languages, Haskell FFI is very easy to use: in the most common case, you only have to translate the prototype of the foreign function into the equivalent Haskell prototype and you're done. For instance, to call the exponential function ("exp") of the libc, you only have to translate its prototype:<br />
<br />
<source lang="c"><br />
double exp(double);<br />
</source><br />
<br />
into the following Haskell code<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
Now you can use the function "c_exp" just like any other Haskell function. When evaluated, it will call "exp".<br />
<br />
Similarly, to export the following Haskell function:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
</haskell><br />
<br />
so that it can be used in foreign codes, you only have to write:<br />
<br />
<haskell><br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
It can get at little more complicated depending on what you want to do, the function parameters, the foreign code you target, etc. This page is here to explain all of this to you.<br />
<br />
== Generalities ==<br />
<br />
=== FFI extension ===<br />
<br />
The Foreign Function Interface (FFI) is an extension to the Haskell standard. To use it, you need to enable it with the following compiler pragma at the beginning of your source file:<br />
<br />
<haskell><br />
{-# LANGUAGE ForeignFunctionInterface #-}<br />
</haskell><br />
<br />
=== Calling conventions ===<br />
<br />
When a program (in any language) is compiled into machine code, functions and procedures become labels: a label is a symbol (a string) associated to a position into the machine code. Calling a function only consists in putting parameters at appropriate places into memory and registers and then branching at the label position. The caller needs to know where to store parameters and the callee needs to know where to retrieve parameters from: there is a '''calling convention'''.<br />
<br />
To interact with foreign code, you need to know the calling conventions that are used by the other language implementation on the given architecture. It can also depend on the operating system.<br />
<br />
GHC supports standard calling conventions with the FFI: it can generate code to convert between its internal (non-standard) convention and the foreign one. If we consider the previous example:<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
we see that the C calling convention ("ccall") is used. GHC will generate code to put (and to retrieve) parameters into memory and registers conforming to what is expected by a code generated with a C compiler (or any other compiler conforming to this convention).<br />
<br />
Other available conventions supported by GHC include "stdcall" (i.e. Pascal convention).<br />
<br />
=== Foreign types ===<br />
<br />
Calling conventions depend on parameter types. For instance, floating-point values (Double, Float) may be passed into floating-point registers. Several values can be combined into a single vector register. And so on. As an example, in http://www.x86-64.org/documentation/abi.pdf you can find the algorithm describing how to pass parameters to functions on Linux on a x86-64 architecture depending on the types of the parameters.<br />
<br />
Only some Haskell types can be directly used as parameters for foreign functions, because they correspond to basic types of low-level languages such as C and are used to define calling conventions.<br />
<br />
According to [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2], the type of a foreign function is a ''foreign type'', that is a function type with zero or more arguments where:<br />
* the argument types can be ''marshallable foreign types'', i.e. Char, Int, Double, Float, Bool, Int8, Int16, Int32, Int64, Word8, Word16, Word32, Word64, Ptr a, FunPtr a, StablePtr a or a renaming of any of these using newtype.<br />
* the return type is either a ''marshallable foreign type'' or has the form IO t where t is a marshallable foreign type or ().<br />
<br />
'''Warning''': GHC does not support passing structures as values yet.<br />
<br />
The [http://hackage.haskell.org/package/base/docs/Foreign-C-Types.html Foreign.C.Types] module contains renaming of some of these ''marshallable foreign types'' with names closer to those of C types (e.g. CLong, CShort).<br />
<br />
If the foreign function performs side-effects, you have to explicitly indicate it in its type (using IO). GHC has no other way to detect it.<br />
<br />
<haskell><br />
foreign import ccall "my_func" myFunc :: Int -> IO Double<br />
</haskell><br />
<br />
Data structures have to passed by reference (using pointers). We will see how to use them later in this document.<br />
<br />
=== Exported functions ===<br />
<br />
GHC can generate wrappers so that a foreign code can call Haskell code:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
<br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
In the generated binary object, there will be a label "triple" that can be called from a language using the C convention.<br />
<br />
Note that to call a Haskell function, the runtime system must have been initialized with a call to "hs_init". It must be released with a call to "hs_exit" when it is no longer required.<br />
<br />
See the [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html user guide] for more details.<br />
<br />
== Function pointers ==<br />
<br />
Sometimes you want to manipulate foreign pointers to foreign functions: these are [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 FunPtr] in Haskell.<br />
<br />
You can get a function pointer by using "&" before a foreign function symbol:<br />
<haskell><br />
foreign import ccall "&exp" a_exp :: FunPtr (Double -> Double)<br />
</haskell><br />
<br />
Some foreign functions can also return function pointers.<br />
<br />
To call a function pointer from Haskell, GHC needs to convert between its own calling convention and the one expected by the foreign code. To create a function doing this conversion, you must use "dynamic" wrappers:<br />
<br />
<haskell><br />
foreign import ccall "dynamic" mkFun :: FunPtr (Double -> Double) -> (Double -> Double)<br />
</haskell><br />
<br />
Then you can apply this wrapper to a FunPtr to get a Haskell function:<br />
<br />
<haskell><br />
c_exp :: Double -> Double<br />
c_exp = mkFun a_exp<br />
</haskell><br />
<br />
You can also perform the opposite operation to give to the foreign code a pointer to a Haskell function. You need a "wrapper" wrapper. GHC generates the callable code to execute the wrapped Haskell closure with the appropriate calling convention and returns a pointer (FunPtr) on it. You have to release the generated code explicitly with `freeHaskellFunPtr` to avoid memory leaks: GHC has no way to know if the function pointer is still referenced in some foreign code, hence it doesn't collect it.<br />
<br />
<haskell><br />
add :: Int -> Int<br />
add = x+y<br />
<br />
foreign import ccall "wrapper" createAddPtr :: (Int -> Int) -> IO (FunPtr (Int -> Int))<br />
<br />
main = do<br />
addPtr <- createAddPtr add<br />
-- you can use addPtr like any other FunPtr (e.g. give it to foreign code)<br />
...<br />
-- you MUST free the FunPtr, otherwise it won't be collected<br />
freeHaskellFunPtr addPtr<br />
</haskell><br />
<br />
== Marshalling data ==<br />
<br />
In Haskell we are accustomed to let the runtime system -- especially the garbage collector -- manage memory. When we use the FFI, however, we sometimes need to do some manual memory management to comply with the data representations of the foreign codes. Hopefully, Haskell makes it very easy to manipulate low-level objects such as pointers. Moreover, many useful Haskell tools have been designed to simplify conversions between data representations.<br />
<br />
=== Pointers ===<br />
<br />
A pointer is an offset in memory. In Haskell, it is represented with the [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html Ptr a] data type. Where "a" is a phantom type that can be used to differentiate two pointers. You can think of "Ptr Stuff" as being equivalent to a "Stuff *" type in C (i.e. a pointer to a "Stuff" data). This analogy may not hold if "a" is a Haskell type not representable in the foreign language. For instance, you can have a pointer with the type "Ptr (Stuff -> OtherStuff)" but it is not function pointer in the foreign language: it is just a pointer tagged with the "Stuff -> OtherStuff" type.<br />
<br />
You can easily cast between pointer types using `castPtr` or perform pointer arithmetic using `plusPtr`, `minusPtr` and `alignPtr`. NULL pointer is represented with `nullPtr`.<br />
<br />
=== Memory allocation ===<br />
<br />
There are basically two ways to allocate memory:<br />
* on the Haskell heap, using `alloca*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
The allocation is ephemeral: it lasts the time of the execution of an IO action, as in the following example:<br />
<haskell><br />
do<br />
allocaBytes 128 $ \ptr -> do<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
-- do not return "ptr" in any way because it will become an invalid pointer<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
* on the "low-level" heap (the same as the runtime system uses), using `malloc*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
Allocations on the low-level heap are not managed by the Haskell implementation and must be freed explicitly with `free`.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
free ptr<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
=== Foreign Pointers ===<br />
<br />
An hybrid approach is to use [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr ForeignPtr]. Foreign pointers are similar to Ptr except that they have finalizers (i.e. actions) attached to them. When the garbage collector detects that a ForeignPtr is no longer accessible, it executes its associated finalizers. A basic finalizer is `finalizerFree` [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html] that calls `free` on the pointer.<br />
<br />
You can convert a Ptr into a ForeignPtr using `newForeignPtr`, add additional finalizers, etc. [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr].<br />
<br />
In the following example, we use `mallocForeignPtrBytes`. It is equivalent to call `malloc` and then to associate the `finalizerFree` finalizer with `newForeignPtr`. GHC has optimized implementations for `mallocForeignPtr*` functions, hence they should be preferred.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocForeignPtrBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
--<br />
-- ptr is freed when it is collected<br />
</haskell><br />
<br />
=== Using pointers: Storable instances ===<br />
<br />
You often want to read or to write at the address a of pointer. Reading consists in obtaining a Haskell value from a pointer; writing consists in somehow writing a representation of the Haskell value at the pointed address. Writing and reading a value depends on the type of the value, hence these methods are encapsulated into the [https://hackage.haskell.org/package/base/docs/Foreign-Storable.html Storable] type class.<br />
<br />
For any type T such that it exists a Storable T instance:<br />
* you can read a value, using <haskell>peek :: Ptr T -> IO T</haskell><br />
* you can write a value, using <haskell>poke :: Ptr T -> T -> IO ()</haskell><br />
<br />
`Storable a` also defines a `sizeOf :: a -> Int` method that returns the size of the stored value in bytes.<br />
<br />
All the ''marshallable foreign types'' (i.e. basic types) have Storable instances. Hence we can use these to write new Storable instances for more involved data types. In the following example, we create a Storable instance for a Complex data type:<br />
<br />
<haskell><br />
data Complex = Complex Double Double<br />
<br />
instance Storable Complex where<br />
sizeOf _ = 2 * sizeOf (undefined :: Double) -- stored complex size = 2 * size of a stored Double<br />
peek ptr = do<br />
real <- peek ptr<br />
img <- peekByteOff ptr (sizeOf real) -- we skip the bytes containing the real part<br />
return $ Complex real img<br />
poke ptr (Complex real img) = do<br />
poke ptr real<br />
pokeByteOff ptr (sizeOf real) img<br />
...<br />
</haskell><br />
<br />
This is not very complicated but it can become very cumbersome if our data type has many fields. Several tools have been developed to automatically or semi-automatically create the Storable instances.<br />
<br />
==== Renaming and Storable instances ====<br />
<br />
It is very common to use type renaming (i.e. newtype) to wrap a data type as in the following example, where we declare a type Pair that contains a pair of Double values just like our Complex type.<br />
<br />
<haskell><br />
newtype Pair = Pair Complex<br />
</haskell><br />
<br />
If we want to store Pair values exactly like Complex values, we have several possibilities:<br />
* unwrap the Complex value each time we want to use its Storable instance<br />
* create a new Storable Pair instance that does the same thing<br />
* automatically derive the Storable Pair instance<br />
<br />
The last solution is obviously the simplest one. It requires an extension however:<br />
<br />
<haskell><br />
{-# LANGUAGE GeneralizedNewtypeDeriving #-}<br />
<br />
newtype Pair = Pair Complex deriving (Storable)<br />
</haskell><br />
<br />
=== Arrays ===<br />
<br />
It is very common to read and to write arrays of values. [http://hackage.haskell.org/package/base/docs/Foreign-Marshal-Array.html Foreign.Marshal.Array] provides many functions to deal with pointers to arrays. You can easily write an Haskell list of storable values as an array of values, and vice versa.<br />
<br />
=== Strings ===<br />
<br />
Strings in Haskell are lists of Char, where Char represents a unicode character. Many foreign codes use the C representation for strings ([https://hackage.haskell.org/package/base/docs/Foreign-C-String.html CString] in Haskell): an array of bytes where each byte is a extended ASCII character terminated with a NUL character.<br />
<br />
In [https://hackage.haskell.org/package/base/docs/Foreign-C-String.html Foreign.C.String], you have many functions to convert between both representations. Be careful because Unicode characters outside of the ASCII range may not be representable with the C representation.<br />
<br />
<haskell><br />
foreign import ccall "echo" c_echo :: CString -> IO ()<br />
<br />
echo :: String -> IO ()<br />
echo str = withCString str $ \c_str -><br />
c_echo c_str<br />
</haskell><br />
<br />
=== Data structures ===<br />
<br />
Marshalling data structures of foreign languages is the most cumbersome task: you have to find out the offset of each field of the data structure (considering padding bytes, etc.). Hopefully, there are Haskell tools to help with this task.<br />
<br />
Suppose you have a C data structure like this:<br />
struct MyStruct {<br />
double d;<br />
char c;<br />
int32_t i;<br />
};<br />
<br />
And its Haskell counterpart:<br />
<haskell><br />
data MyStruct = MyStruct<br />
{ d :: Double<br />
, c :: Word8<br />
, i :: Int32<br />
}<br />
</haskell><br />
<br />
The following sub-sections present the different ways to write the Storable instance for MyStruct. <br />
<br />
The following header is implied:<br />
<haskell><br />
import Control.Applicative ((<$>), (<*>))<br />
import Foreign.Storable<br />
</haskell><br />
<br />
==== The explicit way ====<br />
<br />
<haskell><br />
instance Storable MyStruct where<br />
alignment _ = 8<br />
sizeOf _ = 16<br />
peek ptr = MyStruct<br />
<$> peekByteOff ptr 0<br />
<*> peekByteOff ptr 8<br />
<*> peekByteOff ptr 12 -- skip padding bytes after "c"<br />
poke ptr (MyStruct d c i) = do<br />
pokeByteOff ptr 0 d<br />
pokeByteOff ptr 8 c<br />
pokeByteOff ptr 12 i<br />
</haskell><br />
<br />
* The structure alignment is the least common multiple of the alignments of the structure fields. The alignment of primitive types is equal to their size in bytes (e.g. 8 for Double, 1 for Word8 and 4 for Word32). Hence the alignment for MyStruct is 8.<br />
<br />
* We indicate the offset of each field explicitly for peek and poke methods. We introduce padding bytes to align the "i" field (Word32) on 4 bytes. A C compiler does the same thing (except for packed structures).<br />
<br />
* The size of the structure is the total number of bytes, including padding bytes between fields.<br />
<br />
==== hsc2hs ====<br />
<br />
[https://downloads.haskell.org/~ghc/master/users-guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs hsc2hs] is a tool that can help you compute field offsets by using C headers directly.<br />
<br />
Save your Haskell file with a .hsc extension to enable the support of hsc2hs.<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> (#peek MyStruct, d) ptr<br />
<*> (#peek MyStruct, c) ptr<br />
<*> (#peek MyStruct, i) ptr<br />
...<br />
</haskell><br />
<br />
==== c2hs ====<br />
<br />
[https://hackage.haskell.org/package/c2hs c2hs] is another tool that can help you doing the same thing as hsc2hs for data structure marshalling. [http://stackoverflow.com/questions/6009031/difference-between-hsc2hs-and-c2hs They have differences in other aspects though].<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> {#get MyStruct->d} ptr<br />
<*> {#get MyStruct->c} ptr<br />
<*> {#get MyStruct->i} ptr<br />
...<br />
</haskell><br />
<br />
<br />
==== c-storable-deriving ====<br />
<br />
You can also derive the Storable instances from the types of the fields and their order in the Haskell data type by using [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving package].<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
import GHC.Generics (Generic)<br />
import Foreign.CStorable<br />
<br />
data MyStruct = MyStruct {...} deriving (Generic)<br />
<br />
instance CStorable MyStruct<br />
<br />
instance Storable MyStruct where<br />
sizeOf = cSizeOf<br />
alignment = cAlignment<br />
poke = cPoke<br />
peek = cPeek<br />
</haskell><br />
<br />
The CStorable type-class is equivalent to the Storable type-class but has additional default implementations for its methods if the type has an instance of Generic.<br />
<br />
=== Pointers to Haskell data ===<br />
<br />
In some cases, you may want to give to the foreign code an opaque reference to a Haskell value that you will retrieve later on. You need to be sure that the value is not collected between the time you give it and the time you retrieve it. [https://hackage.haskell.org/package/base/docs/Foreign-StablePtr.html Stable pointers] have been created exactly to do this. You can wrap a value into a StablePtr and give it to the foreign code (StablePtr is one of the marshallable foreign types).<br />
<br />
You need to manually free stable pointers using `freeStablePtr` when they are not required anymore.<br />
<br />
== Tools ==<br />
<br />
There are several tools to help writing bindings using the FFI. In particular by using C headers.<br />
<br />
=== Using C headers ===<br />
* [https://downloads.haskell.org/~ghc/master/users-guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs hsc2hs]<br />
* [https://hackage.haskell.org/package/c2hs c2hs]<br />
* [http://hackage.haskell.org/package/bindings-DSL-1.0.22 bindings-DSL]<br />
* [http://hackage.haskell.org/package/c2hsc c2hsc]<br />
<br />
=== Haskell ===<br />
* [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving]<br />
<br />
=== Dynamic function call ===<br />
* [https://hackage.haskell.org/package/libffi libffi]: allow to call a C function without knowing its type at compile time.<br />
<br />
== Linking ==<br />
<br />
There are several ways for GHC to find the foreign code to link with:<br />
* Static linking: the foreign code binary object is merged with the Haskell one to form the final executable<br />
* Dynamic linking: the generated binary uses libraries (e.g. .dll or .so) that are automatically linked when the binary is executed<br />
* Explicit dynamic linking: the Haskell code explicitly loads libraries, finds symbols in them and makes calls to them<br />
<br />
The first two modes are well described in GHC and Cabal manuals. For the last one, you need to use platform dependent methods:<br />
* on UNIX, you can use [http://hackage.haskell.org/package/unix/docs/System-Posix-DynamicLinker.html System.Posix.DynamicLinker]<br />
<br />
Explicit dynamic linking helps you obtaining [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 function pointers (FunPtr)]. You need to write "dynamic" wrappers to call the functions from Haskell.<br />
<br />
=== Dynamic linker template ===<br />
<br />
[https://hackage.haskell.org/package/dynamic-linker-template dynamic-linker-template] is a package that uses template Haskell to automatically generate "dynamic" wrappers for explicit dynamic linking (only supporting Unix for now).<br />
<br />
The idea is that a library is like a record containing functions, hence it is easy to generate the code that load symbols from a library and store them into a Haskell record.<br />
<br />
In the following code, the record matching library symbols is the data type MyLib. The generated code will apply "myModifier" to each field name of the record to find corresponding symbols in the library. myModifier should often be "id" but it is sometimes useful when symbols are not pretty. Here in the foreign code "_v2" is appended at the end of each symbol to avoid symbol clashes with the first version of the library.<br />
<br />
The package supports optional symbols: functions that may or may not be present in the library. These optional functions are represented by encapsulating the function type into Maybe.<br />
<br />
The `libHandle` field is mandatory and contains a pointer to the loaded library. You can use it to unload the library.<br />
<br />
A function called `loadMyLib` is generated to load symbols from a library, wrap them using "dynamic" wrappers and store them into a MyLib value that is returned.<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell, ForeignFunctionInterface #-}<br />
<br />
import System.Posix.DynamicLinker.Template<br />
<br />
data MyLib = MyLib {<br />
libHandle :: DL,<br />
thing1 :: Double -> IO Int, -- Mandatory symbol<br />
thing2 :: Maybe (Int -> Int -> Int) -- Optional symbol<br />
}<br />
<br />
myModifier :: String -> String<br />
myModifier = (++ "_v2")<br />
<br />
$(makeDynamicLinker ''MyLib CCall 'myModifier)<br />
<br />
-- Load your library with:<br />
-- loadMyLib :: FilePath -> [RTLDFlags] -> IO MyLib<br />
</haskell><br />
<br />
== Enhancing performance and advanced topics ==<br />
<br />
To enhance performance of a call to a foreign function, you first need to understand how GHC runtime system works. GHC uses user-space threads. It uses a set of system threads (called "Tasks"). Each system thread can execute a "capability" (i.e. a user-space thread manager). User-space threads are distributed on capabilities. Each capability executes its associated user-space threads, one at a time, using cooperative scheduling or preemption if necessary.<br />
<br />
All the capabilities have to synchronize to perform garbage collection.<br />
<br />
When a FFI call is made:<br />
* the user-space thread is suspended (indicating it is waiting for the result of a foreign call)<br />
* the current system thread executing the capability executing the user-space thread releases the capability<br />
** the capability can be picked up by another system thread<br />
** the user-space threads that are not suspended in the capability can be executed<br />
** garbage collection can occur<br />
* the system thread executes the FFI call<br />
* when the FFI call returns, the user-space thread is woken up<br />
<br />
If there are too many blocked system threads, the runtime system can spawn new ones.<br />
<br />
=== Unsafe calls ===<br />
<br />
All the capability management before and after a FFI call adds some overhead. It is possible to avoid it in some cases by adding the "unsafe" keyword as in the following example:<br />
<br />
<haskell><br />
foreign import ccall unsafe "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
By doing this, the foreign code will be directly called but the capability won't be released by the system thread during the call. Here are the drawbacks of this approach:<br />
* if the foreign function blocks indefinitely, the other user-space threads of the capability won't be executed anymore (deadlock)<br />
* if the foreign code calls back into the Haskell code, a deadlock may occur<br />
** it may wait for a value produced by one of the locked user-space threads on the capability<br />
** there may not be enough capabilities to execute the code<br />
<br />
=== Foreign PrimOps ===<br />
<br />
If unsafe foreign calls are not fast enough for you, you can try the GHCForeignImportPrim extension.<br />
<br />
<haskell><br />
{-# LANGUAGE GHCForeignImportPrim,<br />
MagicHash,<br />
UnboxedTuples,<br />
UnliftedFFITypes #-}<br />
<br />
import GHC.Base<br />
import GHC.Int<br />
<br />
-- Primitive with type :: Int -> Int -> IO Int<br />
foreign import prim "my_primop_cmm"<br />
my_primop# :: Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #)<br />
<br />
my_primop :: Int64 -> Int64 -> IO Int64<br />
my_primop (I64# x) (I64# y) = IO $ \s -><br />
case (my_primop# x y s) of (# s1, r #) -> (# s1, I64# r #)<br />
</haskell><br />
<br />
Then you have to write your foreign function "my_primop_cmm" using [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CmmType C--] language used internally by GHC.<br />
<br />
As an alternative, if you know how C-- is compiled on your architecture, you can write code in other languages. For instance [https://github.com/hsyl20/haskus-system/blob/fa9a4057c38f1e2808ba570eb57636c51a809c29/src/lib/Haskus/Arch/X86_64/Linux/syscall.c#L95 directly in assembly] or [http://breaks.for.alienz.org/blog/2012/02/09/parsing-market-data-feeds-with-ragel/ using C and LLVM].<br />
<br />
[http://breaks.for.alienz.org/blog/2012/05/23/ffi-vs-primops/ Here] is a comparison of the different approaches on a specific case.<br />
<br />
=== Bound threads ===<br />
<br />
Some foreign codes use (system) thread-local storage. Some others are not thread-safe. In both case, you have to be sure that the same '''system thread''' executes the FFI calls. To control how user-space threads are scheduled on system threads, GHC provide [http://hackage.haskell.org/package/base/docs/Control-Concurrent.html#g:8 bound threads]. Bound threads are user-space threads (Haskell threads) that can only be executed by a single system thread.<br />
<br />
Note that bound threads are more expensive to schedule than normal threads. The first thread executing "main" is a bound thread.<br />
<br />
=== Inline FFI calls ===<br />
<br />
If you want to make a one-shot FFI call without the hassle of writing the foreign import, you can use the following technique (using Template Haskell).<br />
<br />
In AddTopDecls.hs:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module AddTopDecls where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
importDoubleToDouble :: String -> ExpQ<br />
importDoubleToDouble fname = do<br />
n <- newName fname<br />
d <- forImpD CCall unsafe fname n [t|Double -> Double|]<br />
addTopDecls [d]<br />
[|$(varE n)|]<br />
</haskell><br />
<br />
In your module:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module Main where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
import AddTopDecls<br />
<br />
main :: IO ()<br />
main = do<br />
print ($(importDoubleToDouble "sin") pi)<br />
print ($(importDoubleToDouble "cos") pi)<br />
</haskell><br />
<br />
== History ==<br />
<br />
=== Header inclusion ===<br />
<br />
In old versions of GHC (6.8.3 and earlier), the compiler was able to check the prototypes of the foreign imports by including C header files into the generated C code. For instance, you could write:<br />
<haskell><br />
{-# INCLUDE <math.h> #-}<br />
</haskell><br />
or <br />
<haskell><br />
foreign import ccall "math.h sin" c_sin :: Double -> Double<br />
</haskell><br />
to include the "math.h" header.<br />
<br />
This is deprecated in GHC. Nevertheless you may still find examples using this syntax so it is good to know that it has been used. Moreover, other compilers may still use this feature.<br />
<br />
* Justification of the deprecation from the [http://www.haskell.org/ghc/docs/6.10.1/html/users_guide/ffi-ghc.html#glasgow-foreign-headers GHC 6.10.1 manual]:<br />
<br />
"C functions are normally declared using prototypes in a C header file. Earlier versions of GHC (6.8.3 and earlier) #included the header file in the C source file generated from the Haskell code, and the C compiler could therefore check that the C function being called via the FFI was being called at the right type.<br />
<br />
GHC no longer includes external header files when compiling via C, so this checking is not performed. The change was made for compatibility with the native code backend (-fasm) and to comply strictly with the FFI specification, which requires that FFI calls are not subject to macro expansion and other CPP conversions that may be applied when using C header files. This approach also simplifies the inlining of foreign calls across module and package boundaries: there's no need for the header file to be available when compiling an inlined version of a foreign call, so the compiler is free to inline foreign calls in any context.<br />
<br />
The -#include option is now deprecated, and the include-files field in a Cabal package specification is ignored."<br />
<br />
* [http://www.haskell.org/ghc/docs/6.8.3/html/users_guide/ffi-ghc.html#glasgow-foreign-headers Documentation of this feature in the GHC 6.8.3 manual]<br />
<br />
<br />
<br />
== References ==<br />
<br />
* FFI addendum<br />
* The [http://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1490008 Foreign Function Interface section] of the Haskell 2010 report<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html FFI chapter in the GHC user guide]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ "Tackling the awkward squad" paper]<br />
* [http://community.haskell.org/~simonmar/papers/conc-ffi.pdf "Extending the Haskell FFI with Concurrency" paper] (the number of capabilities is now greater than 1)<br />
* http://blog.melding-monads.com/2011/10/24/concurrency-and-foreign-functions-in-the-glasgow-haskell-compiler/<br />
<br />
<br />
=== Related links ===<br />
<br />
* [https://github.com/GaloisInc/ivory Ivory]: EDSL for writing safer low-level C.<br />
<br />
=== Old links ===<br />
<br />
Select one of the following links for more information:<br />
* [[FFI Introduction]]<br />
* GHC manual: [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs Writing Haskell interfaces to C code: hsc2hs]<br />
* [https://github.com/ifesdjeen/haskell-ffi-tutorial haskell-ffi-tutorial] at GitHub<br />
* The official description: chapters 8 and 24 to 37 of [http://www.haskell.org/onlinereport/haskell2010/#QQ2-15-159 The Haskell 2010 Language Report] (a draft: [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ The Haskell 98 Foreign Function Interface 1.0. An Addendum to the Haskell 98 Report])<br />
* [[FFI cook book]]<br />
* [[FFI complete examples]]<br />
* [[GHC/Using the FFI]]<br />
* [http://research.microsoft.com/~simonpj/papers/marktoberdorf/ Tackling the awkward squad]<br />
* [https://github.com/wavewave/fficxx fficxx], a Haskell-C++ Foreign Function Interface Generator<br />
* [[Applications and libraries/Interfacing other languages]]<br />
* [http://rosettacode.org/wiki/Use_another_language_to_call_a_function#Haskell Use another language to call a function; Haskell]<br />
* [https://code.google.com/p/tabi/ TABI] a typeful tagged cross-language calling convention<br />
<br />
=== Blog articles ===<br />
<br />
* [http://www.serpentine.com/blog/2010/09/04/dealing-with-fragile-c-libraries-e-g-mysql-from-haskell/ Dealing with fragile C libraries (e.g. MySQL) from Haskell] <br />
* [http://blog.danieroux.com/2007/01/01/simple-demonstration-of-haskell-ffi/ Simple demonstration of Haskell FFI]<br />
* [http://therning.org/magnus/posts/2006-12-08-238-c-and-haskell-sitting-in-a-tree.html C and Haskell sitting in a tree…]<br />
* [https://web.archive.org/web/20161110104503/vis.renci.org/jeff/2009/07/10/c2hs-example-to-save-other-people-frustration/ C2HS example: To save other people frustration] <br />
* [[Cxx foreign function interface]]; how to link to a C++ library<br />
* [http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/ Safety first: FFI and threading]<br />
<br />
== TODO ==<br />
<br />
* Fix References section<br />
<br />
* Foreign language specific issues<br />
** C++ symbol mangling<br />
** Embedded Objective C<br />
<br />
* Precision<br />
<br />
<code>The Haskell report only guarantees that Int has 30 bits of signed precision, so converting CInt to Int is not safe! On the other hand, many classes have instances for Int and Integer but not CInt, so it's generally more convenient to convert from the C types. To convert, I suppose you could either write a 'checkedFromIntegral' function if you're sure it's small or just use Integer.</code><br />
<br />
* Fix [https://wiki.haskell.org/C2hs]<br />
** One page per tool?<br />
** Links to external tool specific tutorials<br />
<br />
* Linking<br />
** pkgconfig<br />
** cabal<br />
** explicit (ghc parameters)<br />
** cf http://stackoverflow.com/questions/4959802/how-to-specify-dependency-on-external-c-library-in-cabal<br />
<br />
[[Category:FFI]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Foreign_Function_Interface&diff=62597Foreign Function Interface2018-08-26T22:26:38Z<p>Henk-Jan van Tuyl: /* Using C headers */ Updated link</p>
<hr />
<div>[[Category:FFI]]<br />
<br />
== Introduction ==<br />
<br />
The Foreign Function Interface (FFI) allows Haskell programs to cooperate with programs written with other languages. Haskell programs can call foreign functions and foreign functions can call Haskell code.<br />
<br />
Compared to many other languages, Haskell FFI is very easy to use: in the most common case, you only have to translate the prototype of the foreign function into the equivalent Haskell prototype and you're done. For instance, to call the exponential function ("exp") of the libc, you only have to translate its prototype:<br />
<br />
<source lang="c"><br />
double exp(double);<br />
</source><br />
<br />
into the following Haskell code<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
Now you can use the function "c_exp" just like any other Haskell function. When evaluated, it will call "exp".<br />
<br />
Similarly, to export the following Haskell function:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
</haskell><br />
<br />
so that it can be used in foreign codes, you only have to write:<br />
<br />
<haskell><br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
It can get at little more complicated depending on what you want to do, the function parameters, the foreign code you target, etc. This page is here to explain all of this to you.<br />
<br />
== Generalities ==<br />
<br />
=== FFI extension ===<br />
<br />
The Foreign Function Interface (FFI) is an extension to the Haskell standard. To use it, you need to enable it with the following compiler pragma at the beginning of your source file:<br />
<br />
<haskell><br />
{-# LANGUAGE ForeignFunctionInterface #-}<br />
</haskell><br />
<br />
=== Calling conventions ===<br />
<br />
When a program (in any language) is compiled into machine code, functions and procedures become labels: a label is a symbol (a string) associated to a position into the machine code. Calling a function only consists in putting parameters at appropriate places into memory and registers and then branching at the label position. The caller needs to know where to store parameters and the callee needs to know where to retrieve parameters from: there is a '''calling convention'''.<br />
<br />
To interact with foreign code, you need to know the calling conventions that are used by the other language implementation on the given architecture. It can also depend on the operating system.<br />
<br />
GHC supports standard calling conventions with the FFI: it can generate code to convert between its internal (non-standard) convention and the foreign one. If we consider the previous example:<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
we see that the C calling convention ("ccall") is used. GHC will generate code to put (and to retrieve) parameters into memory and registers conforming to what is expected by a code generated with a C compiler (or any other compiler conforming to this convention).<br />
<br />
Other available conventions supported by GHC include "stdcall" (i.e. Pascal convention).<br />
<br />
=== Foreign types ===<br />
<br />
Calling conventions depend on parameter types. For instance, floating-point values (Double, Float) may be passed into floating-point registers. Several values can be combined into a single vector register. And so on. As an example, in http://www.x86-64.org/documentation/abi.pdf you can find the algorithm describing how to pass parameters to functions on Linux on a x86-64 architecture depending on the types of the parameters.<br />
<br />
Only some Haskell types can be directly used as parameters for foreign functions, because they correspond to basic types of low-level languages such as C and are used to define calling conventions.<br />
<br />
According to [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2], the type of a foreign function is a ''foreign type'', that is a function type with zero or more arguments where:<br />
* the argument types can be ''marshallable foreign types'', i.e. Char, Int, Double, Float, Bool, Int8, Int16, Int32, Int64, Word8, Word16, Word32, Word64, Ptr a, FunPtr a, StablePtr a or a renaming of any of these using newtype.<br />
* the return type is either a ''marshallable foreign type'' or has the form IO t where t is a marshallable foreign type or ().<br />
<br />
'''Warning''': GHC does not support passing structures as values yet.<br />
<br />
The [http://hackage.haskell.org/package/base/docs/Foreign-C-Types.html Foreign.C.Types] module contains renaming of some of these ''marshallable foreign types'' with names closer to those of C types (e.g. CLong, CShort).<br />
<br />
If the foreign function performs side-effects, you have to explicitly indicate it in its type (using IO). GHC has no other way to detect it.<br />
<br />
<haskell><br />
foreign import ccall "my_func" myFunc :: Int -> IO Double<br />
</haskell><br />
<br />
Data structures have to passed by reference (using pointers). We will see how to use them later in this document.<br />
<br />
=== Exported functions ===<br />
<br />
GHC can generate wrappers so that a foreign code can call Haskell code:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
<br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
In the generated binary object, there will be a label "triple" that can be called from a language using the C convention.<br />
<br />
Note that to call a Haskell function, the runtime system must have been initialized with a call to "hs_init". It must be released with a call to "hs_exit" when it is no longer required.<br />
<br />
See the [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html user guide] for more details.<br />
<br />
== Function pointers ==<br />
<br />
Sometimes you want to manipulate foreign pointers to foreign functions: these are [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 FunPtr] in Haskell.<br />
<br />
You can get a function pointer by using "&" before a foreign function symbol:<br />
<haskell><br />
foreign import ccall "&exp" a_exp :: FunPtr (Double -> Double)<br />
</haskell><br />
<br />
Some foreign functions can also return function pointers.<br />
<br />
To call a function pointer from Haskell, GHC needs to convert between its own calling convention and the one expected by the foreign code. To create a function doing this conversion, you must use "dynamic" wrappers:<br />
<br />
<haskell><br />
foreign import ccall "dynamic" mkFun :: FunPtr (Double -> Double) -> (Double -> Double)<br />
</haskell><br />
<br />
Then you can apply this wrapper to a FunPtr to get a Haskell function:<br />
<br />
<haskell><br />
c_exp :: Double -> Double<br />
c_exp = mkFun a_exp<br />
</haskell><br />
<br />
You can also perform the opposite operation to give to the foreign code a pointer to a Haskell function. You need a "wrapper" wrapper. GHC generates the callable code to execute the wrapped Haskell closure with the appropriate calling convention and returns a pointer (FunPtr) on it. You have to release the generated code explicitly with `freeHaskellFunPtr` to avoid memory leaks: GHC has no way to know if the function pointer is still referenced in some foreign code, hence it doesn't collect it.<br />
<br />
<haskell><br />
add :: Int -> Int<br />
add = x+y<br />
<br />
foreign import ccall "wrapper" createAddPtr :: (Int -> Int) -> IO (FunPtr (Int -> Int))<br />
<br />
main = do<br />
addPtr <- createAddPtr add<br />
-- you can use addPtr like any other FunPtr (e.g. give it to foreign code)<br />
...<br />
-- you MUST free the FunPtr, otherwise it won't be collected<br />
freeHaskellFunPtr addPtr<br />
</haskell><br />
<br />
== Marshalling data ==<br />
<br />
In Haskell we are accustomed to let the runtime system -- especially the garbage collector -- manage memory. When we use the FFI, however, we sometimes need to do some manual memory management to comply with the data representations of the foreign codes. Hopefully, Haskell makes it very easy to manipulate low-level objects such as pointers. Moreover, many useful Haskell tools have been designed to simplify conversions between data representations.<br />
<br />
=== Pointers ===<br />
<br />
A pointer is an offset in memory. In Haskell, it is represented with the [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html Ptr a] data type. Where "a" is a phantom type that can be used to differentiate two pointers. You can think of "Ptr Stuff" as being equivalent to a "Stuff *" type in C (i.e. a pointer to a "Stuff" data). This analogy may not hold if "a" is a Haskell type not representable in the foreign language. For instance, you can have a pointer with the type "Ptr (Stuff -> OtherStuff)" but it is not function pointer in the foreign language: it is just a pointer tagged with the "Stuff -> OtherStuff" type.<br />
<br />
You can easily cast between pointer types using `castPtr` or perform pointer arithmetic using `plusPtr`, `minusPtr` and `alignPtr`. NULL pointer is represented with `nullPtr`.<br />
<br />
=== Memory allocation ===<br />
<br />
There are basically two ways to allocate memory:<br />
* on the Haskell heap, using `alloca*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
The allocation is ephemeral: it lasts the time of the execution of an IO action, as in the following example:<br />
<haskell><br />
do<br />
allocaBytes 128 $ \ptr -> do<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
-- do not return "ptr" in any way because it will become an invalid pointer<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
* on the "low-level" heap (the same as the runtime system uses), using `malloc*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
Allocations on the low-level heap are not managed by the Haskell implementation and must be freed explicitly with `free`.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
free ptr<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
=== Foreign Pointers ===<br />
<br />
An hybrid approach is to use [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr ForeignPtr]. Foreign pointers are similar to Ptr except that they have finalizers (i.e. actions) attached to them. When the garbage collector detects that a ForeignPtr is no longer accessible, it executes its associated finalizers. A basic finalizer is `finalizerFree` [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html] that calls `free` on the pointer.<br />
<br />
You can convert a Ptr into a ForeignPtr using `newForeignPtr`, add additional finalizers, etc. [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr].<br />
<br />
In the following example, we use `mallocForeignPtrBytes`. It is equivalent to call `malloc` and then to associate the `finalizerFree` finalizer with `newForeignPtr`. GHC has optimized implementations for `mallocForeignPtr*` functions, hence they should be preferred.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocForeignPtrBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
--<br />
-- ptr is freed when it is collected<br />
</haskell><br />
<br />
=== Using pointers: Storable instances ===<br />
<br />
You often want to read or to write at the address a of pointer. Reading consists in obtaining a Haskell value from a pointer; writing consists in somehow writing a representation of the Haskell value at the pointed address. Writing and reading a value depends on the type of the value, hence these methods are encapsulated into the [https://hackage.haskell.org/package/base/docs/Foreign-Storable.html Storable] type class.<br />
<br />
For any type T such that it exists a Storable T instance:<br />
* you can read a value, using <haskell>peek :: Ptr T -> IO T</haskell><br />
* you can write a value, using <haskell>poke :: Ptr T -> T -> IO ()</haskell><br />
<br />
`Storable a` also defines a `sizeOf :: a -> Int` method that returns the size of the stored value in bytes.<br />
<br />
All the ''marshallable foreign types'' (i.e. basic types) have Storable instances. Hence we can use these to write new Storable instances for more involved data types. In the following example, we create a Storable instance for a Complex data type:<br />
<br />
<haskell><br />
data Complex = Complex Double Double<br />
<br />
instance Storable Complex where<br />
sizeOf _ = 2 * sizeOf (undefined :: Double) -- stored complex size = 2 * size of a stored Double<br />
peek ptr = do<br />
real <- peek ptr<br />
img <- peekByteOff ptr (sizeOf real) -- we skip the bytes containing the real part<br />
return $ Complex real img<br />
poke ptr (Complex real img) = do<br />
poke ptr real<br />
pokeByteOff ptr (sizeOf real) img<br />
...<br />
</haskell><br />
<br />
This is not very complicated but it can become very cumbersome if our data type has many fields. Several tools have been developed to automatically or semi-automatically create the Storable instances.<br />
<br />
==== Renaming and Storable instances ====<br />
<br />
It is very common to use type renaming (i.e. newtype) to wrap a data type as in the following example, where we declare a type Pair that contains a pair of Double values just like our Complex type.<br />
<br />
<haskell><br />
newtype Pair = Pair Complex<br />
</haskell><br />
<br />
If we want to store Pair values exactly like Complex values, we have several possibilities:<br />
* unwrap the Complex value each time we want to use its Storable instance<br />
* create a new Storable Pair instance that does the same thing<br />
* automatically derive the Storable Pair instance<br />
<br />
The last solution is obviously the simplest one. It requires an extension however:<br />
<br />
<haskell><br />
{-# LANGUAGE GeneralizedNewtypeDeriving #-}<br />
<br />
newtype Pair = Pair Complex deriving (Storable)<br />
</haskell><br />
<br />
=== Arrays ===<br />
<br />
It is very common to read and to write arrays of values. [http://hackage.haskell.org/package/base/docs/Foreign-Marshal-Array.html Foreign.Marshal.Array] provides many functions to deal with pointers to arrays. You can easily write an Haskell list of storable values as an array of values, and vice versa.<br />
<br />
=== Strings ===<br />
<br />
Strings in Haskell are lists of Char, where Char represents a unicode character. Many foreign codes use the C representation for strings ([https://hackage.haskell.org/package/base/docs/Foreign-C-String.html CString] in Haskell): an array of bytes where each byte is a extended ASCII character terminated with a NUL character.<br />
<br />
In [https://hackage.haskell.org/package/base/docs/Foreign-C-String.html Foreign.C.String], you have many functions to convert between both representations. Be careful because Unicode characters outside of the ASCII range may not be representable with the C representation.<br />
<br />
<haskell><br />
foreign import ccall "echo" c_echo :: CString -> IO ()<br />
<br />
echo :: String -> IO ()<br />
echo str = withCString str $ \c_str -><br />
c_echo c_str<br />
</haskell><br />
<br />
=== Data structures ===<br />
<br />
Marshalling data structures of foreign languages is the most cumbersome task: you have to find out the offset of each field of the data structure (considering padding bytes, etc.). Hopefully, there are Haskell tools to help with this task.<br />
<br />
Suppose you have a C data structure like this:<br />
struct MyStruct {<br />
double d;<br />
char c;<br />
int32_t i;<br />
};<br />
<br />
And its Haskell counterpart:<br />
<haskell><br />
data MyStruct = MyStruct<br />
{ d :: Double<br />
, c :: Word8<br />
, i :: Int32<br />
}<br />
</haskell><br />
<br />
The following sub-sections present the different ways to write the Storable instance for MyStruct. <br />
<br />
The following header is implied:<br />
<haskell><br />
import Control.Applicative ((<$>), (<*>))<br />
import Foreign.Storable<br />
</haskell><br />
<br />
==== The explicit way ====<br />
<br />
<haskell><br />
instance Storable MyStruct where<br />
alignment _ = 8<br />
sizeOf _ = 16<br />
peek ptr = MyStruct<br />
<$> peekByteOff ptr 0<br />
<*> peekByteOff ptr 8<br />
<*> peekByteOff ptr 12 -- skip padding bytes after "c"<br />
poke ptr (MyStruct d c i) = do<br />
pokeByteOff ptr 0 d<br />
pokeByteOff ptr 8 c<br />
pokeByteOff ptr 12 i<br />
</haskell><br />
<br />
* The structure alignment is the least common multiple of the alignments of the structure fields. The alignment of primitive types is equal to their size in bytes (e.g. 8 for Double, 1 for Word8 and 4 for Word32). Hence the alignment for MyStruct is 8.<br />
<br />
* We indicate the offset of each field explicitly for peek and poke methods. We introduce padding bytes to align the "i" field (Word32) on 4 bytes. A C compiler does the same thing (except for packed structures).<br />
<br />
* The size of the structure is the total number of bytes, including padding bytes between fields.<br />
<br />
==== hsc2hs ====<br />
<br />
[https://downloads.haskell.org/~ghc/master/users-guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs hsc2hs] is a tool that can help you compute field offsets by using C headers directly.<br />
<br />
Save your Haskell file with a .hsc extension to enable the support of hsc2hs.<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> (#peek MyStruct, d) ptr<br />
<*> (#peek MyStruct, c) ptr<br />
<*> (#peek MyStruct, i) ptr<br />
...<br />
</haskell><br />
<br />
==== c2hs ====<br />
<br />
[https://hackage.haskell.org/package/c2hs c2hs] is another tool that can help you doing the same thing as hsc2hs for data structure marshalling. [http://stackoverflow.com/questions/6009031/difference-between-hsc2hs-and-c2hs They have differences in other aspects though].<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> {#get MyStruct->d} ptr<br />
<*> {#get MyStruct->c} ptr<br />
<*> {#get MyStruct->i} ptr<br />
...<br />
</haskell><br />
<br />
<br />
==== c-storable-deriving ====<br />
<br />
You can also derive the Storable instances from the types of the fields and their order in the Haskell data type by using [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving package].<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
import GHC.Generics (Generic)<br />
import Foreign.CStorable<br />
<br />
data MyStruct = MyStruct {...} deriving (Generic)<br />
<br />
instance CStorable MyStruct<br />
<br />
instance Storable MyStruct where<br />
sizeOf = cSizeOf<br />
alignment = cAlignment<br />
poke = cPoke<br />
peek = cPeek<br />
</haskell><br />
<br />
The CStorable type-class is equivalent to the Storable type-class but has additional default implementations for its methods if the type has an instance of Generic.<br />
<br />
=== Pointers to Haskell data ===<br />
<br />
In some cases, you may want to give to the foreign code an opaque reference to a Haskell value that you will retrieve later on. You need to be sure that the value is not collected between the time you give it and the time you retrieve it. [https://hackage.haskell.org/package/base/docs/Foreign-StablePtr.html Stable pointers] have been created exactly to do this. You can wrap a value into a StablePtr and give it to the foreign code (StablePtr is one of the marshallable foreign types).<br />
<br />
You need to manually free stable pointers using `freeStablePtr` when they are not required anymore.<br />
<br />
== Tools ==<br />
<br />
There are several tools to help writing bindings using the FFI. In particular by using C headers.<br />
<br />
=== Using C headers ===<br />
* [https://downloads.haskell.org/~ghc/master/users-guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs hsc2hs]<br />
* [https://hackage.haskell.org/package/c2hs c2hs]<br />
* [http://hackage.haskell.org/package/bindings-DSL-1.0.22 bindings-DSL]<br />
* [http://hackage.haskell.org/package/c2hsc c2hsc]<br />
<br />
=== Haskell ===<br />
* [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving]<br />
<br />
=== Dynamic function call ===<br />
* [https://hackage.haskell.org/package/libffi libffi]: allow to call a C function without knowing its type at compile time.<br />
<br />
== Linking ==<br />
<br />
There are several ways for GHC to find the foreign code to link with:<br />
* Static linking: the foreign code binary object is merged with the Haskell one to form the final executable<br />
* Dynamic linking: the generated binary uses libraries (e.g. .dll or .so) that are automatically linked when the binary is executed<br />
* Explicit dynamic linking: the Haskell code explicitly loads libraries, finds symbols in them and makes calls to them<br />
<br />
The first two modes are well described in GHC and Cabal manuals. For the last one, you need to use platform dependent methods:<br />
* on UNIX, you can use [http://hackage.haskell.org/package/unix/docs/System-Posix-DynamicLinker.html System.Posix.DynamicLinker]<br />
<br />
Explicit dynamic linking helps you obtaining [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 function pointers (FunPtr)]. You need to write "dynamic" wrappers to call the functions from Haskell.<br />
<br />
=== Dynamic linker template ===<br />
<br />
[https://hackage.haskell.org/package/dynamic-linker-template dynamic-linker-template] is a package that uses template Haskell to automatically generate "dynamic" wrappers for explicit dynamic linking (only supporting Unix for now).<br />
<br />
The idea is that a library is like a record containing functions, hence it is easy to generate the code that load symbols from a library and store them into a Haskell record.<br />
<br />
In the following code, the record matching library symbols is the data type MyLib. The generated code will apply "myModifier" to each field name of the record to find corresponding symbols in the library. myModifier should often be "id" but it is sometimes useful when symbols are not pretty. Here in the foreign code "_v2" is appended at the end of each symbol to avoid symbol clashes with the first version of the library.<br />
<br />
The package supports optional symbols: functions that may or may not be present in the library. These optional functions are represented by encapsulating the function type into Maybe.<br />
<br />
The `libHandle` field is mandatory and contains a pointer to the loaded library. You can use it to unload the library.<br />
<br />
A function called `loadMyLib` is generated to load symbols from a library, wrap them using "dynamic" wrappers and store them into a MyLib value that is returned.<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell, ForeignFunctionInterface #-}<br />
<br />
import System.Posix.DynamicLinker.Template<br />
<br />
data MyLib = MyLib {<br />
libHandle :: DL,<br />
thing1 :: Double -> IO Int, -- Mandatory symbol<br />
thing2 :: Maybe (Int -> Int -> Int) -- Optional symbol<br />
}<br />
<br />
myModifier :: String -> String<br />
myModifier = (++ "_v2")<br />
<br />
$(makeDynamicLinker ''MyLib CCall 'myModifier)<br />
<br />
-- Load your library with:<br />
-- loadMyLib :: FilePath -> [RTLDFlags] -> IO MyLib<br />
</haskell><br />
<br />
== Enhancing performance and advanced topics ==<br />
<br />
To enhance performance of a call to a foreign function, you first need to understand how GHC runtime system works. GHC uses user-space threads. It uses a set of system threads (called "Tasks"). Each system thread can execute a "capability" (i.e. a user-space thread manager). User-space threads are distributed on capabilities. Each capability executes its associated user-space threads, one at a time, using cooperative scheduling or preemption if necessary.<br />
<br />
All the capabilities have to synchronize to perform garbage collection.<br />
<br />
When a FFI call is made:<br />
* the user-space thread is suspended (indicating it is waiting for the result of a foreign call)<br />
* the current system thread executing the capability executing the user-space thread releases the capability<br />
** the capability can be picked up by another system thread<br />
** the user-space threads that are not suspended in the capability can be executed<br />
** garbage collection can occur<br />
* the system thread executes the FFI call<br />
* when the FFI call returns, the user-space thread is woken up<br />
<br />
If there are too many blocked system threads, the runtime system can spawn new ones.<br />
<br />
=== Unsafe calls ===<br />
<br />
All the capability management before and after a FFI call adds some overhead. It is possible to avoid it in some cases by adding the "unsafe" keyword as in the following example:<br />
<br />
<haskell><br />
foreign import ccall unsafe "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
By doing this, the foreign code will be directly called but the capability won't be released by the system thread during the call. Here are the drawbacks of this approach:<br />
* if the foreign function blocks indefinitely, the other user-space threads of the capability won't be executed anymore (deadlock)<br />
* if the foreign code calls back into the Haskell code, a deadlock may occur<br />
** it may wait for a value produced by one of the locked user-space threads on the capability<br />
** there may not be enough capabilities to execute the code<br />
<br />
=== Foreign PrimOps ===<br />
<br />
If unsafe foreign calls are not fast enough for you, you can try the GHCForeignImportPrim extension.<br />
<br />
<haskell><br />
{-# LANGUAGE GHCForeignImportPrim,<br />
MagicHash,<br />
UnboxedTuples,<br />
UnliftedFFITypes #-}<br />
<br />
import GHC.Base<br />
import GHC.Int<br />
<br />
-- Primitive with type :: Int -> Int -> IO Int<br />
foreign import prim "my_primop_cmm"<br />
my_primop# :: Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #)<br />
<br />
my_primop :: Int64 -> Int64 -> IO Int64<br />
my_primop (I64# x) (I64# y) = IO $ \s -><br />
case (my_primop# x y s) of (# s1, r #) -> (# s1, I64# r #)<br />
</haskell><br />
<br />
Then you have to write your foreign function "my_primop_cmm" using [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CmmType C--] language used internally by GHC.<br />
<br />
As an alternative, if you know how C-- is compiled on your architecture, you can write code in other languages. For instance [https://github.com/hsyl20/haskus-system/blob/fa9a4057c38f1e2808ba570eb57636c51a809c29/src/lib/Haskus/Arch/X86_64/Linux/syscall.c#L95 directly in assembly] or [http://breaks.for.alienz.org/blog/2012/02/09/parsing-market-data-feeds-with-ragel/ using C and LLVM].<br />
<br />
[http://breaks.for.alienz.org/blog/2012/05/23/ffi-vs-primops/ Here] is a comparison of the different approaches on a specific case.<br />
<br />
=== Bound threads ===<br />
<br />
Some foreign codes use (system) thread-local storage. Some others are not thread-safe. In both case, you have to be sure that the same '''system thread''' executes the FFI calls. To control how user-space threads are scheduled on system threads, GHC provide [http://hackage.haskell.org/package/base/docs/Control-Concurrent.html#g:8 bound threads]. Bound threads are user-space threads (Haskell threads) that can only be executed by a single system thread.<br />
<br />
Note that bound threads are more expensive to schedule than normal threads. The first thread executing "main" is a bound thread.<br />
<br />
=== Inline FFI calls ===<br />
<br />
If you want to make a one-shot FFI call without the hassle of writing the foreign import, you can use the following technique (using Template Haskell).<br />
<br />
In AddTopDecls.hs:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module AddTopDecls where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
importDoubleToDouble :: String -> ExpQ<br />
importDoubleToDouble fname = do<br />
n <- newName fname<br />
d <- forImpD CCall unsafe fname n [t|Double -> Double|]<br />
addTopDecls [d]<br />
[|$(varE n)|]<br />
</haskell><br />
<br />
In your module:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module Main where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
import AddTopDecls<br />
<br />
main :: IO ()<br />
main = do<br />
print ($(importDoubleToDouble "sin") pi)<br />
print ($(importDoubleToDouble "cos") pi)<br />
</haskell><br />
<br />
== History ==<br />
<br />
=== Header inclusion ===<br />
<br />
In old versions of GHC (6.8.3 and earlier), the compiler was able to check the prototypes of the foreign imports by including C header files into the generated C code. For instance, you could write:<br />
<haskell><br />
{-# INCLUDE <math.h> #-}<br />
</haskell><br />
or <br />
<haskell><br />
foreign import ccall "math.h sin" c_sin :: Double -> Double<br />
</haskell><br />
to include the "math.h" header.<br />
<br />
This is deprecated in GHC. Nevertheless you may still find examples using this syntax so it is good to know that it has been used. Moreover, other compilers may still use this feature.<br />
<br />
* Justification of the deprecation from the [http://www.haskell.org/ghc/docs/6.10.1/html/users_guide/ffi-ghc.html#glasgow-foreign-headers GHC 6.10.1 manual]:<br />
<br />
"C functions are normally declared using prototypes in a C header file. Earlier versions of GHC (6.8.3 and earlier) #included the header file in the C source file generated from the Haskell code, and the C compiler could therefore check that the C function being called via the FFI was being called at the right type.<br />
<br />
GHC no longer includes external header files when compiling via C, so this checking is not performed. The change was made for compatibility with the native code backend (-fasm) and to comply strictly with the FFI specification, which requires that FFI calls are not subject to macro expansion and other CPP conversions that may be applied when using C header files. This approach also simplifies the inlining of foreign calls across module and package boundaries: there's no need for the header file to be available when compiling an inlined version of a foreign call, so the compiler is free to inline foreign calls in any context.<br />
<br />
The -#include option is now deprecated, and the include-files field in a Cabal package specification is ignored."<br />
<br />
* [http://www.haskell.org/ghc/docs/6.8.3/html/users_guide/ffi-ghc.html#glasgow-foreign-headers Documentation of this feature in the GHC 6.8.3 manual]<br />
<br />
<br />
<br />
== References ==<br />
<br />
* FFI addendum<br />
* The [http://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1490008 Foreign Function Interface section] of the Haskell 2010 report<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html FFI chapter in the GHC user guide]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ "Tackling the awkward squad" paper]<br />
* [http://community.haskell.org/~simonmar/papers/conc-ffi.pdf "Extending the Haskell FFI with Concurrency" paper] (the number of capabilities is now greater than 1)<br />
* http://blog.melding-monads.com/2011/10/24/concurrency-and-foreign-functions-in-the-glasgow-haskell-compiler/<br />
<br />
<br />
=== Related links ===<br />
<br />
* [https://github.com/GaloisInc/ivory Ivory]: EDSL for writing safer low-level C.<br />
<br />
=== Old links ===<br />
<br />
Select one of the following links for more information:<br />
* [[FFI Introduction]]<br />
* GHC manual: [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs Writing Haskell interfaces to C code: hsc2hs]<br />
* [https://github.com/ifesdjeen/haskell-ffi-tutorial haskell-ffi-tutorial] at GitHub<br />
* The official description: chapters 8 and 24 to 37 of [http://www.haskell.org/onlinereport/haskell2010/#QQ2-15-159 The Haskell 2010 Language Report] (a draft: [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ The Haskell 98 Foreign Function Interface 1.0. An Addendum to the Haskell 98 Report])<br />
* [[FFI cook book]]<br />
* [[FFI complete examples]]<br />
* [[GHC/Using the FFI]]<br />
* [http://research.microsoft.com/~simonpj/papers/marktoberdorf/ Tackling the awkward squad]<br />
* [https://github.com/wavewave/fficxx fficxx], a Haskell-C++ Foreign Function Interface Generator<br />
* [[Applications and libraries/Interfacing other languages]]<br />
* [http://rosettacode.org/wiki/Use_another_language_to_call_a_function#Haskell Use another language to call a function; Haskell]<br />
* [https://code.google.com/p/tabi/ TABI] a typeful tagged cross-language calling convention<br />
<br />
=== Blog articles ===<br />
<br />
* [http://www.serpentine.com/blog/2010/09/04/dealing-with-fragile-c-libraries-e-g-mysql-from-haskell/ Dealing with fragile C libraries (e.g. MySQL) from Haskell] <br />
* [http://blog.danieroux.com/2007/01/01/simple-demonstration-of-haskell-ffi/ Simple demonstration of Haskell FFI]<br />
* [http://therning.org/magnus/posts/2006-12-08-238-c-and-haskell-sitting-in-a-tree.html C and Haskell sitting in a tree…]<br />
* [http://vis.renci.org/jeff/2009/07/10/c2hs-example-to-save-other-people-frustration/ C2HS example: To save other people frustration] <br />
* [[Cxx foreign function interface]]; how to link to a C++ library<br />
* [http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/ Safety first: FFI and threading]<br />
<br />
== TODO ==<br />
<br />
* Fix References section<br />
<br />
* Foreign language specific issues<br />
** C++ symbol mangling<br />
** Embedded Objective C<br />
<br />
* Precision<br />
<br />
<code>The Haskell report only guarantees that Int has 30 bits of signed precision, so converting CInt to Int is not safe! On the other hand, many classes have instances for Int and Integer but not CInt, so it's generally more convenient to convert from the C types. To convert, I suppose you could either write a 'checkedFromIntegral' function if you're sure it's small or just use Integer.</code><br />
<br />
* Fix [https://wiki.haskell.org/C2hs]<br />
** One page per tool?<br />
** Links to external tool specific tutorials<br />
<br />
* Linking<br />
** pkgconfig<br />
** cabal<br />
** explicit (ghc parameters)<br />
** cf http://stackoverflow.com/questions/4959802/how-to-specify-dependency-on-external-c-library-in-cabal<br />
<br />
[[Category:FFI]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Foreign_Function_Interface&diff=62596Foreign Function Interface2018-08-26T22:20:12Z<p>Henk-Jan van Tuyl: /* Strings */ Corrected link</p>
<hr />
<div>[[Category:FFI]]<br />
<br />
== Introduction ==<br />
<br />
The Foreign Function Interface (FFI) allows Haskell programs to cooperate with programs written with other languages. Haskell programs can call foreign functions and foreign functions can call Haskell code.<br />
<br />
Compared to many other languages, Haskell FFI is very easy to use: in the most common case, you only have to translate the prototype of the foreign function into the equivalent Haskell prototype and you're done. For instance, to call the exponential function ("exp") of the libc, you only have to translate its prototype:<br />
<br />
<source lang="c"><br />
double exp(double);<br />
</source><br />
<br />
into the following Haskell code<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
Now you can use the function "c_exp" just like any other Haskell function. When evaluated, it will call "exp".<br />
<br />
Similarly, to export the following Haskell function:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
</haskell><br />
<br />
so that it can be used in foreign codes, you only have to write:<br />
<br />
<haskell><br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
It can get at little more complicated depending on what you want to do, the function parameters, the foreign code you target, etc. This page is here to explain all of this to you.<br />
<br />
== Generalities ==<br />
<br />
=== FFI extension ===<br />
<br />
The Foreign Function Interface (FFI) is an extension to the Haskell standard. To use it, you need to enable it with the following compiler pragma at the beginning of your source file:<br />
<br />
<haskell><br />
{-# LANGUAGE ForeignFunctionInterface #-}<br />
</haskell><br />
<br />
=== Calling conventions ===<br />
<br />
When a program (in any language) is compiled into machine code, functions and procedures become labels: a label is a symbol (a string) associated to a position into the machine code. Calling a function only consists in putting parameters at appropriate places into memory and registers and then branching at the label position. The caller needs to know where to store parameters and the callee needs to know where to retrieve parameters from: there is a '''calling convention'''.<br />
<br />
To interact with foreign code, you need to know the calling conventions that are used by the other language implementation on the given architecture. It can also depend on the operating system.<br />
<br />
GHC supports standard calling conventions with the FFI: it can generate code to convert between its internal (non-standard) convention and the foreign one. If we consider the previous example:<br />
<br />
<haskell><br />
foreign import ccall "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
we see that the C calling convention ("ccall") is used. GHC will generate code to put (and to retrieve) parameters into memory and registers conforming to what is expected by a code generated with a C compiler (or any other compiler conforming to this convention).<br />
<br />
Other available conventions supported by GHC include "stdcall" (i.e. Pascal convention).<br />
<br />
=== Foreign types ===<br />
<br />
Calling conventions depend on parameter types. For instance, floating-point values (Double, Float) may be passed into floating-point registers. Several values can be combined into a single vector register. And so on. As an example, in http://www.x86-64.org/documentation/abi.pdf you can find the algorithm describing how to pass parameters to functions on Linux on a x86-64 architecture depending on the types of the parameters.<br />
<br />
Only some Haskell types can be directly used as parameters for foreign functions, because they correspond to basic types of low-level languages such as C and are used to define calling conventions.<br />
<br />
According to [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2], the type of a foreign function is a ''foreign type'', that is a function type with zero or more arguments where:<br />
* the argument types can be ''marshallable foreign types'', i.e. Char, Int, Double, Float, Bool, Int8, Int16, Int32, Int64, Word8, Word16, Word32, Word64, Ptr a, FunPtr a, StablePtr a or a renaming of any of these using newtype.<br />
* the return type is either a ''marshallable foreign type'' or has the form IO t where t is a marshallable foreign type or ().<br />
<br />
'''Warning''': GHC does not support passing structures as values yet.<br />
<br />
The [http://hackage.haskell.org/package/base/docs/Foreign-C-Types.html Foreign.C.Types] module contains renaming of some of these ''marshallable foreign types'' with names closer to those of C types (e.g. CLong, CShort).<br />
<br />
If the foreign function performs side-effects, you have to explicitly indicate it in its type (using IO). GHC has no other way to detect it.<br />
<br />
<haskell><br />
foreign import ccall "my_func" myFunc :: Int -> IO Double<br />
</haskell><br />
<br />
Data structures have to passed by reference (using pointers). We will see how to use them later in this document.<br />
<br />
=== Exported functions ===<br />
<br />
GHC can generate wrappers so that a foreign code can call Haskell code:<br />
<br />
<haskell><br />
triple :: Int -> Int<br />
triple x = 3*x<br />
<br />
foreign export ccall triple :: Int -> Int<br />
</haskell><br />
<br />
In the generated binary object, there will be a label "triple" that can be called from a language using the C convention.<br />
<br />
Note that to call a Haskell function, the runtime system must have been initialized with a call to "hs_init". It must be released with a call to "hs_exit" when it is no longer required.<br />
<br />
See the [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html user guide] for more details.<br />
<br />
== Function pointers ==<br />
<br />
Sometimes you want to manipulate foreign pointers to foreign functions: these are [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 FunPtr] in Haskell.<br />
<br />
You can get a function pointer by using "&" before a foreign function symbol:<br />
<haskell><br />
foreign import ccall "&exp" a_exp :: FunPtr (Double -> Double)<br />
</haskell><br />
<br />
Some foreign functions can also return function pointers.<br />
<br />
To call a function pointer from Haskell, GHC needs to convert between its own calling convention and the one expected by the foreign code. To create a function doing this conversion, you must use "dynamic" wrappers:<br />
<br />
<haskell><br />
foreign import ccall "dynamic" mkFun :: FunPtr (Double -> Double) -> (Double -> Double)<br />
</haskell><br />
<br />
Then you can apply this wrapper to a FunPtr to get a Haskell function:<br />
<br />
<haskell><br />
c_exp :: Double -> Double<br />
c_exp = mkFun a_exp<br />
</haskell><br />
<br />
You can also perform the opposite operation to give to the foreign code a pointer to a Haskell function. You need a "wrapper" wrapper. GHC generates the callable code to execute the wrapped Haskell closure with the appropriate calling convention and returns a pointer (FunPtr) on it. You have to release the generated code explicitly with `freeHaskellFunPtr` to avoid memory leaks: GHC has no way to know if the function pointer is still referenced in some foreign code, hence it doesn't collect it.<br />
<br />
<haskell><br />
add :: Int -> Int<br />
add = x+y<br />
<br />
foreign import ccall "wrapper" createAddPtr :: (Int -> Int) -> IO (FunPtr (Int -> Int))<br />
<br />
main = do<br />
addPtr <- createAddPtr add<br />
-- you can use addPtr like any other FunPtr (e.g. give it to foreign code)<br />
...<br />
-- you MUST free the FunPtr, otherwise it won't be collected<br />
freeHaskellFunPtr addPtr<br />
</haskell><br />
<br />
== Marshalling data ==<br />
<br />
In Haskell we are accustomed to let the runtime system -- especially the garbage collector -- manage memory. When we use the FFI, however, we sometimes need to do some manual memory management to comply with the data representations of the foreign codes. Hopefully, Haskell makes it very easy to manipulate low-level objects such as pointers. Moreover, many useful Haskell tools have been designed to simplify conversions between data representations.<br />
<br />
=== Pointers ===<br />
<br />
A pointer is an offset in memory. In Haskell, it is represented with the [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html Ptr a] data type. Where "a" is a phantom type that can be used to differentiate two pointers. You can think of "Ptr Stuff" as being equivalent to a "Stuff *" type in C (i.e. a pointer to a "Stuff" data). This analogy may not hold if "a" is a Haskell type not representable in the foreign language. For instance, you can have a pointer with the type "Ptr (Stuff -> OtherStuff)" but it is not function pointer in the foreign language: it is just a pointer tagged with the "Stuff -> OtherStuff" type.<br />
<br />
You can easily cast between pointer types using `castPtr` or perform pointer arithmetic using `plusPtr`, `minusPtr` and `alignPtr`. NULL pointer is represented with `nullPtr`.<br />
<br />
=== Memory allocation ===<br />
<br />
There are basically two ways to allocate memory:<br />
* on the Haskell heap, using `alloca*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
The allocation is ephemeral: it lasts the time of the execution of an IO action, as in the following example:<br />
<haskell><br />
do<br />
allocaBytes 128 $ \ptr -> do<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
-- do not return "ptr" in any way because it will become an invalid pointer<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
* on the "low-level" heap (the same as the runtime system uses), using `malloc*` functions in [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html Foreign.Marshal.Alloc]<br />
<br />
Allocations on the low-level heap are not managed by the Haskell implementation and must be freed explicitly with `free`.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
free ptr<br />
-- here the 128 bytes have been released and should not be accessed<br />
</haskell><br />
<br />
=== Foreign Pointers ===<br />
<br />
An hybrid approach is to use [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr ForeignPtr]. Foreign pointers are similar to Ptr except that they have finalizers (i.e. actions) attached to them. When the garbage collector detects that a ForeignPtr is no longer accessible, it executes its associated finalizers. A basic finalizer is `finalizerFree` [https://hackage.haskell.org/package/base/docs/Foreign-Marshal-Alloc.html] that calls `free` on the pointer.<br />
<br />
You can convert a Ptr into a ForeignPtr using `newForeignPtr`, add additional finalizers, etc. [https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#t:ForeignPtr].<br />
<br />
In the following example, we use `mallocForeignPtrBytes`. It is equivalent to call `malloc` and then to associate the `finalizerFree` finalizer with `newForeignPtr`. GHC has optimized implementations for `mallocForeignPtr*` functions, hence they should be preferred.<br />
<br />
<haskell><br />
do<br />
ptr <- mallocForeignPtrBytes 128<br />
-- do stuff with the pointer ptr...<br />
-- ...<br />
--<br />
-- ptr is freed when it is collected<br />
</haskell><br />
<br />
=== Using pointers: Storable instances ===<br />
<br />
You often want to read or to write at the address a of pointer. Reading consists in obtaining a Haskell value from a pointer; writing consists in somehow writing a representation of the Haskell value at the pointed address. Writing and reading a value depends on the type of the value, hence these methods are encapsulated into the [https://hackage.haskell.org/package/base/docs/Foreign-Storable.html Storable] type class.<br />
<br />
For any type T such that it exists a Storable T instance:<br />
* you can read a value, using <haskell>peek :: Ptr T -> IO T</haskell><br />
* you can write a value, using <haskell>poke :: Ptr T -> T -> IO ()</haskell><br />
<br />
`Storable a` also defines a `sizeOf :: a -> Int` method that returns the size of the stored value in bytes.<br />
<br />
All the ''marshallable foreign types'' (i.e. basic types) have Storable instances. Hence we can use these to write new Storable instances for more involved data types. In the following example, we create a Storable instance for a Complex data type:<br />
<br />
<haskell><br />
data Complex = Complex Double Double<br />
<br />
instance Storable Complex where<br />
sizeOf _ = 2 * sizeOf (undefined :: Double) -- stored complex size = 2 * size of a stored Double<br />
peek ptr = do<br />
real <- peek ptr<br />
img <- peekByteOff ptr (sizeOf real) -- we skip the bytes containing the real part<br />
return $ Complex real img<br />
poke ptr (Complex real img) = do<br />
poke ptr real<br />
pokeByteOff ptr (sizeOf real) img<br />
...<br />
</haskell><br />
<br />
This is not very complicated but it can become very cumbersome if our data type has many fields. Several tools have been developed to automatically or semi-automatically create the Storable instances.<br />
<br />
==== Renaming and Storable instances ====<br />
<br />
It is very common to use type renaming (i.e. newtype) to wrap a data type as in the following example, where we declare a type Pair that contains a pair of Double values just like our Complex type.<br />
<br />
<haskell><br />
newtype Pair = Pair Complex<br />
</haskell><br />
<br />
If we want to store Pair values exactly like Complex values, we have several possibilities:<br />
* unwrap the Complex value each time we want to use its Storable instance<br />
* create a new Storable Pair instance that does the same thing<br />
* automatically derive the Storable Pair instance<br />
<br />
The last solution is obviously the simplest one. It requires an extension however:<br />
<br />
<haskell><br />
{-# LANGUAGE GeneralizedNewtypeDeriving #-}<br />
<br />
newtype Pair = Pair Complex deriving (Storable)<br />
</haskell><br />
<br />
=== Arrays ===<br />
<br />
It is very common to read and to write arrays of values. [http://hackage.haskell.org/package/base/docs/Foreign-Marshal-Array.html Foreign.Marshal.Array] provides many functions to deal with pointers to arrays. You can easily write an Haskell list of storable values as an array of values, and vice versa.<br />
<br />
=== Strings ===<br />
<br />
Strings in Haskell are lists of Char, where Char represents a unicode character. Many foreign codes use the C representation for strings ([https://hackage.haskell.org/package/base/docs/Foreign-C-String.html CString] in Haskell): an array of bytes where each byte is a extended ASCII character terminated with a NUL character.<br />
<br />
In [https://hackage.haskell.org/package/base/docs/Foreign-C-String.html Foreign.C.String], you have many functions to convert between both representations. Be careful because Unicode characters outside of the ASCII range may not be representable with the C representation.<br />
<br />
<haskell><br />
foreign import ccall "echo" c_echo :: CString -> IO ()<br />
<br />
echo :: String -> IO ()<br />
echo str = withCString str $ \c_str -><br />
c_echo c_str<br />
</haskell><br />
<br />
=== Data structures ===<br />
<br />
Marshalling data structures of foreign languages is the most cumbersome task: you have to find out the offset of each field of the data structure (considering padding bytes, etc.). Hopefully, there are Haskell tools to help with this task.<br />
<br />
Suppose you have a C data structure like this:<br />
struct MyStruct {<br />
double d;<br />
char c;<br />
int32_t i;<br />
};<br />
<br />
And its Haskell counterpart:<br />
<haskell><br />
data MyStruct = MyStruct<br />
{ d :: Double<br />
, c :: Word8<br />
, i :: Int32<br />
}<br />
</haskell><br />
<br />
The following sub-sections present the different ways to write the Storable instance for MyStruct. <br />
<br />
The following header is implied:<br />
<haskell><br />
import Control.Applicative ((<$>), (<*>))<br />
import Foreign.Storable<br />
</haskell><br />
<br />
==== The explicit way ====<br />
<br />
<haskell><br />
instance Storable MyStruct where<br />
alignment _ = 8<br />
sizeOf _ = 16<br />
peek ptr = MyStruct<br />
<$> peekByteOff ptr 0<br />
<*> peekByteOff ptr 8<br />
<*> peekByteOff ptr 12 -- skip padding bytes after "c"<br />
poke ptr (MyStruct d c i) = do<br />
pokeByteOff ptr 0 d<br />
pokeByteOff ptr 8 c<br />
pokeByteOff ptr 12 i<br />
</haskell><br />
<br />
* The structure alignment is the least common multiple of the alignments of the structure fields. The alignment of primitive types is equal to their size in bytes (e.g. 8 for Double, 1 for Word8 and 4 for Word32). Hence the alignment for MyStruct is 8.<br />
<br />
* We indicate the offset of each field explicitly for peek and poke methods. We introduce padding bytes to align the "i" field (Word32) on 4 bytes. A C compiler does the same thing (except for packed structures).<br />
<br />
* The size of the structure is the total number of bytes, including padding bytes between fields.<br />
<br />
==== hsc2hs ====<br />
<br />
[https://downloads.haskell.org/~ghc/master/users-guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs hsc2hs] is a tool that can help you compute field offsets by using C headers directly.<br />
<br />
Save your Haskell file with a .hsc extension to enable the support of hsc2hs.<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> (#peek MyStruct, d) ptr<br />
<*> (#peek MyStruct, c) ptr<br />
<*> (#peek MyStruct, i) ptr<br />
...<br />
</haskell><br />
<br />
==== c2hs ====<br />
<br />
[https://hackage.haskell.org/package/c2hs c2hs] is another tool that can help you doing the same thing as hsc2hs for data structure marshalling. [http://stackoverflow.com/questions/6009031/difference-between-hsc2hs-and-c2hs They have differences in other aspects though].<br />
<br />
<haskell><br />
#include <myheader.h><br />
<br />
instance Storable MyStruct where<br />
peek ptr = MyStruct<br />
<$> {#get MyStruct->d} ptr<br />
<*> {#get MyStruct->c} ptr<br />
<*> {#get MyStruct->i} ptr<br />
...<br />
</haskell><br />
<br />
<br />
==== c-storable-deriving ====<br />
<br />
You can also derive the Storable instances from the types of the fields and their order in the Haskell data type by using [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving package].<br />
<br />
<haskell><br />
{-# LANGUAGE DeriveGeneric #-}<br />
<br />
import GHC.Generics (Generic)<br />
import Foreign.CStorable<br />
<br />
data MyStruct = MyStruct {...} deriving (Generic)<br />
<br />
instance CStorable MyStruct<br />
<br />
instance Storable MyStruct where<br />
sizeOf = cSizeOf<br />
alignment = cAlignment<br />
poke = cPoke<br />
peek = cPeek<br />
</haskell><br />
<br />
The CStorable type-class is equivalent to the Storable type-class but has additional default implementations for its methods if the type has an instance of Generic.<br />
<br />
=== Pointers to Haskell data ===<br />
<br />
In some cases, you may want to give to the foreign code an opaque reference to a Haskell value that you will retrieve later on. You need to be sure that the value is not collected between the time you give it and the time you retrieve it. [https://hackage.haskell.org/package/base/docs/Foreign-StablePtr.html Stable pointers] have been created exactly to do this. You can wrap a value into a StablePtr and give it to the foreign code (StablePtr is one of the marshallable foreign types).<br />
<br />
You need to manually free stable pointers using `freeStablePtr` when they are not required anymore.<br />
<br />
== Tools ==<br />
<br />
There are several tools to help writing bindings using the FFI. In particular by using C headers.<br />
<br />
=== Using C headers ===<br />
* [https://www.haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html hsc2hs]<br />
* [https://hackage.haskell.org/package/c2hs c2hs]<br />
* [http://hackage.haskell.org/package/bindings-DSL-1.0.22 bindings-DSL]<br />
* [http://hackage.haskell.org/package/c2hsc c2hsc]<br />
<br />
=== Haskell ===<br />
* [https://hackage.haskell.org/package/c-storable-deriving c-storable-deriving]<br />
<br />
=== Dynamic function call ===<br />
* [https://hackage.haskell.org/package/libffi libffi]: allow to call a C function without knowing its type at compile time.<br />
<br />
== Linking ==<br />
<br />
There are several ways for GHC to find the foreign code to link with:<br />
* Static linking: the foreign code binary object is merged with the Haskell one to form the final executable<br />
* Dynamic linking: the generated binary uses libraries (e.g. .dll or .so) that are automatically linked when the binary is executed<br />
* Explicit dynamic linking: the Haskell code explicitly loads libraries, finds symbols in them and makes calls to them<br />
<br />
The first two modes are well described in GHC and Cabal manuals. For the last one, you need to use platform dependent methods:<br />
* on UNIX, you can use [http://hackage.haskell.org/package/unix/docs/System-Posix-DynamicLinker.html System.Posix.DynamicLinker]<br />
<br />
Explicit dynamic linking helps you obtaining [https://hackage.haskell.org/package/base/docs/Foreign-Ptr.html#g:2 function pointers (FunPtr)]. You need to write "dynamic" wrappers to call the functions from Haskell.<br />
<br />
=== Dynamic linker template ===<br />
<br />
[https://hackage.haskell.org/package/dynamic-linker-template dynamic-linker-template] is a package that uses template Haskell to automatically generate "dynamic" wrappers for explicit dynamic linking (only supporting Unix for now).<br />
<br />
The idea is that a library is like a record containing functions, hence it is easy to generate the code that load symbols from a library and store them into a Haskell record.<br />
<br />
In the following code, the record matching library symbols is the data type MyLib. The generated code will apply "myModifier" to each field name of the record to find corresponding symbols in the library. myModifier should often be "id" but it is sometimes useful when symbols are not pretty. Here in the foreign code "_v2" is appended at the end of each symbol to avoid symbol clashes with the first version of the library.<br />
<br />
The package supports optional symbols: functions that may or may not be present in the library. These optional functions are represented by encapsulating the function type into Maybe.<br />
<br />
The `libHandle` field is mandatory and contains a pointer to the loaded library. You can use it to unload the library.<br />
<br />
A function called `loadMyLib` is generated to load symbols from a library, wrap them using "dynamic" wrappers and store them into a MyLib value that is returned.<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell, ForeignFunctionInterface #-}<br />
<br />
import System.Posix.DynamicLinker.Template<br />
<br />
data MyLib = MyLib {<br />
libHandle :: DL,<br />
thing1 :: Double -> IO Int, -- Mandatory symbol<br />
thing2 :: Maybe (Int -> Int -> Int) -- Optional symbol<br />
}<br />
<br />
myModifier :: String -> String<br />
myModifier = (++ "_v2")<br />
<br />
$(makeDynamicLinker ''MyLib CCall 'myModifier)<br />
<br />
-- Load your library with:<br />
-- loadMyLib :: FilePath -> [RTLDFlags] -> IO MyLib<br />
</haskell><br />
<br />
== Enhancing performance and advanced topics ==<br />
<br />
To enhance performance of a call to a foreign function, you first need to understand how GHC runtime system works. GHC uses user-space threads. It uses a set of system threads (called "Tasks"). Each system thread can execute a "capability" (i.e. a user-space thread manager). User-space threads are distributed on capabilities. Each capability executes its associated user-space threads, one at a time, using cooperative scheduling or preemption if necessary.<br />
<br />
All the capabilities have to synchronize to perform garbage collection.<br />
<br />
When a FFI call is made:<br />
* the user-space thread is suspended (indicating it is waiting for the result of a foreign call)<br />
* the current system thread executing the capability executing the user-space thread releases the capability<br />
** the capability can be picked up by another system thread<br />
** the user-space threads that are not suspended in the capability can be executed<br />
** garbage collection can occur<br />
* the system thread executes the FFI call<br />
* when the FFI call returns, the user-space thread is woken up<br />
<br />
If there are too many blocked system threads, the runtime system can spawn new ones.<br />
<br />
=== Unsafe calls ===<br />
<br />
All the capability management before and after a FFI call adds some overhead. It is possible to avoid it in some cases by adding the "unsafe" keyword as in the following example:<br />
<br />
<haskell><br />
foreign import ccall unsafe "exp" c_exp :: Double -> Double<br />
</haskell><br />
<br />
By doing this, the foreign code will be directly called but the capability won't be released by the system thread during the call. Here are the drawbacks of this approach:<br />
* if the foreign function blocks indefinitely, the other user-space threads of the capability won't be executed anymore (deadlock)<br />
* if the foreign code calls back into the Haskell code, a deadlock may occur<br />
** it may wait for a value produced by one of the locked user-space threads on the capability<br />
** there may not be enough capabilities to execute the code<br />
<br />
=== Foreign PrimOps ===<br />
<br />
If unsafe foreign calls are not fast enough for you, you can try the GHCForeignImportPrim extension.<br />
<br />
<haskell><br />
{-# LANGUAGE GHCForeignImportPrim,<br />
MagicHash,<br />
UnboxedTuples,<br />
UnliftedFFITypes #-}<br />
<br />
import GHC.Base<br />
import GHC.Int<br />
<br />
-- Primitive with type :: Int -> Int -> IO Int<br />
foreign import prim "my_primop_cmm"<br />
my_primop# :: Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #)<br />
<br />
my_primop :: Int64 -> Int64 -> IO Int64<br />
my_primop (I64# x) (I64# y) = IO $ \s -><br />
case (my_primop# x y s) of (# s1, r #) -> (# s1, I64# r #)<br />
</haskell><br />
<br />
Then you have to write your foreign function "my_primop_cmm" using [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CmmType C--] language used internally by GHC.<br />
<br />
As an alternative, if you know how C-- is compiled on your architecture, you can write code in other languages. For instance [https://github.com/hsyl20/haskus-system/blob/fa9a4057c38f1e2808ba570eb57636c51a809c29/src/lib/Haskus/Arch/X86_64/Linux/syscall.c#L95 directly in assembly] or [http://breaks.for.alienz.org/blog/2012/02/09/parsing-market-data-feeds-with-ragel/ using C and LLVM].<br />
<br />
[http://breaks.for.alienz.org/blog/2012/05/23/ffi-vs-primops/ Here] is a comparison of the different approaches on a specific case.<br />
<br />
=== Bound threads ===<br />
<br />
Some foreign codes use (system) thread-local storage. Some others are not thread-safe. In both case, you have to be sure that the same '''system thread''' executes the FFI calls. To control how user-space threads are scheduled on system threads, GHC provide [http://hackage.haskell.org/package/base/docs/Control-Concurrent.html#g:8 bound threads]. Bound threads are user-space threads (Haskell threads) that can only be executed by a single system thread.<br />
<br />
Note that bound threads are more expensive to schedule than normal threads. The first thread executing "main" is a bound thread.<br />
<br />
=== Inline FFI calls ===<br />
<br />
If you want to make a one-shot FFI call without the hassle of writing the foreign import, you can use the following technique (using Template Haskell).<br />
<br />
In AddTopDecls.hs:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module AddTopDecls where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
importDoubleToDouble :: String -> ExpQ<br />
importDoubleToDouble fname = do<br />
n <- newName fname<br />
d <- forImpD CCall unsafe fname n [t|Double -> Double|]<br />
addTopDecls [d]<br />
[|$(varE n)|]<br />
</haskell><br />
<br />
In your module:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
module Main where<br />
<br />
import Language.Haskell.TH<br />
import Language.Haskell.TH.Syntax<br />
<br />
import AddTopDecls<br />
<br />
main :: IO ()<br />
main = do<br />
print ($(importDoubleToDouble "sin") pi)<br />
print ($(importDoubleToDouble "cos") pi)<br />
</haskell><br />
<br />
== History ==<br />
<br />
=== Header inclusion ===<br />
<br />
In old versions of GHC (6.8.3 and earlier), the compiler was able to check the prototypes of the foreign imports by including C header files into the generated C code. For instance, you could write:<br />
<haskell><br />
{-# INCLUDE <math.h> #-}<br />
</haskell><br />
or <br />
<haskell><br />
foreign import ccall "math.h sin" c_sin :: Double -> Double<br />
</haskell><br />
to include the "math.h" header.<br />
<br />
This is deprecated in GHC. Nevertheless you may still find examples using this syntax so it is good to know that it has been used. Moreover, other compilers may still use this feature.<br />
<br />
* Justification of the deprecation from the [http://www.haskell.org/ghc/docs/6.10.1/html/users_guide/ffi-ghc.html#glasgow-foreign-headers GHC 6.10.1 manual]:<br />
<br />
"C functions are normally declared using prototypes in a C header file. Earlier versions of GHC (6.8.3 and earlier) #included the header file in the C source file generated from the Haskell code, and the C compiler could therefore check that the C function being called via the FFI was being called at the right type.<br />
<br />
GHC no longer includes external header files when compiling via C, so this checking is not performed. The change was made for compatibility with the native code backend (-fasm) and to comply strictly with the FFI specification, which requires that FFI calls are not subject to macro expansion and other CPP conversions that may be applied when using C header files. This approach also simplifies the inlining of foreign calls across module and package boundaries: there's no need for the header file to be available when compiling an inlined version of a foreign call, so the compiler is free to inline foreign calls in any context.<br />
<br />
The -#include option is now deprecated, and the include-files field in a Cabal package specification is ignored."<br />
<br />
* [http://www.haskell.org/ghc/docs/6.8.3/html/users_guide/ffi-ghc.html#glasgow-foreign-headers Documentation of this feature in the GHC 6.8.3 manual]<br />
<br />
<br />
<br />
== References ==<br />
<br />
* FFI addendum<br />
* The [http://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1490008 Foreign Function Interface section] of the Haskell 2010 report<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html FFI chapter in the GHC user guide]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/ "Tackling the awkward squad" paper]<br />
* [http://community.haskell.org/~simonmar/papers/conc-ffi.pdf "Extending the Haskell FFI with Concurrency" paper] (the number of capabilities is now greater than 1)<br />
* http://blog.melding-monads.com/2011/10/24/concurrency-and-foreign-functions-in-the-glasgow-haskell-compiler/<br />
<br />
<br />
=== Related links ===<br />
<br />
* [https://github.com/GaloisInc/ivory Ivory]: EDSL for writing safer low-level C.<br />
<br />
=== Old links ===<br />
<br />
Select one of the following links for more information:<br />
* [[FFI Introduction]]<br />
* GHC manual: [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs Writing Haskell interfaces to C code: hsc2hs]<br />
* [https://github.com/ifesdjeen/haskell-ffi-tutorial haskell-ffi-tutorial] at GitHub<br />
* The official description: chapters 8 and 24 to 37 of [http://www.haskell.org/onlinereport/haskell2010/#QQ2-15-159 The Haskell 2010 Language Report] (a draft: [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ The Haskell 98 Foreign Function Interface 1.0. An Addendum to the Haskell 98 Report])<br />
* [[FFI cook book]]<br />
* [[FFI complete examples]]<br />
* [[GHC/Using the FFI]]<br />
* [http://research.microsoft.com/~simonpj/papers/marktoberdorf/ Tackling the awkward squad]<br />
* [https://github.com/wavewave/fficxx fficxx], a Haskell-C++ Foreign Function Interface Generator<br />
* [[Applications and libraries/Interfacing other languages]]<br />
* [http://rosettacode.org/wiki/Use_another_language_to_call_a_function#Haskell Use another language to call a function; Haskell]<br />
* [https://code.google.com/p/tabi/ TABI] a typeful tagged cross-language calling convention<br />
<br />
=== Blog articles ===<br />
<br />
* [http://www.serpentine.com/blog/2010/09/04/dealing-with-fragile-c-libraries-e-g-mysql-from-haskell/ Dealing with fragile C libraries (e.g. MySQL) from Haskell] <br />
* [http://blog.danieroux.com/2007/01/01/simple-demonstration-of-haskell-ffi/ Simple demonstration of Haskell FFI]<br />
* [http://therning.org/magnus/posts/2006-12-08-238-c-and-haskell-sitting-in-a-tree.html C and Haskell sitting in a tree…]<br />
* [http://vis.renci.org/jeff/2009/07/10/c2hs-example-to-save-other-people-frustration/ C2HS example: To save other people frustration] <br />
* [[Cxx foreign function interface]]; how to link to a C++ library<br />
* [http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/ Safety first: FFI and threading]<br />
<br />
== TODO ==<br />
<br />
* Fix References section<br />
<br />
* Foreign language specific issues<br />
** C++ symbol mangling<br />
** Embedded Objective C<br />
<br />
* Precision<br />
<br />
<code>The Haskell report only guarantees that Int has 30 bits of signed precision, so converting CInt to Int is not safe! On the other hand, many classes have instances for Int and Integer but not CInt, so it's generally more convenient to convert from the C types. To convert, I suppose you could either write a 'checkedFromIntegral' function if you're sure it's small or just use Integer.</code><br />
<br />
* Fix [https://wiki.haskell.org/C2hs]<br />
** One page per tool?<br />
** Links to external tool specific tutorials<br />
<br />
* Linking<br />
** pkgconfig<br />
** cabal<br />
** explicit (ghc parameters)<br />
** cf http://stackoverflow.com/questions/4959802/how-to-specify-dependency-on-external-c-library-in-cabal<br />
<br />
[[Category:FFI]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62595Template Haskell2018-08-26T22:09:56Z<p>Henk-Jan van Tuyl: /* Instance deriving example */ Updated link</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** https://web.archive.org/web/20170331032455/www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [https://web.archive.org/web/20120208093803/http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: <nowiki>http://www.ScannedInAvian.org/repos/hacanon</nowiki> - You'll need gccxml (<nowiki>http://www.gccxml.org/</nowiki>) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on <nowiki>http://www.gill-warbington.com/home/andy/share/hera1.html</nowiki> - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([https://web.archive.org/web/20120206061801/www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses [[Scrap your boilerplate]] (SYB) to address some of the pain of dealing with the rather large data types. We define <tt>mkOptional</tt> so that given a data type <tt><datatype></tt> it generates a new data type <tt><datatype>_opt</tt> that is like <tt><datatype></tt>, but where each record field <tt><field> :: <type></tt> is changed to <tt><field>_opt :: Maybe <type></tt>, and all types <tt><type></tt> that are defined in the same module <tt><datatype></tt> are replaced with <tt><type>_opt</tt>.<br />
<br />
First an example of using <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
<br />
data Foo = Foo { a :: Double<br />
, f :: Int }<br />
data Bar = Bar { x :: Foo<br />
, y :: String }<br />
<br />
mapM mkOptional [''Foo, ''Bar]<br />
</haskell><br />
<br />
The above generates the following new types <tt>Foo_opt</tt> and <tt>Bar_opt</tt>:<br />
<haskell><br />
data Foo_opt = Foo_opt { a_opt :: Maybe Double<br />
, f_opt :: Maybe Int }<br />
data Bar_opt = Bar_opt { x_opt :: Maybe Foo_opt<br />
, y_opt :: Maybe String }<br />
</haskell><br />
Note that <tt>x_opt</tt> has type <tt>Maybe Foo_opt</tt>, and not type <tt>Maybe Foo</tt>.<br />
<br />
Here is the implementation of <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybesAndOpts :: Maybe String -> Dec -> Q Dec<br />
addMaybesAndOpts modName dec =<br />
-- Apply @rename@ and @addMaybe@ everywhere in the<br />
-- declaration @dec@.<br />
--<br />
-- The SYB, @everywhere (mkT (f :: a -> a)) (x :: b)@<br />
-- applies @f@ to all data of type @a@ in @x@, and<br />
-- @everywhereM (mkM (f :: a -> m a) (x :: b)@ is<br />
-- similar, but applies @f@ everywhere in @x@ monadically.<br />
everywhere (mkT rename) <$><br />
everywhereM (mkM addMaybe) dec<br />
where<br />
-- Add the "_opt" suffix to a name, if it's from<br />
-- the given module.<br />
rename :: Name -> Name<br />
rename n = if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
-- Wrap the type of a record field in @Maybe@.<br />
addMaybe :: (Name, Strict, Type) -> Q (Name, Strict, Type)<br />
addMaybe (n, s, ty) = do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI dec <- reify n<br />
addMaybesAndOpts (nameModule n) dec<br />
</haskell><br />
<br />
<br />
[[Category:Language extensions]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62594Template Haskell2018-08-26T22:08:15Z<p>Henk-Jan van Tuyl: /* Projects */ Added <nowiki> because sites no longer exist</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** https://web.archive.org/web/20170331032455/www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [https://web.archive.org/web/20120208093803/http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: <nowiki>http://www.ScannedInAvian.org/repos/hacanon</nowiki> - You'll need gccxml (<nowiki>http://www.gccxml.org/</nowiki>) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on <nowiki>http://www.gill-warbington.com/home/andy/share/hera1.html</nowiki> - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses [[Scrap your boilerplate]] (SYB) to address some of the pain of dealing with the rather large data types. We define <tt>mkOptional</tt> so that given a data type <tt><datatype></tt> it generates a new data type <tt><datatype>_opt</tt> that is like <tt><datatype></tt>, but where each record field <tt><field> :: <type></tt> is changed to <tt><field>_opt :: Maybe <type></tt>, and all types <tt><type></tt> that are defined in the same module <tt><datatype></tt> are replaced with <tt><type>_opt</tt>.<br />
<br />
First an example of using <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
<br />
data Foo = Foo { a :: Double<br />
, f :: Int }<br />
data Bar = Bar { x :: Foo<br />
, y :: String }<br />
<br />
mapM mkOptional [''Foo, ''Bar]<br />
</haskell><br />
<br />
The above generates the following new types <tt>Foo_opt</tt> and <tt>Bar_opt</tt>:<br />
<haskell><br />
data Foo_opt = Foo_opt { a_opt :: Maybe Double<br />
, f_opt :: Maybe Int }<br />
data Bar_opt = Bar_opt { x_opt :: Maybe Foo_opt<br />
, y_opt :: Maybe String }<br />
</haskell><br />
Note that <tt>x_opt</tt> has type <tt>Maybe Foo_opt</tt>, and not type <tt>Maybe Foo</tt>.<br />
<br />
Here is the implementation of <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybesAndOpts :: Maybe String -> Dec -> Q Dec<br />
addMaybesAndOpts modName dec =<br />
-- Apply @rename@ and @addMaybe@ everywhere in the<br />
-- declaration @dec@.<br />
--<br />
-- The SYB, @everywhere (mkT (f :: a -> a)) (x :: b)@<br />
-- applies @f@ to all data of type @a@ in @x@, and<br />
-- @everywhereM (mkM (f :: a -> m a) (x :: b)@ is<br />
-- similar, but applies @f@ everywhere in @x@ monadically.<br />
everywhere (mkT rename) <$><br />
everywhereM (mkM addMaybe) dec<br />
where<br />
-- Add the "_opt" suffix to a name, if it's from<br />
-- the given module.<br />
rename :: Name -> Name<br />
rename n = if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
-- Wrap the type of a record field in @Maybe@.<br />
addMaybe :: (Name, Strict, Type) -> Q (Name, Strict, Type)<br />
addMaybe (n, s, ty) = do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI dec <- reify n<br />
addMaybesAndOpts (nameModule n) dec<br />
</haskell><br />
<br />
<br />
[[Category:Language extensions]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62593Template Haskell2018-08-26T21:49:54Z<p>Henk-Jan van Tuyl: /* Other useful resources */ Updated link</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** https://web.archive.org/web/20170331032455/www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [https://web.archive.org/web/20120208093803/http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses [[Scrap your boilerplate]] (SYB) to address some of the pain of dealing with the rather large data types. We define <tt>mkOptional</tt> so that given a data type <tt><datatype></tt> it generates a new data type <tt><datatype>_opt</tt> that is like <tt><datatype></tt>, but where each record field <tt><field> :: <type></tt> is changed to <tt><field>_opt :: Maybe <type></tt>, and all types <tt><type></tt> that are defined in the same module <tt><datatype></tt> are replaced with <tt><type>_opt</tt>.<br />
<br />
First an example of using <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
<br />
data Foo = Foo { a :: Double<br />
, f :: Int }<br />
data Bar = Bar { x :: Foo<br />
, y :: String }<br />
<br />
mapM mkOptional [''Foo, ''Bar]<br />
</haskell><br />
<br />
The above generates the following new types <tt>Foo_opt</tt> and <tt>Bar_opt</tt>:<br />
<haskell><br />
data Foo_opt = Foo_opt { a_opt :: Maybe Double<br />
, f_opt :: Maybe Int }<br />
data Bar_opt = Bar_opt { x_opt :: Maybe Foo_opt<br />
, y_opt :: Maybe String }<br />
</haskell><br />
Note that <tt>x_opt</tt> has type <tt>Maybe Foo_opt</tt>, and not type <tt>Maybe Foo</tt>.<br />
<br />
Here is the implementation of <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybesAndOpts :: Maybe String -> Dec -> Q Dec<br />
addMaybesAndOpts modName dec =<br />
-- Apply @rename@ and @addMaybe@ everywhere in the<br />
-- declaration @dec@.<br />
--<br />
-- The SYB, @everywhere (mkT (f :: a -> a)) (x :: b)@<br />
-- applies @f@ to all data of type @a@ in @x@, and<br />
-- @everywhereM (mkM (f :: a -> m a) (x :: b)@ is<br />
-- similar, but applies @f@ everywhere in @x@ monadically.<br />
everywhere (mkT rename) <$><br />
everywhereM (mkM addMaybe) dec<br />
where<br />
-- Add the "_opt" suffix to a name, if it's from<br />
-- the given module.<br />
rename :: Name -> Name<br />
rename n = if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
-- Wrap the type of a record field in @Maybe@.<br />
addMaybe :: (Name, Strict, Type) -> Q (Name, Strict, Type)<br />
addMaybe (n, s, ty) = do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI dec <- reify n<br />
addMaybesAndOpts (nameModule n) dec<br />
</haskell><br />
<br />
<br />
[[Category:Language extensions]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62592Template Haskell2018-08-26T21:46:19Z<p>Henk-Jan van Tuyl: /* Template Haskell tutorials and papers */ Updated link</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** https://web.archive.org/web/20170331032455/www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses [[Scrap your boilerplate]] (SYB) to address some of the pain of dealing with the rather large data types. We define <tt>mkOptional</tt> so that given a data type <tt><datatype></tt> it generates a new data type <tt><datatype>_opt</tt> that is like <tt><datatype></tt>, but where each record field <tt><field> :: <type></tt> is changed to <tt><field>_opt :: Maybe <type></tt>, and all types <tt><type></tt> that are defined in the same module <tt><datatype></tt> are replaced with <tt><type>_opt</tt>.<br />
<br />
First an example of using <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
<br />
data Foo = Foo { a :: Double<br />
, f :: Int }<br />
data Bar = Bar { x :: Foo<br />
, y :: String }<br />
<br />
mapM mkOptional [''Foo, ''Bar]<br />
</haskell><br />
<br />
The above generates the following new types <tt>Foo_opt</tt> and <tt>Bar_opt</tt>:<br />
<haskell><br />
data Foo_opt = Foo_opt { a_opt :: Maybe Double<br />
, f_opt :: Maybe Int }<br />
data Bar_opt = Bar_opt { x_opt :: Maybe Foo_opt<br />
, y_opt :: Maybe String }<br />
</haskell><br />
Note that <tt>x_opt</tt> has type <tt>Maybe Foo_opt</tt>, and not type <tt>Maybe Foo</tt>.<br />
<br />
Here is the implementation of <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybesAndOpts :: Maybe String -> Dec -> Q Dec<br />
addMaybesAndOpts modName dec =<br />
-- Apply @rename@ and @addMaybe@ everywhere in the<br />
-- declaration @dec@.<br />
--<br />
-- The SYB, @everywhere (mkT (f :: a -> a)) (x :: b)@<br />
-- applies @f@ to all data of type @a@ in @x@, and<br />
-- @everywhereM (mkM (f :: a -> m a) (x :: b)@ is<br />
-- similar, but applies @f@ everywhere in @x@ monadically.<br />
everywhere (mkT rename) <$><br />
everywhereM (mkM addMaybe) dec<br />
where<br />
-- Add the "_opt" suffix to a name, if it's from<br />
-- the given module.<br />
rename :: Name -> Name<br />
rename n = if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
-- Wrap the type of a record field in @Maybe@.<br />
addMaybe :: (Name, Strict, Type) -> Q (Name, Strict, Type)<br />
addMaybe (n, s, ty) = do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI dec <- reify n<br />
addMaybesAndOpts (nameModule n) dec<br />
</haskell><br />
<br />
<br />
[[Category:Language extensions]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=GHC&diff=62591GHC2018-08-26T21:42:52Z<p>Henk-Jan van Tuyl: /* Documentation */ Removed link to users_guide.ps, as it no longer exists</p>
<hr />
<div>The '''Glasgow Haskell Compiler''' is a state-of-the-art, open source compiler and interactive environment for the functional language Haskell.<br />
<br />
* [http://www.haskell.org/ghc/ The GHC Home Page]<br />
<br />
== Documentation ==<br />
<br />
The documentation below relates to ''using'' GHC. For documentation about GHC's internals and building GHC, head over to the [http://hackage.haskell.org/trac/ghc GHC Developer Wiki].<br />
<br />
These documents relate to the ''latest released'' version of GHC.<br />
For ''earlier released'' versions click the relevant version on the<br />
[http://www.haskell.org/ghc/download downloads page]. <br />
For release candidates, look at <br />
[http://downloads.haskell.org/~ghc/ the GHC download directory].<br />
<br />
; [http://www.haskell.org/ghc/docs/latest/html/users_guide/index.html The User's Guide]: The User's Guide has all you need to know about using GHC: command line options, language extensions, GHCi, etc.<br />
: Download: | [http://www.haskell.org/ghc/docs/latest/users_guide.html.tar.xz HTML.tar.xz] | [http://www.haskell.org/ghc/docs/latest/users_guide.pdf PDF] |<br />
<br />
; [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html Standard Libraries]: Documentation for the libraries that come with GHC.<br />
: Download: | [http://www.haskell.org/ghc/docs/latest/libraries.html.tar.xz HTML.tar.xz]<br />
<br />
; [http://www.haskell.org/cabal/users-guide/ Cabal]: An infrastructure for building and distributing Haskell software.<br />
<br />
== Collaborative documentation ==<br />
<br />
GHC is a big system. We try to document the core functionality (above), but<br />
you can help by writing documentation yourself. This section collects<br />
documentation written in a collaborative way, by users and developers together.<br />
Please help by adding new sections, and by clarifying and improving existing ones.<br />
<br />
* Using GHC<br />
** [[How_to_write_a_Haskell_program|How to write a Haskell program]]<br />
** [[/FAQ|GHC FAQ]]<br />
** [[/Error messages|Error messages]]<br />
** [[Upgrading_packages|Guidelines for upgrading your GHC]]<br />
** [[/GHCi|Using GHCi]]<br />
** [[/GHCi debugger| The GHCi debugger]]<br />
** [[Cabal|Using Cabal]] (including with DLLs)<br />
** The [[Performance|Haskell Performance Resource]], for advice on improving the performance of your code<br />
** [[Mutually recursive modules]]<br />
** [[/Memory_Management| Memory management and garbage collection]]<br />
** [[/Memory Footprint|Memory footprint on the heap of common data-structures]]<br />
** [[Evaluation order and state tokens]]<br />
** [[Inlining and Specialisation]]<br />
* Platform related matters<br />
** [[GHC under WINE|Running GHC under Wine]]<br />
** [[Mac OS X]]<br />
** [[Windows]]<br />
*** [http://haskell.forkio.com/dotnet Using GHC with .NET]<br />
*** [http://haskell.forkio.com/gmpwindows Dynamically linking GMP on Windows]<br />
<br />
* GHC extensions<br />
** [[/Type system|Type system extensions in GHC]]<br />
** [[/As a library|Using GHC as a library]]<br />
** [[/Concurrency|Concurrent programming in GHC]]<br />
** [https://ocharles.org.uk/blog/pages/2014-12-01-24-days-of-ghc-extensions.html 24 Days of GHC Extensions], a series of blog articles.<br />
** [[Template Haskell]] is a (GHC) extension to Haskell that adds compile-time metaprogramming facilities.<br />
** [[Quasiquotation]] allows the ability for user-definable parsers to provide new concrete syntax for any datatype.<br />
** [https://web.archive.org/web/20110429002539/http://www.cse.unsw.edu.au:80/~dons/hs-plugins/ Dynamically loaded Haskell modules]: Don Stewart's <tt>hs-plugins</tt> library (Web Archive)<br />
** [[/Using the FFI|Using the Foreign Function Interface]]<br />
** [[/GUI programming|GUI programming in GHC]]<br />
** [[/Using rules|Using RULES in GHC]]<br />
** [[GHC/Data Parallel Haskell|Data Parallel Haskell: using nested data parallelism in GHC]]<br />
** [[Roles]] are GHC's way of discerning the difference between compile-time type equality (created by type synonyms and type families) and runtime type equality (created by newtypes).<br />
<br />
* [[Correctness of short cut fusion]]<br />
<br />
== Development of GHC ==<br />
<br />
See the [http://hackage.haskell.org/trac/ghc GHC Developer Wiki]. The latest snapshot of the documentation for the next version can be found [http://haskell.org/ghc/dist/current/docs/ here].<br />
<br />
* [http://takenobu-hs.github.io/downloads/ghc_development_flow.pdf GHC development flow] ([https://github.com/takenobu-hs/ghc-development-flow GitHub])<br />
<br />
[[Category:Implementations]]<br />
[[Category:GHC]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=Performance&diff=62590Performance2018-08-26T21:39:50Z<p>Henk-Jan van Tuyl: Updated link</p>
<hr />
<div>{{Performance infobox}}<br />
Welcome to the '''Haskell Performance Resource''', the collected wisdom on how to make your Haskell programs go faster. <br />
<br />
== Introduction ==<br />
<br />
One question that often comes up is along the general lines of "Can I write this program in Haskell so that it performs as well as, or better than, the same program written in some other language?"<br />
<br />
This is a difficult question to answer in general because Haskell is a language, not an implementation. Performance can only be measured relative to a specific language implementation.<br />
<br />
Moreover, it's often not clear if two programs which supposedly have the same functionality really do the same thing. Different languages sometimes require very different ways of expressing the same intent. Certain types of bug are rare in typical Haskell programs that are more common in other languages and vice versa, due to strong typing, automatic memory management and lazy evaluation.<br />
<br />
Nonetheless, it is usually possible to write a Haskell program that performs as well as, or better than, the same program written in any other language. The main caveat is that you may have to modify your code significantly in order to improve its performance. Compilers such as GHC are good at eliminating layers of abstraction, but they aren't perfect, and often need some help. <br />
<br />
There are many non-invasive techniques: compiler options, for example. Then there are techniques that require adding some small amounts of performance cruft to your program: strictness annotations, for example. If you still don't get the best performance, though, it might be necessary to resort to larger refactorings.<br />
<br />
Sometimes the code tweaks required to get the best performance are non-portable, perhaps because they require language extensions that aren't implemented in all compilers (e.g. unboxing), or because they require using platform-specific features or libraries. This might not be acceptable in your setting.<br />
<br />
If the worst comes to the worst, you can always write your critical code in C and use the FFI to call it. Beware of the boundaries though - marshaling data across the FFI can be expensive, and multi-language memory management can be complex and error-prone. It's usually better to stick to Haskell if possible.<br />
<br />
== Basic techniques ==<br />
<br />
The key tool to use in making your Haskell program run faster is ''profiling''. Profiling is provided by [[GHC]] and [[nhc98]]. There is ''no substitute'' for finding where your program's time/space is ''really'' going, as opposed to where you imagine it is going.<br />
<br />
Another point to bear in mind: By far the best way to improve a program's performance ''dramatically'' is to use better algorithms. Once profiling has thrown the spotlight on the guilty time-consumer(s), it may be better to re-think your program than to try all the tweaks listed below.<br />
<br />
Another extremely efficient way to make your program snappy is to use library code that has been Seriously Tuned By Someone Else. You ''might'' be able to write a better sorting function than the one in <tt>Data.List</tt>, but it will take you much longer than typing <tt>import Data.List</tt>.<br />
<br />
We have chosen to organise the rest of this resource first by Haskell construct (data types, pattern matching, integers), and then within each category to describe techniques that apply across implementations, and also techniques that are specific to a certain Haskell implementation (e.g. GHC). There are some implementation-specific techniques that apply in general - those are linked from the [[Haskell Performance Resource#General_Implementation-Specific_Techniques | General Implementation-Specific Techniques]] section below.<br />
<br />
== Haskell constructs ==<br />
<br />
* [[/Data Types/]]<br />
* [[/Functions/]]<br />
* [[/Overloading/]]<br />
* [[/FFI/]]<br />
* [[/Arrays/]]<br />
* [[/Strings/]]<br />
* [[/Integers/]]<br />
* [[/IO | I/O ]]<br />
* [[/Floating Point/]]<br />
* [[/Concurrency/]]<br />
* [[/Modules/]]<br />
* [[/Monads/]]<br />
<br />
== General techniques ==<br />
<br />
The most important thing for a beginner to keep in mind is that Haskell programs are evaluated using [[lazy evaluation]], which has many advantages, but also drawbacks when it comes to performance. The rule of thumb is that if you really want to have explicit control over the evaluation, then you should try to avoid it.<br />
<br />
* [[/Strictness/]]<br />
* [[/Laziness/]]<br />
* [[/Space | Avoiding space leaks]]<br />
* [[/Accumulating parameter|Accumulating parameters]]<br />
* [[Stack_overflow|Avoiding stack overflow]]<br />
<br />
== Benchmarking libraries ==<br />
<br />
The [[Criterion]] library is used often to generate detailed benchmark results.<br />
<br />
* [http://www.serpentine.com/blog/2009/09/29/criterion-a-new-benchmarking-library-for-haskell/ Introductory blog post]<br />
* [http://www.stackbuilders.com/news/obverse-versus-reverse-benchmarking-in-haskell-with-criterion Simple example of using Criterion]<br />
<br />
== Compiler specific techniques ==<br />
<br />
* [[/GHC/]]<br />
* [[/NHC98| nhc98]]<br />
* [[/Hugs/]]<br />
* [[/Yhc/]]<br />
* [[/JHC/]]<br />
<br />
== More information ==<br />
<br />
* [https://two-wrongs.com/on-competing-with-c-using-haskell On Competing with C Using Haskell]<br />
<br />
* [http://www.well-typed.com/blog/2016/09/sharing-conduit/ Sharing, Memory Leaks, and Conduit and friends], 2016. Edsko's war stories. Sharing conduit values leads to memory leaks. Make sure to disable the full laziness optimization in the module with your top-level calls to <tt>runConduit</tt> or <tt>($$)</tt>. Similar considerations apply to other streaming libraries and indeed any Haskell code that uses lazy data structures to drive computation. <br />
<br />
* [https://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/ Haskell as fast as C: working at a high altitude for low level performance]<br />
<br />
* [http://www.randomhacks.net/2007/01/22/high-performance-haskell/ High-Performance Haskell] ([http://www.slideshare.net/tibbe/highperformance-haskell Slide deck])<br />
<br />
* [http://lambda.jstolarek.com/2013/04/haskell-as-fast-as-c-a-case-study/ Haskell as fast as C: A case study]<br />
<br />
* [https://www.youtube.com/watch?v=McFNkLPTOSY&feature=youtu.be Dan Doel - Introduction to Low Level Haskell Optimization]; a video of Dan Doel's talk at the Boston Haskell Meetup, Sept 17, 2014 ([http://hub.darcs.net/dolio/optimization-talk-demo/browse/slides/slides.md slides]).<br />
<br />
* Don Stewart's [http://stackoverflow.com/questions/3276240/tools-for-analyzing-performance-of-a-haskell-program/3276557#3276557 Haskell performance overview] on StackOverflow (2013)<br />
<br />
* There are plenty of good examples of Haskell code written for performance in the [https://benchmarksgame-team.pages.debian.net/benchmarksgame/ The Computer Language Benchmarks Game]<br />
<br />
* And many alternatives, with discussion, on this wiki: [[Benchmarks Game]] and on the [http://web.archive.org/web/20060209215702/http://haskell.org/hawiki/ShootoutEntry old Haskell wiki] (in the Web Archive)<br />
<br />
* There are ~100 [http://blog.johantibell.com/2010/09/slides-from-my-high-performance-haskell.html slides on High-Performance Haskell] from the 2010 CUFP tutorial on that topic.<br />
<br />
== Specific comparisons of data structures ==<br />
<br />
=== Ropes ===<br />
<br />
For modifying very long strings, a [https://en.wikipedia.org/wiki/Rope_(data_structure) rope data structure] is very efficient. The [https://hackage.haskell.org/package/rope rope] package provides these.<br />
<br />
=== Data.Sequence vs. lists ===<br />
<br />
Data.Sequence has complexity O(log(min(i,n-i))) for access, insertion and update to position i of a sequence of length n.<br />
<br />
List has complexity O(i).<br />
<br />
List is a non-trivial constant-factor faster for operations at the head (cons and head), making it a more efficient choice for stack-like and stream-like access patterns. Data.Sequence is faster for every other access pattern, such as queue and random access.<br />
<br />
See the following program for proof:<br />
<haskell><br />
import Data.Sequence<br />
<br />
insert_million 0 sequence = sequence<br />
insert_million n sequence = insert_million (n - 1)(sequence |> n)<br />
<br />
main = print (Data.Sequence.length (insert_million 1000000 empty))<br />
</haskell><br />
<pre><br />
$ ghc -O2 --make InsertMillionElements.hs && time ./InsertMillionElements +RTS -K100M<br />
1000000<br />
real 0m7.238s<br />
user 0m6.804s<br />
sys 0m0.228s<br />
</pre><br />
<haskell><br />
insert_million 0 list = reverse list<br />
insert_million n list = insert_million (n -1) (n:list)<br />
<br />
main = print (length (insert_million 1000000 []))<br />
</haskell><br />
<pre><br />
$ ghc -O2 --make InsertMillionElements.hs && time ./InsertMillionElementsList +RTS -K100M<br />
1000000<br />
real 0m0.588s<br />
user 0m0.528s<br />
sys 0m0.052s<br />
</pre><br />
Lists are substantially faster on this micro-benchmark.<br />
<br />
A sequence uses between 5/6 and 4/3 times as much space as the equivalent list (assuming an overhead of one word per node, as in GHC).<br />
If only deque operations are used, the space usage will be near the lower end of the range, because all internal nodes will be ternary.<br />
Heavy use of split and append will result in sequences using approximately the same space as lists.<br />
In detail:<br />
* a list of length ''n'' consists of ''n'' cons nodes, each occupying 3 words.<br />
* a sequence of length ''n'' has approximately ''n''/(''k''-1) nodes, where ''k'' is the average arity of the internal nodes (each 2 or 3). There is a pointer, a size and overhead for each node, plus a pointer for each element, i.e. ''n''(3/(''k''-1) + 1) words.<br />
<br />
== Additional Tips ==<br />
<br />
* Use strict returns ( return $! ...) unless you absolutely need them lazy.<br />
* Profile, profile, profile - understand who is allocated the memory on your heap (+RTS -hc) and how it's being used (+RTS -hb).<br />
* Use +RTS -p to understand who's doing all the allocations and where your time is being spent.<br />
* Approach profiling like a science experiment - make one change, observe if anything is different, rollback and make another change - observe the change. Keep notes!<br />
* Use [[ThreadScope]] to visualize GHC eventlog traces.<br />
<br />
[[Category:Idioms]]<br />
[[Category:Language]]<br />
[[Category:Performance|*]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=GHC/GHCi&diff=62589GHC/GHCi2018-08-26T21:34:19Z<p>Henk-Jan van Tuyl: /* rlwrap (for GHCI compiled without readline/editline) */ Updated link and improved lay-out</p>
<hr />
<div>[[Category:GHC|GHCi]]<br />
== Introduction ==<br />
<br />
GHCi is GHC's interactive environment, in which Haskell expressions can be interactively evaluated and programs can be interpreted. The [http://www.haskell.org/ghc/docs/latest/html/users_guide/index.html GHC User's Guide] contains [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html more fundamental and detailed information about GHCi.]<br />
<br />
This page is a place to collect advice about how to use GHCi beyond what User's Guide covers. Please add to it! <br />
<br />
== Advanced customization ==<br />
<br />
=== Using <tt>.ghci</tt>, a mini-tutorial ===<br />
<br />
There is a lot more one can do to customize and extend GHCi. Some extended examples can be found in an email posted to <tt>haskell-cafe</tt>, titled<br />
[http://www.haskell.org/pipermail/haskell-cafe/2007-September/032260.html getting more out of ghci]. Dating from September 2007, and using GHC 6.6.1, some of the GHCi tickets mentioned in there have since been fixed, but the message should still serve as a useful introduction to writing your own <tt>.ghci</tt> files. It also provides several useful commands you might want to copy into your own file!-) Newer GHCis support the multiline commands mentioned in the message, allowing for more readable <tt>.ghci</tt> files (at the time, definitions had to be squashed into single lines, so you have to read the message to understand the `.ghci` file). For those still using older GHCis, a variant file for 6.4.1 is available, too:<br />
<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2007-September/032260.html "getting more out of ghci", the mini-tutorial]<br />
* [http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/dot-squashed.ghci squashed .ghci, for 6.6.1 or later]<br />
* [http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/dot-squashed.ghci641 squashed .ghci, for 6.4.1]<br />
<br />
(See the user guide for [http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/ghci-dot-files.html where to locate the <tt>.ghci</tt> file]).<br />
<br />
=== Customized GHCi interactive environments ===<br />
<br />
You can create shell commands that start up GHCi and<br />
initialize it for use as a specialized interactive<br />
computing environment for any purpose that you can<br />
imagine.<br />
<br />
The idea is that if you put the following lines in your<br />
<tt>.ghci</tt> file, GHCi will load commands at startup<br />
from whatever file whose path you specify in<br />
the <tt>GHCIRC</tt> environment variable. You can then easily write<br />
shell scripts that exploit this to initialize GHCi in<br />
any manner you please.<br />
<br />
<haskell><br />
-- Read GHCI commands from the file whose name is<br />
-- in the GHCIRC environment variable<br />
:def _load const(System.Environment.getEnvironment>>=maybe(return"")readFile.lookup"GHCIRC")<br />
:_load<br />
:undef _load<br />
</haskell><br />
<br />
=== External tool integration ===<br />
==== Hoogle ====<br />
External command-line tools like [[Hoogle]] can be integrated in GHCi by adding a line to .ghci similar to<br />
<haskell><br />
:def hoogle \str -> return $ ":! hoogle --count=15 \"" ++ str ++ "\""<br />
</haskell><br />
<br />
Make sure that the directory containing the executable is in your PATH environment variable or modify the line to point directly to the executable. Invoke the executable with commands like<br />
<haskell><br />
:hoogle map<br />
</haskell><br />
<br />
==== Hlint ====<br />
Hlint can be similarly integrated. It is much more complex, however, as one must acquire the filename to run hlint on:<br />
<br />
<haskell><br />
-- <http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/dot-squashed.ghci641><br />
let { redir varcmd = case break Data.Char.isSpace varcmd of { (var,_:cmd) -> return $ unlines [":set -fno-print-bind-result","tmp <- System.Directory.getTemporaryDirectory","(f,h) <- System.IO.openTempFile tmp \"ghci\"","sto <- GHC.Handle.hDuplicate System.IO.stdout","GHC.Handle.hDuplicateTo h System.IO.stdout","System.IO.hClose h",cmd,"GHC.Handle.hDuplicateTo sto System.IO.stdout","let readFileNow f = readFile f >>= \\t->length t `seq` return t",var++" <- readFileNow f","System.Directory.removeFile f"]; _ -> return "putStrLn \"usage: :redir <var> <cmd>\"" } }<br />
:def redir redir<br />
-- End copied material<br />
<br />
-- Integration with the hlint code style tool<br />
let hlint _ = return $ unlines [":set -w", ":redir hlintvar1 :show modules", ":cmd return (\":! hlint \" ++ (concat $ Data.List.intersperse \" \" (map (fst . break (==',') . drop 2 . snd . break (== '(')) $ lines hlintvar1)))", ":set -Wall"]<br />
:def hlint hlint<br />
</haskell><br />
<br />
(There may be a more up-to-date version in the hlint darcs repo.)<br />
<br />
=== Package and documentation lookup ===<br />
<br />
Ever tried to find the users guide for the version of GHCi you are currently running? Or information about the packages installed for it? The new <tt>[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-paths ghc-paths]</tt> package makes such tasks easier by exporting a <tt>GHC.Paths</tt> module:<br />
<haskell><br />
Prelude> :browse GHC.Paths<br />
docdir :: FilePath<br />
ghc :: FilePath<br />
ghc_pkg :: FilePath<br />
libdir :: FilePath<br />
</haskell><br />
We can define some auxiliary commands to make this more comfortable:<br />
<haskell><br />
:ghc_pkg cmds -- run ghc-pkg commands<br />
:browser url -- start browser with url<br />
:doc [relative] -- open docs, with optional relative path<br />
:users_guide [relative] -- open users guide, with optional relative path<br />
</haskell><br />
So, <haskell>:ghc_pkg list</haskell> will list the packages for the current GHCi instance, <haskell>:ghc_pkg find-module Text.Regex</haskell> will tell us what package that module is in, etc. <haskell>:doc</haskell> will open a browser window on the documentation for this GHCi version, <haskell>:doc /Cabal/index.html</haskell> takes us to the Cabal docs, and <haskell>:users_guide /flag-reference.html</haskell> takes us to the flag reference, all matching the version of GHCi we're in, provided that the docs and <tt>ghc-paths</tt> are installed.<br />
<br />
Here are the definitions - adapt to your preferences (note that the construction of the documentation path from <tt>libdir</tt> and <tt>docdir</tt> is slightly dodgy):<br />
<haskell><br />
:def ghc_pkg (\l->return $ ":!"++GHC.Paths.ghc_pkg++" "++l)<br />
<br />
:def browser (\l->return $ ":!c:/Progra~1/Opera/Opera.exe "++l)<br />
<br />
let doc p = return $ ":browser "++GHC.Paths.libdir++dropWhile (/='/')GHC.Paths.docdir++relative where { relative | p=="" = "/index.html" | otherwise = p }<br />
:def doc doc<br />
<br />
let users_guide p = doc ("/users_guide"++if null p then "/index.html" else p)<br />
:def users_guide users_guide<br />
</haskell><br />
<br />
=== GHCi on Acid ===<br />
<br />
GHCi on Acid is an extension to GHCi (Interactive GHC) for adding useful lambdabot features. It does pretty much anything [[lambdabot]] does, just nicely embedded inside your GHCi.<br />
<br />
==== Features ====<br />
<br />
Here are some examples of the commands that can be used.<br />
<br />
The :instances command shows all the instances of a class:<br />
<br />
GOA> :instances Monad<br />
((->) r), ArrowMonad a, Cont r, ContT r m, Either e, ErrorT e m, IO, Maybe, RWS r w s, RWST r w s m, Reader r, ReaderT r m, ST s, State s, StateT s m, Writer w, WriterT w m, []<br />
GOA> :instances Arrow<br />
(->), Kleisli m<br />
GOA> :instances Num<br />
Double, Float, Int, Integer<br />
<br />
Here we have the :hoogle command, for querying the Hoogle database. Great for looking for functions of a specific type:<br />
<br />
GOA> :hoogle Arrow<br />
Control.Arrow :: module<br />
Control.Arrow.Arrow :: class Arrow a<br />
Control.Arrow.ArrowZero :: class Arrow a => ArrowZero a<br />
GOA> :hoogle b -> (a -> b) -> Maybe a -> b<br />
Prelude.maybe :: b -> (a -> b) -> Maybe a -> b<br />
Data.Maybe.maybe :: b -> (a -> b) -> Maybe a -> b<br />
<br />
The :source command gives a link to the source code of a module (sometimes you are curious):<br />
<br />
GOA> :source Data.Maybe<br />
http://darcs.haskell.org/packages/base/Data/Maybe.hs<br />
<br />
Similarly, :docs gives a link to the documentation of a module.<br />
<br />
GOA> :docs Data.Maybe<br />
http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html<br />
<br />
The :index command is a nice way to search modules.<br />
<br />
GOA> :index Monad<br />
Control.Monad, Prelude, Control.Monad.Reader, Control.Monad.Writer, Control.Monad.State, Control.Monad.RWS, Control.Monad.Identity, Control.Monad.Cont, Control.Monad.Error, Control.Monad.List<br />
<br />
Then we have :pl, which shows the pointless (or: point-free) way of writing a function, which is very useful for learning and sometimes for fun:<br />
<br />
GOA> :pl (\x -> x * x)<br />
join (*)<br />
GOA> :pl (\x y -> (x * 5) + (y * 5))<br />
(. (5 *)) . (+) . (5 *)<br />
<br />
==== How to install ====<br />
<br />
$ cabal install lambdabot<br />
$ cabal install goa<br />
<br />
Then edit your .ghci to look like the following:<br />
<br />
:m - Prelude<br />
:m + GOA<br />
setLambdabotHome "/home/chris/.cabal/bin"<br />
:def bs lambdabot "botsnack"<br />
:def pl lambdabot "pl"<br />
:def unpl lambdabot "unpl"<br />
:def redo lambdabot "redo"<br />
:def undo lambdabot "undo"<br />
:def index lambdabot "index"<br />
:def docs lambdabot "docs"<br />
:def instances lambdabot "instances"<br />
:def hoogle lambdabot "hoogle"<br />
:def source lambdabot "fptools"<br />
:def where lambdabot "where"<br />
:def version lambdabot "version"<br />
:def src lambdabot "src"<br />
<br />
And you should be able to do this:<br />
<br />
chris@chrisamilo:~$ ghci<br />
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help<br />
Loading package ghc-prim ... linking ... done.<br />
Loading package integer ... linking ... done.<br />
Loading package base ... linking ... done.<br />
Loading package syb ... linking ... done.<br />
Loading package base-3.0.3.1 ... linking ... done.<br />
Loading package old-locale-1.0.0.1 ... linking ... done.<br />
Loading package old-time-1.0.0.2 ... linking ... done.<br />
Loading package filepath-1.1.0.2 ... linking ... done.<br />
Loading package unix-2.3.2.0 ... linking ... done.<br />
Loading package directory-1.0.0.3 ... linking ... done.<br />
Loading package process-1.0.1.1 ... linking ... done.<br />
Loading package goa-3.0.2 ... linking ... done.<br />
GOA> :src foldr<br />
src foldr<br />
foldr f z [] = z<br />
foldr f z (x:xs) = f x (foldr f z xs)<br />
GOA> <br />
<br />
Tip: if you accidentally unload the GOA module, use :m + GOA to load it.<br />
<br />
== Frequently Asked Questions (FAQ) ==<br />
<br />
=== How do I stop GHCi from printing the result of a bind statement? ===<br />
<br />
Sometimes you want to perform an IO action at the prompt that will produce a lot of data (e.g. reading a large file). When you try to do this, GHCi will helpfully spew this data all over your terminal, making the console temporarily unavailable.<br />
<br />
To prevent this, use <tt>:set -fno-print-bind-result</tt>. If you want this option to be permanently set, add it to your <tt>.ghci</tt> file.<br />
<br />
== Additional command advice ==<br />
<br />
=== The :def command ===<br />
<br />
The [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-commands.html#id2902944 :def command], documented here, allows GHCi's commands to be extended in quite a powerful way.<br />
<br />
Here is one example.<br />
<br />
Prelude> let loop = do { l <- getLine; if l == "\^D" then return () else do appendFile "foo.hs" (l++"\n"); loop }<br />
Prelude> :def pasteCode (\_ -> loop >> return ":load foo.hs")<br />
<br />
This defines a new command :pasteCode, which allows you to paste Haskell code directly into GHCi. You type the command :pasteCode, followed by the code you want, followed by ^D, followed (unfortunately) by enter, and your code is executed. Thus:<br />
<br />
Prelude> :pasteCode<br />
x = 42<br />
^D<br />
Compiling Main ( foo.hs, interpreted )<br />
Ok, modules loaded: Main.<br />
*Main> x<br />
42<br />
*Main><br />
<br />
== Compatibility/shell/platform integration ==<br />
<br />
=== Readline/editline ===<br />
<br />
There are some tricks to getting readline/editline to work as expected with GHCi.<br />
<br />
==== A readline-aware GHCi on Windows ====<br />
<br />
Mauricio reports: I've just uploaded a package (<tt>rlwrap</tt>) to Cygwin that I like to use with <tt>ghci</tt>. You can use it like this:<br />
<pre><br />
rlwrap ghcii.sh<br />
</pre><br />
and then you will use <tt>ghc</tt> as if it were readline aware (i.e., you can <br />
press up arrow to get last typed lines etc.). <tt>rlwrap</tt> is very stable <br />
and I never had unexpected results while using it.<br />
<br />
Since the issue of <tt>ghci</tt> integration with terminals has been raised <br />
here sometimes, I thought some guys here would be interested (actually, <br />
I found rlwrap looking for a better way to use ghci).<br />
<br />
==== rlwrap (for GHCI compiled without readline/editline) ====<br />
<br />
GHCi has support for session-specific command-line completion, but only if it was built with the readline or editline package, and some versions of GHCi aren't. In such cases, you can try [https://web.archive.org/web/20161029155321/utopia.knoware.nl/~hlub/uck/rlwrap/ rlwrap (readline wrapper)] to attach readline "from the outside", which isn't as specific, but gives basic completion support. In particular, there's an rlwrap package for Cygwin.<br />
<br />
For starters,<br />
<br />
<code><br />
rlwrap -cr ghci<br />
</code><br />
<br />
gives you filename completion, and completion wrt to previous input/output in your GHCi session (so if a GHCi error message suggests to set <hask>AnnoyinglyLongVerySpecificOption</hask>, that will be available for completion;-).<br />
<br />
If you want to get more specific, you need to supply files with possible completions - flags and modules spring to mind, but where to get those?<br />
<br />
1. extracting a list of options from the flag-reference in the users guide:<br />
<br />
<pre><br />
cat /cygdrive/c/ghc/ghc-6.9.20080514/doc/users_guide/flag-reference.html<br />
| sed 's/</\n</g' <br />
| sed '/<code class="option">/!d;s/<code class="option">\(.*\)$/\1/'<br />
> options.txt<br />
</pre><br />
<br />
actually, we only want the dynamic or :setable options, and no duplicates, so:<br />
<br />
<pre><br />
cat /cygdrive/c/ghc/ghc-6.9.20080514/doc/users_guide/flag-reference.html <br />
| sed 's/<tr/\n<tr/g' <br />
| grep '<code class="option".*>\(dynamic\|:set\)<' <br />
| sed 's/^.*<code class="option">\([^<]*\)<.*$/\1/' <br />
| uniq<br />
> options.txt<br />
</pre><br />
<br />
2. extracting a list of modules from <tt>ghc-pkg</tt>:<br />
<br />
<code><br />
ghc-pkg field '*' exposed-modules | sed 's/exposed-modules: //; s/^\s\+//g' >modules.txt<br />
</code><br />
<br />
And now,<br />
<br />
<code><br />
rlwrap -cr -f modules.txt -f options.txt ghcii.sh<br />
</code><br />
<br />
will give you completion wrt filenames, options, module names, and previous session contents, as well as the usual readline goodies, like history search and editing. The main drawback is that the completion is neither session nor context-specific, so it will suggest filenames where module names are expected, it will suggest module names that may not be exposed, etc.</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=GHC/FAQ&diff=62588GHC/FAQ2018-08-26T21:29:24Z<p>Henk-Jan van Tuyl: /* When do other Haskell threads get blocked by an FFI call? */ Updated link to FFI description</p>
<hr />
<div>[[Category:GHC]] [[Category:FAQ]]<br />
Please feel free to add stuff here.<br />
<br />
This page is rather long. We've started to add some sub-headings, but would welcome your help in making it better organised.<br />
<br />
= GHC (Platform-specific Issues) =<br />
<br />
== Porting GHC ==<br />
<br />
=== How do I port GHC to platform X? ===<br />
<br />
There are two distinct possibilities: either<br />
<br />
* The hardware architecture for your system is already supported by GHC, but you're running an OS that isn't supported (or perhaps has been supported in the past, but currently isn't). This is the easiest type of porting job, but it still requires some careful bootstrapping.<br />
<br />
* Your system's hardware architecture isn't supported by GHC. This will be a more difficult port (though by comparison perhaps not as difficult as porting gcc).<br />
<br />
Both ways require you to bootstrap from intermediate HC files: these are the stylised C files generated by GHC when it compiles Haskell source. Basically the idea is to take the HC files for GHC itself to the target machine and compile them with gcc to get a working GHC, and go from there.<br />
<br />
The [http://hackage.haskell.org/trac/ghc/wiki/Building Building Guide] has all the details on how to bootstrap GHC on a new platform.<br />
<br />
<br />
== Linux-related ==<br />
<br />
=== Missing libreadline.so.x Errors ===<br />
<br />
==== I Can't run GHCi on Linux, because it complains about a missing <tt>libreadline.so.3</tt>. ====<br />
<br />
The "correct" fix for this problem is to install the correct package for the particular flavour of Linux on your machine. If this isn't an option, however, there is a hack that might work: make a symbolic link from <tt>libreadline.so.4</tt> to <tt>libreadline.so.3</tt> in <tt>/usr/lib</tt>. We tried this on a SuSE 7.1 box and it seemed to work, but YMMV.<br />
<br />
=== Linking Errors ===<br />
<br />
==== Linking a program causes the following error on Linux: <tt>/usr/bin/ld: cannot open -lgmp: No such file or directory</tt> ====<br />
<br />
The problem is that your system doesn't have the GMP library installed. If this is a RedHat distribution, install the RedHat-supplied gmp-devel package, and the gmp package if you don't already have it. There have been reports that installing the RedHat packages also works for SuSE (SuSE doesn't supply a shared gmp library).<br />
<br />
=== SELinux-related ===<br />
<br />
==== Memory Allocation Errors ====<br />
<br />
If you have SELinux enabled on your system, then GHC may fail with a memory allocation error:<br />
<br />
ghc-6.4.1: internal error: mallocBytesRWX: failed to protect 0x0x1660730<br />
<br />
or maybe<br />
<br />
ghc: internal error: getMBlock: mmap: Permission denied <br />
<br />
The reason for this is that SELinux prevents allocation of writeable/executable memory regions, which GHC needs in order to implement certain parts of the FFI that require dynamic code generation. (See [http://hackage.haskell.org/trac/ghc/ticket/738 this bug report]).<br />
<br />
In GHC 6.4.2 we improved the situation somewhat, but not completely.<br />
<br />
Workarounds:<br />
<br />
* Set <tt>allow_execmem</tt> to 0, with the <tt>setsebool</tt> command.<br />
* do this on a per-program basis, for GHC and GHC-compiled programs. Apparently this is done by:<br />
<br />
<tt>/usr/bin/chcon -t unconfined_execmem_exec_t /path/to/binary/prog</tt><br />
<br />
== Solaris-related ==<br />
<br />
=== Link Errors ===<br />
<br />
==== Solaris users may sometimes get link errors due to libraries needed by GNU Readline. ====<br />
<br />
We suggest you try linking in some combination of the termcap, curses and ncurses libraries, by giving <tt>-ltermcap</tt>, <tt>-lcurses</tt> and <tt>-lncurses</tt> respectively. If you encounter this problem, we would appreciate feedback on it, since we don't fully understand what's going on here.<br />
The build fails in readline.<br />
<br />
It has been reported that if you have multiple versions of the readline library installed on Linux, then this may cause the build to fail. If you have multiple versions of readline, try uninstalling all except the most recent version.<br />
<br />
== Windows-related ==<br />
<br />
=== Heapsize-related Crashes ===<br />
<br />
==== My program that uses a really large heap crashes on Windows. ====<br />
<br />
For utterly horrible reasons, programs that use more than 128Mb of heap won't work when compiled dynamically on Windows (they should be fine statically compiled).<br />
<br />
=== Ctrl-C Not Working ===<br />
<br />
When running GHC under a Cygwin shell on Windows, Ctrl-C sometimes doesn't work. A workaround is to use Ctrl-Break instead. Another workaround is to use the rlwrap program (cygwin package available) to invoke ghci : In addition to proper Ctrl-C, you also get emacs (or vi) key bindings and command history across sessions. <br />
<br />
=== Linking with Visual Studio C++ Code ===<br />
<br />
==== How do I link Haskell with C++ code compiled by Visual Studio? ====<br />
<br />
===== Prerequisites =====<br />
<br />
It is assumed that the reader is familiar with the Haskell <br />
[http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi.html Foreign function interface (FFI)],<br />
and is able to compile Haskell programs with GHC and C++ programs with Visual Studio.<br />
<br />
===== Background =====<br />
<br />
GHC has two modes of code generation. It either compiles Haskell straight into object code<br />
(native mode), or translates Haskell into intermediate C code, and uses a C compiler as backend.<br />
<br />
The Windows distribution of GHC comes bundled with the GCC compiler, which is used as backend.<br />
That's why linking Haskell with Visual C++ is no different from linking GCC-generated code with<br />
the code generated by Visual C++.<br />
<br />
One cannot statically link together object files produced by those two compilers,<br />
but they can be linked dynamically: an executable produced by Visual C++ can invoke a DLL<br />
produced by GCC, and vice versa. Likewise, we can link Haskell with Visual C++ in one of these ways.<br />
<br />
''Note:'' when Haskell becomes able to use Visual C++ as a backend (see [http://hackage.haskell.org/trac/ghc/ticket/989]), we would not need to go via a DLL anymore. Instead, we would simply list<br />
all source files (Haskell and C++) on the command line of GHC.<br />
<br />
===== Invoking a Haskell DLL =====<br />
<br />
====== From a C++ executable ======<br />
<br />
#Make a Haskell DLL as explained in [http://www.haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html#win32-dlls-foreign]<br />
#Make a module definition file, such as<tt><br>LIBRARY Adder<br>EXPORTS<br>&nbsp;&nbsp;&nbsp;&nbsp;adder</tt><br />
#Create an import library using Visual Studio's <tt>lib.exe:<br>lib /DEF:adder.def /OUT:adder.lib</tt><br />
#Link the C++ program against the import library.<br />
<br />
====== From a Haskell executable ======<br />
<br />
#Make a DLL project in Visual Studio. It will create a <tt>.vcproj</tt> and <tt>.sln</tt> files for you. Add your C++ source files to this project. <br />
#Create a <tt>.def</tt> file for your DLL. It might look like<tt><br>LIBRARY MyDLL<br>EXPORTS<br>&nbsp;&nbsp;&nbsp;&nbsp;function1<br>&nbsp;&nbsp;&nbsp;&nbsp;function2<br></tt> where <tt>function1</tt> and <tt>function2</tt> are the names of the C++ functions that you want to invoke from Haskell (there can be more of them, of course), <tt>MyDLL</tt> is the name of your DLL.<br />
#Create an import library that can be used by <tt>ghc:<br>dlltool -d MyDLL.def -l libMyDLL.a</tt> <br />
#Link your Haskell project, adding the library:<tt><br>ghc --make main.hs -optl-lMyDLL -optl-L.<br></tt>''mind the dot at the end of the command line!''<br> (<tt>[https://ghc.readthedocs.io/en/latest/phases.html#forcing-options-to-a-particular-phase -optl]</tt> switch passes its argument as an option to the linker).<br />
<br />
=== GHCi Hanging Issues ===<br />
<br />
==== GHCi hangs after "Loading package base ... linking ... done." ====<br />
<br />
On a small number of systems GHCi will fail to start, hanging after loading the base package. The "Prelude>" prompt is never reached.<br />
<br />
This is believed to be due to a bug in Windows thought to affect tablet PCs, although the details are not fully understood.<br />
<br />
A workaround is to open a command prompt, enter "chcp 28591" - if this hangs hit Ctrl-C - and then run "ghci". Some users may find this [http://support.microsoft.com/kb/925271 hotfix] useful.<br />
<br />
=== A console window opens when my application is supposed to be GUI only ===<br />
<br />
Windows has several different "subsystems", the default subsystem which the mingw linker uses is console, so that stdout/stderr can be printed on screen and stdin be read from the console window.<br />
<br />
This can be solved by giving the option -optl-mwindows with the compile command:<br />
ghc --make -optl-mwindows MyProgramWithGUI.lhs<br />
With this option, the option -mwindows is passed to the linker.<br />
<br />
Caveat: attempting to read from stdin with -mwindows set may cause a runtime error, any output on stdout/stderr will be lost.<br />
<br />
== .NET/JVM Availability ==<br />
<br />
=== Why isn't GHC available for .NET or on the JVM? ===<br />
<br />
It would make a lot of sense to give GHC a .NET or JVM back end, and it's a<br />
question that comes up regularly. The reason that we haven't done it<br />
here, at GHC HQ, is because it's a more substantial undertaking than<br />
might at first appear (see below). Furthermore, it'd permanently add a<br />
complete new back-end platform for us to maintain. Given our rather<br />
limited development effort, we have so far not bitten<br />
the bullet, and we have no immediate plans to do so.<br />
<br />
It would be a good, well-defined project for someone else to tackle, and<br />
we would love to see it done. There is some good groundwork already done:<br />
<br />
* Ashley Yakeley worked on a [http://sourceforge.net/projects/jvm-bridge/ Haskell-JVM bridge]<br />
<br />
* Sigbjorn Finne did a simple interop implementation ([http://hackage.haskell.org/package/hs-dotnet the hs-dotnet package]) that allows a Haskell program to be compiled to native code (as now) but to call .NET programs via a variant of the FFI. I don't think this work is in active use, and I'd be surprised if it worked out of the box, but it could probably be revived with modest effort<br />
<br />
* Andre Santos and his colleagues at UFPE in Brazil are working on a .NET back end, that generates CLR IL, though I don't know where they are up to.<br />
<br />
* Nigel Perry and Oliver Hunt have a Haskell.NET prototype that works using GHC to compile to Core, and then compiling Core to NET. I'm not sure what stage it is at.<br />
<br />
* GHC.Net would be extra attractive if there was a Visual Studio integration for GHC. Substantial progress on this has been made in 2004 by Simon Marlow, Krasimir Angelov, and Andre Santos and colleagues.<br />
<br />
* Brian Alliet created a patch for GHC called LambdaVM that compiles programs into JVM bytecode. [http://wiki.brianweb.net/LambdaVM/LambdaVM]<br />
<br />
* Not GHC but [[UHC]]: the Jazy backend of UHC generates Java class files to allow Haskell programs to run on the Java Virtual Machine (JVM). Jazy is [http://www.cs.uu.nl/wiki/bin/view/Ehc/UhcJazyDocumentation#2_Status not fully functional yet].<br />
<br />
<br />
There may be others that I don't know of. If anyone wants to join in<br />
this effort, do contact the above folk. And please keep us informed!<br />
<br />
Here's a summary of why it's a non-trivial thing to do (using .NET language, but it mostly applies to the JVM too):<br />
<br />
* The first thing is to generate native CLR Intermediate Language (IL). That's not really hard. Requires thinking about representations for thunks and functions, and it may not be particularly efficient, but it can surely be done. <br />
: An open question is about whether to generate ''verifiable'' IL or not. The trouble here is that Haskell's type system is more expressive than the CLR's in some ways, notably the use of higher-kinded type variables. So, to generate verifiable IL one is bound to need some run-time casts, and it's not clear how to minimise these.<br />
<br />
At first blush this is ''all'' you need do. But it isn't!<br />
<br />
* Next, you need to think about how to inter-operate with .NET libraries. You don't really want to write "foreign import..." for each and every import. You'd like GHC to read the CLR meta-data directly. But there are lots of tricky issues here; see the paper that Mark Shields and I wrote about "Object-oriented style overloading for Haskell".<br />
<br />
* A closely-related question is this: how to make the type systems of Java/.NET and Haskell "line up"? For example, when importing a Java procedure, what is the Haskell type that corresponds to its .NET/JVM type? How do you sub-class a .NET class in Haskell? For example [http://research.microsoft.com/en-us/um/people/simonpj/papers/oo-haskell/index.htm Object-Oriented Style Overloading for Haskell] gives one "take" on the subject, but there are plenty of other possibilities. <br />
<br />
* Now you need to figure out how to implement GHC's primitive operations:<br />
** the I/O monad<br />
** arbitrary precision arithmetic<br />
** concurrency<br />
** exceptions<br />
** finalisers<br />
** stable pointers<br />
** [[Software transactional memory]]<br />
<br />
:: Not all of these are necessary, of course, but many are used in the libraries. The CLR supports many of them (e.g. concurrency) but with a very different cost model.<br />
<br />
* Last, you have to figure out what to do for the libraries. GHC has a pretty large library, and you either have to implement the primops on which the library is based (see previous point), or re-implement it. For example, GHC's implementation of I/O uses mutable state, concurrency, and more besides. For each module, you need to decide either to re-implement it using .NET primitives, or to implement the stuff the module is based on.<br />
<br />
These challenges are mostly broad rather than deep. But to get a<br />
production quality implementation that runs a substantial majority of<br />
Haskell programs "out of the box" requires a decent stab at all of them.<br />
<br />
== Mac OS X-related ==<br />
<br />
=== Linking with GHC ===<br />
<br />
==== Linking with ghc produces <tt>ld: Undefined symbols: _sprintf$LDBLStub ...</tt> ====<br />
<br />
This happens on a PowerPC Mac OS X 10.4 if gcc-3.3 is the default compiler and you try to compile with a ghc that has been built with gcc-4.0. For example:<br />
<br />
$ cat t2.hs <br />
module Main where<br />
main = putStr ("t2: Hello trac 1066 2007-Feb-17 19.48\n")<br />
$ gcc --version<br />
gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1819)<br />
...<br />
$ ghc --make t2.hs<br />
[1 of 1] Compiling Main ( t2.hs, t2.o )<br />
Linking t2 ...<br />
ld: Undefined symbols:<br />
_sprintf$LDBLStub<br />
_fprintf$LDBLStub<br />
_vfprintf$LDBLStub<br />
_sscanf$LDBLStub<br />
$ <br />
<br />
To correct this, set the default compiler to gcc-4.0 (<tt>sudo gcc_select 4.0</tt>) or include linking options <tt>-lHSrts -lSystemStubs</tt> in that order on the ghc command:<br />
<br />
$ ghc --make t2.hs -lHSrts -lSystemStubs<br />
[1 of 1] Skipping Main ( t2.hs, t2.o )<br />
Linking t2 ...<br />
$ <br />
<br />
The command<br />
<br />
for l in <ghc installation directory>/lib/ghc-<ghc version>/*.a; do nm $l 2>&1 | if grep LDBLStub 1>/dev/null; then echo $l; fi; done<br />
<br />
prints the list of libraries that may be needed instead of or in addition to <tt>-lHSrts</tt> before <tt>-lSystemStubs</tt> on the ghc command. For example:<br />
<br />
$ for l in /Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/*.a; do nm $l 2>&1 | if grep LDBLStub 1>/dev/null; then echo $l; fi; done<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSX11_cbits.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts_debug.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts_p.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts_thr.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts_thr_debug.a<br />
/Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/lib/ghc-6.7.20070209/libHSrts_thr_p.a<br />
$ <br />
<br />
[http://hackage.haskell.org/trac/ghc/ticket/1066] has additional details.<br />
<br />
=== Linking with C++ ===<br />
<br />
==== Linking with a C++ library gives: <tt>Undefined symbols: __Unwind_Resume</tt> ====<br />
<br />
You need to pass the <tt>-fexceptions</tt> to the linker. Use <tt>-optl -fexceptions</tt>.<br />
<br />
---------------------------------------<br />
= Running GHC =<br />
<br />
== Filenames Containing '+' ==<br />
<br />
=== GHC doesn't like filenames containing '+'. ===<br />
<br />
Indeed not. You could change <tt>+</tt> to <tt>p</tt> or <tt>plus</tt>.<br />
<br />
== Linking ==<br />
<br />
=== Why does linking take so long? ===<br />
<br />
Linking a small program should take no more than a few seconds. Larger programs can take longer, but even linking GHC itself only takes 3-4 seconds on our development machines.<br />
<br />
Long link times have been attributed to using Sun's linker on Solaris, as compared to GNU ld which appears to be much faster. So if you're on a Sun box, try switching to GNU ld. [http://www.haskell.org/pipermail/glasgow-haskell-users/2002-November/004477.html This article] from the mailing list has more information.<br />
<br />
One huge slowdown is also working on remote filesystem, e.g., nfs. <br />
Work on a local machine, preferably.<br />
<br />
You may also speed up linking by enabling dynamic linking with the <code>-dynamic</code> option of GHC or <code>--enable-executable-dynamic</code> of [[Cabal]].<br />
<br />
== Missing Include Files ==<br />
<br />
=== Why do I get errors about missing include files when compiling with -O or -prof? ===<br />
<br />
Certain options, such as -O, turn on via-C compilation, instead of using the native code generator. Include files named by -#include options or in foreign import declarations are only used in via-C compilation mode. See [http://www.haskell.org/ghc/docs/latest/html/users_guide/sec-ffi-ghc.html#finding-header-files Section 8.2.2.1, ´Finding Header files] for more details.<br />
<br />
== Compiling for Profiling ==<br />
<br />
=== How do I compile my program for profiling without overwriting the object files and hi files I've already built? ===<br />
<br />
You can select alternative suffixes for object files and interface files, so you can have several builds of the same code coexisting in the same directory. For example, to compile with profiling, you might do this:<br />
<br />
<pre><br />
ghc --make -prof -o foo-prof -osuf p.o -hisuf p.hi Main<br />
</pre><br />
<br />
See [http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation.html#options-output Section 4.6.4, ´Redirecting the compilation output(s)] for more details on the <tt>-osuf</tt> and <tt>-hisuf</tt> options.<br />
<br />
---------------------------------------<br />
= Syntax =<br />
<br />
== String Gaps ==<br />
<br />
=== I can't get string gaps to work ===<br />
<br />
If you're also using CPP, beware of the known pitfall with string gaps mentioned in [http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#cpp-string-gaps Section 4.10.3.1, CPP and string gaps].<br />
<br />
---------------------------------------<br />
= GHCi =<br />
<br />
== Error Messages ==<br />
<br />
=== Missing Symbols ===<br />
<br />
==== GHCi complains about missing symbols like CC_LIST when loading a previously compiled .o file. ====<br />
<br />
This probably means the .o files in question were compiled for profiling (with -prof). Workaround: recompile them without profiling. We really ought to detect this situation and give a proper error message.<br />
<br />
=== Starting GHCi ===<br />
<br />
==== When I try to start ghci (probably one I compiled myself) it says <tt>ghc-5.02: not built for interactive use</tt> ====<br />
To build a working ghci, you need to build GHC 5.02 with itself; the above message appears if you build it with 4.08.X, for example. It'll still work fine for batch-mode compilation, though. Note that you really must build with exactly the same version of the compiler. Building 5.02 with 5.00.2, for example, may or may not give a working interactive system; it probably won't, and certainly isn't supported. Note also that you can build 5.02 with any older compiler, back to 4.08.1, if you don't want a working interactive system; that's OK, and supported.<br />
<br />
=== Duplicate Definitions ===<br />
<br />
==== I get an error message from GHCi about a "<tt>duplicate definition for symbol __module_registered</tt>" ====<br />
<br />
An error message like this:<br />
<br />
<pre><br />
GHCi runtime linker: fatal error: I found a duplicate definition for symbol<br />
__module_registered<br />
whilst processing object file<br />
/usr/local/lib/ghc-6.2/HSfgl.o<br />
</pre><br />
<br />
probably indicates that when building a library for GHCi (<tt>HSfgl.o</tt> in the above example), you should use the <tt>-x</tt> option to <tt>ld</tt>.<br />
<br />
== REPL Workarounds ==<br />
<br />
=== Why doesn't "x=1" work at the ghci prompt? ===<br />
<br />
Type<br />
<pre><br />
let x = 1<br />
</pre><br />
<br />
instead.<br />
<br />
From IRC: "But in general, it's tricky to define function interactively. You can do simple stuff easily enough: "let f x = x * x" or whatever; but for anything other than a simple one-liner, I usually stick it into a file and then load it with ghci.<br />
<br />
---------------------------------------<br />
= The Foreign Function Interface =<br />
<br />
== Blocking ==<br />
<br />
=== When do other Haskell threads get blocked by an FFI call? ===<br />
<br />
{| border="1" align="center"<br />
|<br />
! safe<br />
! unsafe<br />
|-<br />
! -threaded<br />
| NO <br />
| YES<br />
|-<br />
! no -threaded<br />
| YES<br />
| YES<br />
|}<br />
<br />
The <tt>-threaded</tt> flag (given when linking; see the <br />
[http://www.haskell.org/ghc/docs/latest/html/users_guide/flag-reference.html manual])<br />
allows other Haskell threads to run concurrently with a thread making an FFI call.<br />
This nice behaviour does not happen for foreign calls marked as `unsafe` (see<br />
the [https://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1490008 Foreign Function Interface description] in the Haskell 2010 Language Report).<br />
<br />
There used to be another modifier, <tt>threadsafe</tt>, which is now deprecated. Use `safe` instead.<br />
<br />
== Using Floats ==<br />
<br />
=== When I use a foreign function that takes or returns a float, it gives the wrong answer, or crashes. ===<br />
<br />
You should use the <tt>-#include</tt> option to bring the correct prototype into scope (see [http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#options-C-compiler Section 4.10.5, ´Options affecting the C compiler (if applicable)]).<br />
<br />
== Propagating Run-time Errors as Exceptions ==<br />
<br />
=== How can I propagate a Haskell run-time error (e.g. pattern match failure) as an exception to a foreign caller of the Haskell function. ===<br />
<br />
If a runtime error occurs inside a DLL compiled by ghc (like <br />
"irrefutable pattern match failed" or exceptions caused by error),<br />
the application that called the DLL function dies. This is ok for <br />
development but unacceptable when it happens with a user sitting in <br />
front of the display. <br />
So the question is: Is there any way to catch and process runtime errors? <br />
I am looking for some way to map those errors to exceptions on the C++ <br />
side that can be caught if required. It would be ok to kill the Haskell <br />
runtime system and unload the DLL if necessary.<br />
<br />
Answer: The FFI doesn't provide any way to propagate exceptions from Haskell to <br />
the caller of a foreign export, because there's no standard way to do <br />
this. It is your responsibility to catch the exception in Haskell and <br />
return an appropriate error code to the caller. To raise a C++ <br />
exception, you would probably need another C++ wrapper around each <br />
foreign export, translating an error code into the C++ exception.<br />
<br />
== Calling C Procedures ==<br />
<br />
=== How do I call a C procedure from a Haskell program? ===<br />
<br />
First, you'll want to keep open <br />
the [http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi.html GHC user manual section on foreign function calling], and the <br />
[http://www.cse.unsw.edu.au/~chak/haskell/ffi/ Haskell FFI addendum].<br />
<br />
Now, let's assume you got this c-program ffi.c which writes THE answer to a file:<br />
<br />
<pre><br />
#include <stdlib.h><br />
#include <stdio.h><br />
<br />
write_answer(char *userfilename)<br />
{<br />
FILE *userfile;<br />
userfile=fopen(userfilename,"w");<br />
fprintf(userfile,"42");<br />
fclose(userfile);<br />
}<br />
</pre><br />
You also need a header file ffi.h.<br />
<pre><br />
void write_answer(char *userfilename)<br />
</pre><br />
Next Step: Write the according Haskell program to include the function<br />
<tt>write_answer</tt> in your Haskell code:<br />
<haskell><br />
{-# INCLUDE <ffi.h> #-}<br />
{-# LANGUAGE ForeignFunctionInterface #-}<br />
module Main where<br />
<br />
import Foreign<br />
import Foreign.C.String <br />
<br />
foreign import ccall "ffi.h write_answer" cwrite_answer :: CString -> IO ()<br />
<br />
write_answer :: String -> IO ()<br />
write_answer s = do<br />
s' <- newCString s<br />
cwrite_answer s'<br />
<br />
main = write_answer "ffi.dat"<br />
</haskell><br />
<br />
Now we get to compiling (assume that <tt>/tmp/ffi/</tt> is the current path).<br />
<pre><br />
cc -fPIC -c ffi.c<br />
ar rc libffi.a ffi.o<br />
ghc -lffi -L/tmp/ffi --make Main<br />
</pre><br />
And the resulting executable should write the file.<br />
<br />
The <tt>-fPIC</tt> parameter to the c compiler is not strictly necessary. <br />
But the result will help us in the next step which is to dynamically link the library for use in GHCi.<br />
<br />
== Compiling C Programs ==<br />
<br />
=== How do I compile my C program to use in GHCi? ===<br />
<br />
Suppose you got your c-program compiled (with <tt>-fPIC</tt> parameter) as described above. If you try to load your file <tt>Main.hs</tt> in GHCi you get an error similar to this:<br />
<pre><br />
Loading object (dynamic) ffi ... failed.<br />
Dynamic linker error message was:<br />
libffi.so: cannot open shared object file: No such file or directory<br />
Whilst trying to load: (dynamic) ffi<br />
</pre><br />
What you need is a shared library. To get it you compile once more:<br />
<pre><br />
cc -shared -o libffi.so ffi.o<br />
</pre><br />
And now it all works fine:<br />
<pre><br />
$ ghci -lffi -L/tmp/ffi Main.hs<br />
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help<br />
Loading package base ... linking ... done.<br />
Loading object (dynamic) ffi ... done<br />
final link ... done<br />
Ok, modules loaded: Main.<br />
Prelude Main> write_answer "test"<br />
Prelude Main> :! cat test<br />
42<br />
Prelude Main> <br />
</pre><br />
<br />
---------------------------------------<br />
<br />
= Input/Output =<br />
<br />
== Strings ==<br />
<br />
=== If I print out a string using <tt>putStr</tt>, and then attempt to read some input using <tt>hGetLine</tt>, I don't see the output from the <tt>putStr</tt>. ===<br />
<br />
The <tt>stdout</tt> handle is line-buffered by default, which means that output sent to the handle is only flushed when a newline (<tt>\n</tt>) is output, the buffer is full, or <tt>hFlush</tt> is called on the <tt>Handle</tt>. The right way to make the text appear without sending a newline is to use <tt>hFlush</tt>:<br />
<br />
<haskell><br />
import System.IO<br />
main = do<br />
putStr "how are you today? "<br />
hFlush stdout<br />
input <- hGetLine stdin<br />
process input<br />
</haskell><br />
<br />
You'll probably find that the behaviour differs when using GHCi: the hFlush isn't necessary to make the text appear. This is because in GHCi we turn off the buffering on stdout, because this is normally what you want in an interpreter: output appears as it is generated.<br />
<br />
=== If I use the above fix, but check for EOF with <tt>isEOF</tt> before prompting for user input, the above problem still happens (GHC 6.12.1) ===<br />
<br />
== Buffering on Handles ==<br />
<br />
=== If I explicitly set the buffering on a Handle to <tt>NoBuffering</tt> I'm not able to enter EOF by typing "Ctrl-D". ===<br />
<br />
This is a consequence of Unixy terminal semantics. Unix does line buffering on terminals in the kernel as part of the terminal processing, unless you turn it off. However, the Ctrl-D processing is also part of the terminal processing which gets turned off when the kernel line buffering is disabled. So GHC tries its best to get NoBuffering semantics by turning off the kernel line buffering, but as a result you lose Ctrl-D. C'est la vie.<br />
<br />
== FIFOs (Named Pipes) ==<br />
<br />
=== When I open a FIFO (named pipe) and try to read from it, I get EOF immediately. ===<br />
<br />
This is a consequence of the fact that GHC opens the FIFO in non-blocking mode. The behaviour varies from OS to OS: on Linux and Solaris you can wait for a writer by doing an explicit threadWaitRead on the file descriptor (gotten from <tt>Posix.handleToFd</tt>) before the first read, but this doesn't work on FreeBSD (although rumour has it that recent versions of FreeBSD changed the behaviour to match other OSs). A workaround for all systems is to open the FIFO for writing yourself, before (or at the same time as) opening it for reading.<br />
<br />
== Importing Functions Returning Char/Short ==<br />
<br />
=== When I foreign import a function that returns char or short, I get garbage back. ===<br />
<br />
This is a known bug in GHC versions prior to 5.02.2. GHC doesn't mask out the more significant bits of the result. It doesn't manifest with gcc 2.95, but apparently shows up with g++ and gcc 3.0.<br />
<br />
---------------------------------------<br />
= Optimization =<br />
<br />
== Garbage Collection ==<br />
<br />
=== My program spent too much time doing garbage collection ===<br />
<br />
Add the "+RTS -A10m" option to the command line when you run your<br />
program. This sets the allocation area size used by the garbage<br />
collector to 10M, which should sufficiently decrease GC times (the<br />
default is 256K; see the section "Running a compiled program" in the<br />
users' guide). You can also add to your program C module containing<br />
statement<br />
<br />
char *ghc_rts_opts = "-A10m";<br />
<br />
to force your program to use this setting on each run.<br />
<br />
== Subexpression Elimination ==<br />
<br />
=== Does GHC do common subexpression elimination? ===<br />
<br />
In general, GHC does not do CSE.<br />
It'd be a relatively easy pass for someone to add, but it can cause space leaks. And it can replace two strictly-evaluated calls with one lazy thunk:<br />
<haskell><br />
let { x = case e of ...; y = case e of ... } in ...<br />
==><br />
let { v = e; x = case v of ...; y = case v of ... } in ...<br />
</haskell><br />
Now <hask>v</hask> is allocated as a thunk. (Of course, that might be well worth it if <hask>e</hask> is an expensive expression.)<br />
<br />
Instead GHC does "opportunistic CSE". If you have <br />
<haskell><br />
let x = e in .... let y = e in ....<br />
</haskell><br />
then it'll discard the duplicate binding. This can still cause space<br />
leaks but it guarantees never to create a new thunk, and it turns out <br />
to be very useful in practice.<br />
<br />
Bottom line: if you care about sharing, do it yourself using <hask>let</hask> <br />
or <hask>where</hask>.<br />
<br />
== Laziness ==<br />
<br />
=== When can I rely on full laziness? ===<br />
<br />
Consider this program<br />
<haskell><br />
f x y = let r = expensive x <br />
in r+y<br />
g vs = map (f 2) vs<br />
</haskell><br />
Since r depends only on x, you might hope that <tt>(expensive 2)</tt> is computed just once. And that is indeed what will happen if you write<br />
<haskell><br />
f_opt x = let r = expensive x <br />
in \y -> r+y<br />
g_opt vs = map (f_opt 2) vs<br />
</haskell><br />
It's easy enough for a compiler to transform f into f_opt. (This is called the "full laziness" transformation.) BUT in the cases when f is fully-applied, f_opt is *less* efficient than f; consider<br />
<haskell><br />
h ys zs = zipWith f_opt ys zs<br />
</haskell><br />
Reason: it's much less efficient to have separate lambdas <tt>\x-> let ... in \y -> e</tt> than one compound lambda <tt>\xy -> e</tt>.<br />
<br />
So the best way to transform f depends on how it is used. When it's used locally and just once, GHC inlines it at the call site and all is good. But when it's exported or called many times, GHC's full laziness transformation uses the following rule: never "float" a let <em>between</em> two lambdas. So it won't transform f into f_opt. <br />
<br />
On the other hand, if you write f_opt, GHC will keep it that way. Furthermore, if a sub-expression can be floated right out of a complete lambda group, GHC will float it out. For example<br />
<haskell><br />
f x vs = map (\y -> y + expensive x) vs<br />
</haskell><br />
Here, the <tt>(expensive x)</tt> can be floated out of the <tt>\x->...</tt> lambda without separating two lambdas, and the full laziness transfom will do just that.<br />
<br />
---------------------------------------<br />
<br />
= Miscellaneous =<br />
<br />
== Upgrading GHC ==<br />
<br />
=== Do I have to recompile all my code if I upgrade GHC? ===<br />
<br />
Yes. There are two reasons for this:<br />
<br />
* GHC does a lot of cross-module optimisation, so compiled code will include parts of the libraries it was compiled against (including the Prelude), so will be deeply tied to the actual version of those libraries it was compiled against. When you upgrade GHC, the libraries may change; even if the external interface of the libraries doesn't change, sometimes internal details may change because GHC optimised the code in the library differently. <br />
* We sometimes change the ABI (application binary interface) between versions of GHC. Code compiled with one version of GHC is not necessarily compatible with code compiled by a different version, even if you arrange to keep the same libraries.<br />
<br />
== Shared Libraries ==<br />
<br />
=== Why doesn't GHC use shared libraries? ===<br />
<br />
GHC does provide shared libraries, currently only on MacOS X. We are working on making shared libraries work on other platforms.<br />
<br />
However, GHC-compiled libraries are very tightly coupled, which means it's unlikely you'd be able to swap out a shared library for a newer version unless it was compiled with exactly the same compiler and set of libraries as the old version.<br />
<br />
== Debugging ==<br />
<br />
=== My program is failing with head [], or an array bounds error, or some other random error, and I have no idea how to find the bug. Can you help? ===<br />
<br />
Try the [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html GHCi Debugger], in particular look at the section on "Debugging Exceptions".<br />
<br />
Alternatively, compile your program with <tt>-prof -auto-all</tt> (make sure you have the profiling libraries installed), and run it with <tt>+RTS -xc -RTS</tt> to get a ´stack trace at the point at which the exception was raised. See [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-options-debugging Section 4.14.4, ´RTS options for hackers, debuggers, and over-interested souls] for more details.<br />
<br />
== Increasing Heap Size ==<br />
<br />
=== How do I increase the heap size permanently for a given binary? ===<br />
<br />
See [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-hooks Section 4.14.5, ´´Hooks to change RTS behaviour].<br />
<br />
== Compiling for Parallel Execution ==<br />
<br />
=== I'm trying to compile my program for parallel execution with the -parallel, and GHC complains with an error like 'failed to load interface file for Prelude'. ===<br />
<br />
GHC doesn't ship with support for parallel execution; that support is provided separately by the [http://www.macs.hw.ac.uk/~dsg/gph/ GPH] project.<br />
<br />
== Using Unsafe Functions ==<br />
<br />
=== When is it safe to use [[unsafe functions]] such as <hask>unsafePerformIO</hask>? ===<br />
<br />
We'll give two answers to this question, each of which may be helpful. These criteria are not rigorous in any real sense (you'd need a formal semantics for Haskell in order to give a proper answer to this question), but should give you a feel for the kind of things you can and cannot do with unsafePerformIO.<br />
<br />
* It is safe to implement a function or API using unsafePerformIO if you could imagine also implementing the same function or API in Haskell without using unsafePerformIO (forget about efficiency, just consider the semantics).<br />
* In pure Haskell, the value of a function depends only on the values of its arguments (and free variables, if it has any). If you can implement the function using unsafePerformIO and still retain this invariant, then you're probably using unsafePerformIO in a safe way. Note that you need only consider the observable values of the arguments and result.<br />
<br />
For more information, see [http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003681.html this thread].<br />
<br />
== Using Finalizers ==<br />
<br />
=== I can't get finalizers to work properly. My program sometimes just prints <tt><<loop>></tt>. ===<br />
<br />
Chances are that your program is trying to write a message to stdout or stderr in the finalizer. Handles have finalizers themselves, and since finalizers don't keep other finalized values alive, the stdout and stderr Handles may be finalized before your finalizer runs. If this happens, your finalizer will block on the handle, and probably end up receiving a NonTermination exception (which is printed as <tt><<loop>></tt>).<br />
<br />
== Extensible Records ==<br />
<br />
=== Does GHC implement any kind of extensible records? ===<br />
<br />
No, extensible records are not implemented in GHC. [http://www.haskell.org/hugs/ Hugs] implements TRex, one extensible record variant. The problem is that the record design space is large, and seems to lack local optima. And all reasonable variants break backward compatibility. As a result, nothing much happens.<br />
<br />
== Using Extra GCC/Linker Options ==<br />
<br />
=== How can I make GHC always use some extra gcc or linker option? ===<br />
<br />
If you want to *always* use an extra option then you can edit the package configuration for the 'rts' or 'base' package since these packages are used by every program that you compile with GHC. You might want to do this if you had installed something that ghc needs but into a non-standard directory, thus requiring special compilation or linking options.<br />
<br />
All you need to do is to dump out the configuration into a human readable form, edit it and re-register the modified package configuration. The exact commands to do that are below, but first here are the fields in the file that you might want to modify:<br />
<br />
; include-dirs: directories to search for .h files<br />
; library-dirs: directories to search for libraries<br />
; extra-libraries: extra C libs to link with<br />
; cc-options: extra flags to pass to gcc when compiling C code or assembly<br />
; ld-options: extra flags to pass to '''gcc''' when linking<br />
<br />
to edit the rts package (or base) confiuration just do:<br />
# <tt>ghc-pkg describe rts > rts.package.conf</tt><br />
# edit <tt>rts.package.conf</tt> with your favourite text editor<br />
# <tt>ghc-pkg update rts.package.conf</tt><br />
<br />
On Unix systems and Windows, some options can also be set with environment variables such as LIBRARY_PATH and C_INCLUDE_PATH.</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=How_to_write_a_Haskell_program&diff=62587How to write a Haskell program2018-08-26T21:21:00Z<p>Henk-Jan van Tuyl: Added more <nowiki> tags</p>
<hr />
<div>A developers' guide to creating a new Haskell project or program, and working in the Haskell developer ecosystem.<br />
<br />
''Note: for learning the Haskell language itself we recommend [http://haskell.org/haskellwiki/Tutorials#Introductions_to_Haskell these resources].''<br />
<br />
== Recommended tools ==<br />
<br />
Almost all new Haskell projects use the following tools. Each is<br />
intrinsically useful, but using a set of common tools also helps<br />
everyone by increasing productivity, and you're more likely to get<br />
patches.<br />
<br />
=== Revision control ===<br />
<br />
Use [http://git-scm.com/ git] or [http://darcs.net darcs] unless you have a specific reason not to. Both are lightweight distributed revision control system. Darcs is written in Haskell. They are the two most popular [http://en.wikipedia.org/wiki/Distributed_version_control_system DVCS]es in the Haskell world. If you want to encourage contributions from other Haskell hackers then git is best. For git, [http://github.com/ GitHub] is very popular. Darcs hosting is available on [http://hub.darcs.net/ hub.darcs.net].<br />
<br />
=== Build system ===<br />
<br />
[[Image:Cabal-With-Text-small.png|frame|Built with Cabal]]<br />
<br />
Use [http://haskell.org/cabal/ Cabal].<br />
You should read at least the start of section 2 of the [http://www.haskell.org/cabal/users-guide/ Cabal User's Guide].<br />
<br />
You should use [http://haskell.org/cabal/download.html cabal-install] as a front-end for installing your Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)<br />
<br />
cabal-install is widely available, as a [http://www.haskell.org/cabal/download.html binary distribution] or as part of the [http://haskell.org/platform Haskell Platform], so you can probably assume your users will have it too.<br />
<br />
=== Documentation ===<br />
<br />
For libraries, use [http://haskell.org/haddock/ Haddock]. Haddock generates [http://hackage.haskell.org/package/base-4.7.0.0/docs/Prelude.html nice markup], with links to source.<br />
<br />
=== Testing ===<br />
<br />
Typical unit/spec based testing, particularly with impure code, can be done with [http://hspec.github.io/ HSpec] and [http://hackage.haskell.org/package/HUnit HUnit].<br />
<br />
You can use [http://hackage.haskell.org/package/QuickCheck QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. These libraries work best when you have known invariants in your code's behavior. See [http://hackage.haskell.org/package/hashable-1.1.2.2/hashable.cabal this Cabal file] for an example of how to include tests in your Cabal package.<br />
<br />
To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/posts/2006-09-01-simple-unit-testing.html Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell. For HUnit, see [[HUnit 1.0 User's Guide]]<br />
<br />
[https://github.com/sol/doctest#readme doctest] is another testing method similar to python [https://en.wikipedia.org/wiki/Doctest Doctest]<br />
<br />
=== Distribution ===<br />
<br />
The standard mechanism for distributing Haskell libraries and<br />
applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can<br />
host your cabalised tarball releases, and link to any library<br />
dependencies your code has. Users will find and install your packages via "cabal install", and your package will be integrated into Haskell search engines, like [http://www.haskell.org/hoogle/ hoogle]<br />
<br />
=== Target Environment ===<br />
<br />
If possible, depend on libraries that are provided by the current stable [http://daniel-diaz.github.io/stackagelist/ Stackage package versions] or the [http://haskell.org/platform Haskell Platform]. Ideally your package should be able to build with users that keep current with Stackage or users of the Platform.<br />
<br />
== Structure of a simple project ==<br />
<br />
The basic structure of a new Haskell project can be adopted from<br />
[https://github.com/strangemonad/hnop HNop], the minimal Haskell project. It<br />
consists of the following files, for the mythical project "haq".<br />
<br />
* Haq.hs -- the main haskell source file<br />
* haq.cabal -- the cabal build description<br />
* Setup.hs -- build script itself<br />
* .git -- revision control<br />
* README -- info<br />
* LICENSE -- license<br />
<br />
Of course, you can elaborate on this, with subdirectories and multiple<br />
modules. See [[Structure of a Haskell project]] for an example of a larger project's directory structure.<br />
<br />
Here is a transcript that shows how you'd create a minimal git and cabalised<br />
Haskell project for the cool new Haskell program "haq", build it,<br />
install it and release.<br />
<br />
''Note'': The new tool "cabal init" automates all this for you, but you should<br />
understand all the parts even so. <br />
<br />
We will now walk through the creation of the infrastructure for a simple<br />
Haskell executable. Advice for libraries follows after.<br />
<br />
=== Create a directory ===<br />
<br />
Create somewhere for the source:<br />
<br />
<code><br />
$ mkdir haq<br />
$ cd haq<br />
</code><br />
<br />
=== Write some Haskell source ===<br />
<br />
Write your program:<br />
<br />
<haskell><br />
$ cat > Haq.hs<br />
--<br />
-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/<br />
-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
--<br />
import System.Environment<br />
<br />
-- | 'main' runs the main program<br />
main :: IO ()<br />
main = getArgs >>= print . haqify . head<br />
<br />
haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
=== Stick it in version control ===<br />
<br />
Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):<br />
<br />
<code><br />
$ git init<br />
$ git add Haq.hs <br />
$ git commit -am "my commit message"<br />
</code><br />
<br />
=== Add a build system ===<br />
<br />
Create a .cabal file describing how to build your project:<br />
<code><br />
$ cabal init<br />
</code><br />
<br />
that will ask a few questions about your project and generate a file similar to the example:<br />
<br />
<code><br />
-- Initial scratch.cabal generated by cabal init. For further <br />
-- documentation, see http://haskell.org/cabal/users-guide/<br />
<br />
name: haq<br />
version: 0.1.0.0<br />
description: Super cool mega lambdas<br />
license: GPL<br />
license-file: LICENSE<br />
author: Don Stewart<br />
maintainer: dons@cse.unsw.edu.au<br />
build-type: Simple<br />
cabal-version: >=1.10<br />
<br />
executable haq<br />
main-is: Haq.hs <br />
build-depends: base >=4.5 && <4.8<br />
default-language: Haskell2010<br />
</code><br />
<br />
(If your package uses other packages, e.g. <tt>text</tt>, you'll need to add them to the <tt>build-depends:</tt> field as a comma separated list.)<br />
<br />
Cabal will also generate a <tt>Setup.hs</tt> file that will do the actual building. You will rarely need to modify it.<br />
<br />
If you specifed a known license, it will also add a LICENSE file.<br />
<br />
You might like to add a README file to tell what your project is about.<br />
<br />
Record your changes:<br />
<br />
<code><br />
$ git add haq.cabal Setup.hs LICENSE README<br />
$ git commit -am "Add a build system"<br />
</code><br />
<br />
=== Build your project ===<br />
<br />
Now build it! There are two methods of accessing Cabal functionality: through your Setup.hs script or through cabal-install. cabal-install is now the preferred method.<br />
<br />
Building using cabal-install and sandboxes, always use sandboxes in your projects unless you are an expert and know what you are doing! Demonstrated here:<br />
<br />
<code><br />
$ cabal sandbox init<br />
$ cabal install -j<br />
</code><br />
<br />
This will install your newly minted haq program in $PROJECT_DIR/.cabal-sandbox/bin.<br />
<br />
=== Run it ===<br />
<br />
And now you can run your cool project:<br />
<code><br />
$ .cabal-sandbox/bin/haq me<br />
"Haq! me"<br />
</code><br />
<br />
Since our program doesn't rely on any other assets we can just copy it to a directory in our path if we want to be able to use it from anywhere without referencing the sandbox directory. Like so:<br />
<br />
<code><br />
$ sudo cp .cabal-sandbox/bin/haq /usr/local/bin/haq<br />
$ haq me<br />
"Haq! me"<br />
</code><br />
<br />
=== Build some haddock documentation ===<br />
<br />
Generate some API documentation into dist/doc/*<br />
<br />
Using cabal install:<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
Using cabal install if you planned to upload your haq package to Hackage:<br />
<br><code><nowiki><br />
$ cabal haddock --hyperlink-source --html-location='http://hackage.haskell.org/package/haq/docs' --contents-location='http://hackage.haskell.org/package/haq'<br />
</nowiki></code><br />
<br />
which generates files in dist/doc/ including:<br />
<br />
<code><br />
$ w3m -dump dist/doc/html/haq/Main.html<br />
haq Contents Index<br />
Main<br />
<br />
Synopsis<br />
main :: IO ()<br />
<br />
Documentation<br />
<br />
main :: IO ()<br />
main runs the main program<br />
<br />
Produced by Haddock version 0.7<br />
</code><br />
<br />
No output? Make sure you have actually installed haddock. It is a separate program, not something that comes with Cabal. Note that the stylized comment in the source gets picked up by Haddock.<br />
<br />
=== (Optional) Improve your code: HLint ===<br />
<br />
[http://hackage.haskell.org/package/hlint HLint] can be a valuable tool for improving your coding style, particularly if you're new to Haskell. Let's run it now.<br />
<br />
<code><br />
$ hlint .<br />
./Haq.hs:11:1: Warning: Eta reduce<br />
Found:<br />
haqify s = "Haq! " ++ s<br />
Why not:<br />
haqify = ("Haq! " ++)<br />
</code><br />
<br />
The existing code will work, but let's follow that suggestion. Open Haq.hs in your favourite editor and change the line:<br />
<br />
<haskell><br />
where haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
to:<br />
<br />
<haskell><br />
where haqify = ("Haq! " ++)<br />
</haskell><br />
<br />
=== Add some tests ===<br />
<br />
==== HSpec ====<br />
<br />
If you'd like to use HSpec:<br />
<br />
To your cabal, add:<br />
<br />
<code><br />
test-suite tests<br />
ghc-options: -Wall<br />
default-extensions: OverloadedStrings<br />
type: exitcode-stdio-1.0<br />
main-is: HSpecTests.hs<br />
build-depends: base,<br />
haq,<br />
hspec >= 1.8<br />
default-language: Haskell2010<br />
</code><br />
<br />
To enable tests and install HSpec (and any other needed dependencies):<br />
<br />
<code><br />
$ cabal install --enable-tests<br />
</code><br />
<br />
Then for your actual file containing the test code:<br />
<br />
<haskell><br />
$ cat > HSpecTests.hs<br />
module Main where<br />
<br />
import Haq<br />
import Test.Hspec<br />
<br />
main :: IO ()<br />
main = hspec $ do<br />
<br />
describe "Validate haqify function" $ do<br />
it "haqify is supposed to prefix Haq! to things" $ do<br />
haqify "me" `shouldBe` "Haq! me"<br />
<br />
</haskell><br />
<br />
Execute the tests with:<br />
<br />
<code><br />
$ cabal test<br />
</code><br />
<br />
==== QuickCheck ====<br />
<br />
If you're using QuickCheck:<br />
<br />
<haskell><br />
$ cat > QuickTests.hs<br />
<br />
import Data.Char<br />
import Data.List<br />
import Haq<br />
import Test.QuickCheck<br />
import Text.Printf<br />
<br />
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests<br />
<br />
-- reversing twice a finite list, is the same as identity<br />
prop_reversereverse s = (reverse . reverse) s == id s<br />
where _ = s :: [Int]<br />
<br />
-- Dropping the "Haq! " string is the same as identity<br />
prop_haq s = drop (length "Haq! ") (haqify s) == id s<br />
where haqify s = "Haq! " ++ s<br />
<br />
tests = [("reverse.reverse/id", quickCheck prop_reversereverse)<br />
,("drop.haq/id", quickCheck prop_haq)]<br />
</haskell><br />
<br />
To run the test:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : +++ OK, passed 100 tests.<br />
drop.haq/id : +++ OK, passed 100 tests.<br />
</code><br />
<br />
Success!<br />
<br />
=== Tag the stable version, create a tarball, and sell it! ===<br />
<br />
Tag the stable version:<br />
<br />
<code><br />
$ git tag 0.0<br />
</code><br />
<br />
==== Create a tarball ====<br />
You can do this using either Cabal or an explicit <tt>tar</tt> command.<br />
<br />
===== Using Cabal =====<br />
<br />
Since the code is cabalised, we can create a tarball with cabal-install<br />
directly (you can also use <tt>runhaskell Setup.hs sdist</tt>, but you need <tt>tar</tt> on your system [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/60617/focus=60653]):<br />
<br />
<code><br />
$ cabal sdist<br />
Building source dist for haq-0.0...<br />
Source tarball created: dist/haq-0.0.tar.gz<br />
</code><br />
This has the advantage that Cabal will do a bit more checking, and<br />
ensure that the tarball has the structure that HackageDB expects. <br />
Note that it does require the LICENSE file to exist.<br />
It packages up the files needed to build the project; to include other files (such as <tt>Test.hs</tt> in the above example, and our README), we need to add:<br />
<br />
<code><br />
extra-source-files: Tests.hs README<br />
</code><br />
<br />
to the .cabal file to have everything included.<br />
<br />
==== Check that your source package is complete ====<br />
<br />
Just to make sure everything works, try building the source package in some temporary directory:<br />
<code><br />
$ tar xzf haq-0.0.tar.gz<br />
$ cd haq-0.0<br />
$ cabal configure<br />
$ cabal build<br />
</code><br />
and for packages containing libraries,<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
==== Upload your package to Hackage ====<br />
<br />
Whichever of the above methods you've used to create your package, you can upload it to the Hackage package collection via a [http://hackage.haskell.org/upload web interface].<br />
You may wish to use the package checking interface there first, and fix things it warns about, before uploading your package.<br />
<br />
==== Upload your package documentation to Hackage ====<br />
<br />
Assuming you built your documentation like this:<br />
<br />
<code><nowiki><br />
$ cabal haddock --hyperlink-source --html-location='http://hackage.haskell.org/package/haq/docs' --contents-location='http://hackage.haskell.org/package/haq'<br />
</nowiki></code><br />
<br />
You can force upload (so you don't have to wait on the server to build it for you) your documentation for your package like so:<br />
<br />
<code><nowiki><br />
$ cp -R ./dist/doc/html/haq/ haq-0.0-docs<br />
$ tar cvzf --format=ustar -f haq-0.0-docs.tar.gz haq-0.0-docs<br />
$ curl -X PUT -H 'Content-Type: application/x-tar' -H 'Content-Encoding: gzip' --data-binary '@haq-0.0-docs.tar.gz' 'https://$USERNAME:$PASSWORD@hackage.haskell.org/package/haq-0.0/docs'<br />
</nowiki></code><br />
<br />
=== Summary ===<br />
<br />
The following files were created:<br />
<br />
$ ls<br />
Haq.hs HSpecTests.hs dist haq.cabal<br />
Setup.hs .git haq-0.0.tar.gz QuickTests.hs<br />
<br />
== Libraries ==<br />
<br />
The process for creating a Haskell library is almost identical. The differences<br />
are as follows, for the hypothetical "ltree" library:<br />
<br />
=== Hierarchical source ===<br />
<br />
The source should live under a directory path that fits into the<br />
existing [[Hierarchical module names|module layout guide]].<br />
So we would create the following directory structure, for the module<br />
Data.LTree:<br />
<br />
$ mkdir Data<br />
$ cat > Data/LTree.hs <br />
module Data.LTree where<br />
<br />
So our Data.LTree module lives in Data/LTree.hs<br />
<br />
=== The Cabal file ===<br />
<br />
Cabal files for libraries list the publically visible modules, and have<br />
no executable section:<br />
<br />
$ cat > ltree.cabal <br />
Name: ltree<br />
Version: 0.1<br />
Description: Lambda tree implementation<br />
License: BSD3<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Type: Simple<br />
Cabal-Version: >=1.2<br />
<br />
Library<br />
Build-Depends: base >= 3 && < 5<br />
Exposed-modules: Data.LTree<br />
ghc-options: -Wall<br />
<br />
We can thus build our library:<br />
<br />
$ cabal configure --prefix=$HOME --user<br />
$ cabal build <br />
Preprocessing library ltree-0.1...<br />
Building ltree-0.1...<br />
[1 of 1] Compiling Data.LTree ( Data/LTree.hs, dist/build/Data/LTree.o )<br />
/usr/bin/ar: creating dist/build/libHSltree-0.1.a<br />
<br />
and our library has been created as a object archive. Now install it:<br />
<br />
$ cabal install<br />
Installing: /home/dons/lib/ltree-0.1/ghc-6.6 & /home/dons/bin ltree-0.1...<br />
Registering ltree-0.1...<br />
Reading package info from ".installed-pkg-config" ... done.<br />
Saving old package config file... done.<br />
Writing new package config file... done.<br />
<br />
And we're done!<br />
To try it out, first make sure that your working directory is anything but the source directory of your library:<br />
<br />
$ cd ..<br />
<br />
And then use your new library from, for example, ghci:<br />
<br />
$ ghci -package ltree<br />
Prelude> :m + Data.LTree<br />
Prelude Data.LTree> <br />
<br />
The new library is in scope, and ready to go.<br />
<br />
=== More complex build systems ===<br />
<br />
For larger projects, you may want to store source trees in subdirectories. This can be done simply by creating a directory -- for example, "src" -- into which you will put your src tree.<br />
<br />
To have Cabal find this code, you add the following line to your Cabal<br />
file:<br />
<br />
hs-source-dirs: src<br />
<br />
You can also set up Cabal to run configure scripts, among other features. For more information consult the<br />
[http://www.haskell.org/cabal/users-guide/ Cabal user guide].<br />
<br />
== Licenses ==<br />
<br />
Code for the common base library package must be BSD licensed. Otherwise, it<br />
is entirely up to you as the author.<br />
Choose a licence (inspired by [http://archive.is/http://web.archive.org/web/20031206042644/http://www.dina.dk/~abraham/rants/license.html this]).<br />
Check the licences of things you use (both other Haskell packages and C<br />
libraries), since these may impose conditions you must follow.<br />
Use the same licence as related projects, where possible. The Haskell community is<br />
split into 2 camps, roughly: those who release everything under BSD, and<br />
(L)GPLers. Some Haskellers recommend avoiding LGPL, due to cross-module optimisation<br />
issues. Like many licensing questions, this advice is controversial. Several Haskell projects<br />
(wxHaskell, HaXml, etc) use the LGPL with an extra permissive clause which gets round the<br />
cross-module optimisation problem.<br />
<br />
== Releases ==<br />
<br />
It's important to release your code as stable, tagged tarballs. Don't just rely on your commit hashes for tracking history, tag your released versions and milestones!<br />
<br />
* '''git archive''' generates tarballs directly from a git repository based on the provided tag.<br />
<br />
For example:<br />
<br />
$ cd fps<br />
$ ls <br />
Data LICENSE README Setup.hs TODO .git cbits dist fps.cabal tests<br />
$ git tag v0.8<br />
$ git archive --format=tar.gz v0.8 > fps-0.8.tar.gz<br />
<br />
You can now just post your fps-0.8.tar.gz<br />
<br />
<br />
* Tag each release using '''git tag'''. For example:<br />
<br />
== Hosting ==<br />
<br />
Hosting for repos is available from [http://github.com Github] and the [http://community.haskell.org/ Haskell community server]<br />
<br />
There is also a (minimal) Github equivalent for Darcs at [http://hub.darcs.net/ hub.darcs.net].<br />
<br />
== Web page ==<br />
<br />
Create a web page documenting your project! An easy way to do this is to<br />
add a project specific page to [[HaskellWiki:Contributing|the Haskell wiki]]<br />
<br />
== The user experience ==<br />
<br />
When developing a new Haskell library, it is important to remember how the user expects to be able to build and use a library.<br />
<br />
=== Introductory information and build guide ===<br />
<br />
A typical library user expects to:<br />
<br />
# Visit [[Haskell|Haskell.org]]<br />
# Find the library/program they are looking for:<br />
## if not found, try mailing list; <br />
## if it is hidden, try improving the documentation on haskell.org;<br />
## if it does not exist, try contributing code and documentation) <br />
# Download<br />
# Build and install<br />
# Enjoy<br />
<br />
Each of these steps can pose potential road blocks, and code authors can<br />
do a lot to help code users avoid such blocks. Steps 1..2 may be easy enough, and many coders and users are mainly concerned with step 5. Steps 3..4 are the ones that often get in the way. In particular, the<br />
following questions should have clear answers:<br />
<br />
* Which is the latest version? <br />
* What state is it in? <br />
* What are its aims? <br />
* Where is the documentation?<br />
* Which is the right version for given OS and Haskell implementation?<br />
* How is it packaged, and what tools are needed to get and unpack it?<br />
* How is it installed, and what tools are needed to install it?<br />
* How do we handle dependencies?<br />
* How do we provide/acquire the knowledge and tool-chains needed?<br />
<br />
The best place to answer these questions is a README file,<br />
distributed with the library or application, and often accompanied with<br />
similar text on a more extensive web page.<br />
<br />
=== Tutorials ===<br />
<br />
Generated haddock documentation is usually not enough to help new<br />
programmers learn how to use a library. You must also provide accompanying examples, and even tutorials about the library.<br />
<br />
Please consider providing example code for your library or application. The code should be type-correct and well-commented.<br />
<br />
== Program structure ==<br />
<br />
Monad transformers are very useful for programming in the large,<br />
encapsulating state, and controlling side effects. To learn more about this approach, try [http://www.grabmueller.de/martin/www/pub/Transformers.en.html Monad Transformers Step by Step].<br />
<br />
== Publicity ==<br />
<br />
The best code in the world is meaningless if nobody knows about it. The<br />
process to follow once you've tagged and released your code is:<br />
<br />
=== Join the community ===<br />
<br />
If you haven't already, join the community. The best way to do this is to [http://haskell.org/haskellwiki/Mailing_lists subscribe] to at least haskell-cafe@ and haskell@ mailing lists. Joining the [[IRC_channel|#haskell IRC channel]] is also an excellent idea.<br />
<br />
=== Announce your project on haskell@ ===<br />
<br />
Most important: announce your project releases to the haskell@haskell.org mailing list. Tag your email subject line with "ANNOUNCE: ...". This ensure it will then make it into the [http://haskell.org/haskellwiki/HWN Haskell Weekly News]. To be doubly sure, you can email the release text to the [[HWN|HWN editor]].<br />
<br />
=== Add your code to the public collections ===<br />
<br />
* Add your library or application to the [[Libraries and tools]] page, under the relevant category, so people can find it.<br />
<br />
* If your release is a Cabal package, add it to the [http://hackage.haskell.org/packages/hackage.html Hackage database]<br />
<br />
* If your library stays up to date with its dependencies, add it to the vetted packages on [https://github.com/fpco/stackage Stackage].<br />
<br />
=== Blog about it ===<br />
<br />
Blog about it! Blog about your new code on [http://planet.haskell.org Planet Haskell].<br />
Write about your project in your blog, then email the [http://planet.haskell.org/ Planet Haskell] maintainer (ibid on [[IRC channel|#haskell]]) the RSS feed url for your blog<br />
<br />
[[Category:Community]]<br />
[[Category:Tutorials]]</div>Henk-Jan van Tuylhttps://wiki.haskell.org/index.php?title=How_to_write_a_Haskell_program&diff=62586How to write a Haskell program2018-08-26T17:05:29Z<p>Henk-Jan van Tuyl: /* Build some haddock documentation */ Added <nowiki> to prevent invalid links; added spaces to improve lay-out</p>
<hr />
<div>A developers' guide to creating a new Haskell project or program, and working in the Haskell developer ecosystem.<br />
<br />
''Note: for learning the Haskell language itself we recommend [http://haskell.org/haskellwiki/Tutorials#Introductions_to_Haskell these resources].''<br />
<br />
== Recommended tools ==<br />
<br />
Almost all new Haskell projects use the following tools. Each is<br />
intrinsically useful, but using a set of common tools also helps<br />
everyone by increasing productivity, and you're more likely to get<br />
patches.<br />
<br />
=== Revision control ===<br />
<br />
Use [http://git-scm.com/ git] or [http://darcs.net darcs] unless you have a specific reason not to. Both are lightweight distributed revision control system. Darcs is written in Haskell. They are the two most popular [http://en.wikipedia.org/wiki/Distributed_version_control_system DVCS]es in the Haskell world. If you want to encourage contributions from other Haskell hackers then git is best. For git, [http://github.com/ GitHub] is very popular. Darcs hosting is available on [http://hub.darcs.net/ hub.darcs.net].<br />
<br />
=== Build system ===<br />
<br />
[[Image:Cabal-With-Text-small.png|frame|Built with Cabal]]<br />
<br />
Use [http://haskell.org/cabal/ Cabal].<br />
You should read at least the start of section 2 of the [http://www.haskell.org/cabal/users-guide/ Cabal User's Guide].<br />
<br />
You should use [http://haskell.org/cabal/download.html cabal-install] as a front-end for installing your Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)<br />
<br />
cabal-install is widely available, as a [http://www.haskell.org/cabal/download.html binary distribution] or as part of the [http://haskell.org/platform Haskell Platform], so you can probably assume your users will have it too.<br />
<br />
=== Documentation ===<br />
<br />
For libraries, use [http://haskell.org/haddock/ Haddock]. Haddock generates [http://hackage.haskell.org/package/base-4.7.0.0/docs/Prelude.html nice markup], with links to source.<br />
<br />
=== Testing ===<br />
<br />
Typical unit/spec based testing, particularly with impure code, can be done with [http://hspec.github.io/ HSpec] and [http://hackage.haskell.org/package/HUnit HUnit].<br />
<br />
You can use [http://hackage.haskell.org/package/QuickCheck QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. These libraries work best when you have known invariants in your code's behavior. See [http://hackage.haskell.org/package/hashable-1.1.2.2/hashable.cabal this Cabal file] for an example of how to include tests in your Cabal package.<br />
<br />
To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/posts/2006-09-01-simple-unit-testing.html Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell. For HUnit, see [[HUnit 1.0 User's Guide]]<br />
<br />
[https://github.com/sol/doctest#readme doctest] is another testing method similar to python [https://en.wikipedia.org/wiki/Doctest Doctest]<br />
<br />
=== Distribution ===<br />
<br />
The standard mechanism for distributing Haskell libraries and<br />
applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can<br />
host your cabalised tarball releases, and link to any library<br />
dependencies your code has. Users will find and install your packages via "cabal install", and your package will be integrated into Haskell search engines, like [http://www.haskell.org/hoogle/ hoogle]<br />
<br />
=== Target Environment ===<br />
<br />
If possible, depend on libraries that are provided by the current stable [http://daniel-diaz.github.io/stackagelist/ Stackage package versions] or the [http://haskell.org/platform Haskell Platform]. Ideally your package should be able to build with users that keep current with Stackage or users of the Platform.<br />
<br />
== Structure of a simple project ==<br />
<br />
The basic structure of a new Haskell project can be adopted from<br />
[https://github.com/strangemonad/hnop HNop], the minimal Haskell project. It<br />
consists of the following files, for the mythical project "haq".<br />
<br />
* Haq.hs -- the main haskell source file<br />
* haq.cabal -- the cabal build description<br />
* Setup.hs -- build script itself<br />
* .git -- revision control<br />
* README -- info<br />
* LICENSE -- license<br />
<br />
Of course, you can elaborate on this, with subdirectories and multiple<br />
modules. See [[Structure of a Haskell project]] for an example of a larger project's directory structure.<br />
<br />
Here is a transcript that shows how you'd create a minimal git and cabalised<br />
Haskell project for the cool new Haskell program "haq", build it,<br />
install it and release.<br />
<br />
''Note'': The new tool "cabal init" automates all this for you, but you should<br />
understand all the parts even so. <br />
<br />
We will now walk through the creation of the infrastructure for a simple<br />
Haskell executable. Advice for libraries follows after.<br />
<br />
=== Create a directory ===<br />
<br />
Create somewhere for the source:<br />
<br />
<code><br />
$ mkdir haq<br />
$ cd haq<br />
</code><br />
<br />
=== Write some Haskell source ===<br />
<br />
Write your program:<br />
<br />
<haskell><br />
$ cat > Haq.hs<br />
--<br />
-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/<br />
-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
--<br />
import System.Environment<br />
<br />
-- | 'main' runs the main program<br />
main :: IO ()<br />
main = getArgs >>= print . haqify . head<br />
<br />
haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
=== Stick it in version control ===<br />
<br />
Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):<br />
<br />
<code><br />
$ git init<br />
$ git add Haq.hs <br />
$ git commit -am "my commit message"<br />
</code><br />
<br />
=== Add a build system ===<br />
<br />
Create a .cabal file describing how to build your project:<br />
<code><br />
$ cabal init<br />
</code><br />
<br />
that will ask a few questions about your project and generate a file similar to the example:<br />
<br />
<code><br />
-- Initial scratch.cabal generated by cabal init. For further <br />
-- documentation, see http://haskell.org/cabal/users-guide/<br />
<br />
name: haq<br />
version: 0.1.0.0<br />
description: Super cool mega lambdas<br />
license: GPL<br />
license-file: LICENSE<br />
author: Don Stewart<br />
maintainer: dons@cse.unsw.edu.au<br />
build-type: Simple<br />
cabal-version: >=1.10<br />
<br />
executable haq<br />
main-is: Haq.hs <br />
build-depends: base >=4.5 && <4.8<br />
default-language: Haskell2010<br />
</code><br />
<br />
(If your package uses other packages, e.g. <tt>text</tt>, you'll need to add them to the <tt>build-depends:</tt> field as a comma separated list.)<br />
<br />
Cabal will also generate a <tt>Setup.hs</tt> file that will do the actual building. You will rarely need to modify it.<br />
<br />
If you specifed a known license, it will also add a LICENSE file.<br />
<br />
You might like to add a README file to tell what your project is about.<br />
<br />
Record your changes:<br />
<br />
<code><br />
$ git add haq.cabal Setup.hs LICENSE README<br />
$ git commit -am "Add a build system"<br />
</code><br />
<br />
=== Build your project ===<br />
<br />
Now build it! There are two methods of accessing Cabal functionality: through your Setup.hs script or through cabal-install. cabal-install is now the preferred method.<br />
<br />
Building using cabal-install and sandboxes, always use sandboxes in your projects unless you are an expert and know what you are doing! Demonstrated here:<br />
<br />
<code><br />
$ cabal sandbox init<br />
$ cabal install -j<br />
</code><br />
<br />
This will install your newly minted haq program in $PROJECT_DIR/.cabal-sandbox/bin.<br />
<br />
=== Run it ===<br />
<br />
And now you can run your cool project:<br />
<code><br />
$ .cabal-sandbox/bin/haq me<br />
"Haq! me"<br />
</code><br />
<br />
Since our program doesn't rely on any other assets we can just copy it to a directory in our path if we want to be able to use it from anywhere without referencing the sandbox directory. Like so:<br />
<br />
<code><br />
$ sudo cp .cabal-sandbox/bin/haq /usr/local/bin/haq<br />
$ haq me<br />
"Haq! me"<br />
</code><br />
<br />
=== Build some haddock documentation ===<br />
<br />
Generate some API documentation into dist/doc/*<br />
<br />
Using cabal install:<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
Using cabal install if you planned to upload your haq package to Hackage:<br />
<br><code><nowiki><br />
$ cabal haddock --hyperlink-source --html-location='http://hackage.haskell.org/package/haq/docs' --contents-location='http://hackage.haskell.org/package/haq'<br />
</nowiki></code><br />
<br />
which generates files in dist/doc/ including:<br />
<br />
<code><br />
$ w3m -dump dist/doc/html/haq/Main.html<br />
haq Contents Index<br />
Main<br />
<br />
Synopsis<br />
main :: IO ()<br />
<br />
Documentation<br />
<br />
main :: IO ()<br />
main runs the main program<br />
<br />
Produced by Haddock version 0.7<br />
</code><br />
<br />
No output? Make sure you have actually installed haddock. It is a separate program, not something that comes with Cabal. Note that the stylized comment in the source gets picked up by Haddock.<br />
<br />
=== (Optional) Improve your code: HLint ===<br />
<br />
[http://hackage.haskell.org/package/hlint HLint] can be a valuable tool for improving your coding style, particularly if you're new to Haskell. Let's run it now.<br />
<br />
<code><br />
$ hlint .<br />
./Haq.hs:11:1: Warning: Eta reduce<br />
Found:<br />
haqify s = "Haq! " ++ s<br />
Why not:<br />
haqify = ("Haq! " ++)<br />
</code><br />
<br />
The existing code will work, but let's follow that suggestion. Open Haq.hs in your favourite editor and change the line:<br />
<br />
<haskell><br />
where haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
to:<br />
<br />
<haskell><br />
where haqify = ("Haq! " ++)<br />
</haskell><br />
<br />
=== Add some tests ===<br />
<br />
==== HSpec ====<br />
<br />
If you'd like to use HSpec:<br />
<br />
To your cabal, add:<br />
<br />
<code><br />
test-suite tests<br />
ghc-options: -Wall<br />
default-extensions: OverloadedStrings<br />
type: exitcode-stdio-1.0<br />
main-is: HSpecTests.hs<br />
build-depends: base,<br />
haq,<br />
hspec >= 1.8<br />
default-language: Haskell2010<br />
</code><br />
<br />
To enable tests and install HSpec (and any other needed dependencies):<br />
<br />
<code><br />
$ cabal install --enable-tests<br />
</code><br />
<br />
Then for your actual file containing the test code:<br />
<br />
<haskell><br />
$ cat > HSpecTests.hs<br />
module Main where<br />
<br />
import Haq<br />
import Test.Hspec<br />
<br />
main :: IO ()<br />
main = hspec $ do<br />
<br />
describe "Validate haqify function" $ do<br />
it "haqify is supposed to prefix Haq! to things" $ do<br />
haqify "me" `shouldBe` "Haq! me"<br />
<br />
</haskell><br />
<br />
Execute the tests with:<br />
<br />
<code><br />
$ cabal test<br />
</code><br />
<br />
==== QuickCheck ====<br />
<br />
If you're using QuickCheck:<br />
<br />
<haskell><br />
$ cat > QuickTests.hs<br />
<br />
import Data.Char<br />
import Data.List<br />
import Haq<br />
import Test.QuickCheck<br />
import Text.Printf<br />
<br />
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests<br />
<br />
-- reversing twice a finite list, is the same as identity<br />
prop_reversereverse s = (reverse . reverse) s == id s<br />
where _ = s :: [Int]<br />
<br />
-- Dropping the "Haq! " string is the same as identity<br />
prop_haq s = drop (length "Haq! ") (haqify s) == id s<br />
where haqify s = "Haq! " ++ s<br />
<br />
tests = [("reverse.reverse/id", quickCheck prop_reversereverse)<br />
,("drop.haq/id", quickCheck prop_haq)]<br />
</haskell><br />
<br />
To run the test:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : +++ OK, passed 100 tests.<br />
drop.haq/id : +++ OK, passed 100 tests.<br />
</code><br />
<br />
Success!<br />
<br />
=== Tag the stable version, create a tarball, and sell it! ===<br />
<br />
Tag the stable version:<br />
<br />
<code><br />
$ git tag 0.0<br />
</code><br />
<br />
==== Create a tarball ====<br />
You can do this using either Cabal or an explicit <tt>tar</tt> command.<br />
<br />
===== Using Cabal =====<br />
<br />
Since the code is cabalised, we can create a tarball with cabal-install<br />
directly (you can also use <tt>runhaskell Setup.hs sdist</tt>, but you need <tt>tar</tt> on your system [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/60617/focus=60653]):<br />
<br />
<code><br />
$ cabal sdist<br />
Building source dist for haq-0.0...<br />
Source tarball created: dist/haq-0.0.tar.gz<br />
</code><br />
This has the advantage that Cabal will do a bit more checking, and<br />
ensure that the tarball has the structure that HackageDB expects. <br />
Note that it does require the LICENSE file to exist.<br />
It packages up the files needed to build the project; to include other files (such as <tt>Test.hs</tt> in the above example, and our README), we need to add:<br />
<br />
<code><br />
extra-source-files: Tests.hs README<br />
</code><br />
<br />
to the .cabal file to have everything included.<br />
<br />
==== Check that your source package is complete ====<br />
<br />
Just to make sure everything works, try building the source package in some temporary directory:<br />
<code><br />
$ tar xzf haq-0.0.tar.gz<br />
$ cd haq-0.0<br />
$ cabal configure<br />
$ cabal build<br />
</code><br />
and for packages containing libraries,<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
==== Upload your package to Hackage ====<br />
<br />
Whichever of the above methods you've used to create your package, you can upload it to the Hackage package collection via a [http://hackage.haskell.org/upload web interface].<br />
You may wish to use the package checking interface there first, and fix things it warns about, before uploading your package.<br />
<br />
==== Upload your package documentation to Hackage ====<br />
<br />
Assuming you built your documentation like this:<br />
<br />
<code><br />
$ cabal haddock --hyperlink-source --html-location='http://hackage.haskell.org/package/haq/docs' --contents-location='http://hackage.haskell.org/package/haq'<br />
</code><br />
<br />
You can force upload (so you don't have to wait on the server to build it for you) your documentation for your package like so:<br />
<br />
<code><br />
$ cp -R ./dist/doc/html/haq/ haq-0.0-docs<br />
$ tar cvzf --format=ustar -f haq-0.0-docs.tar.gz haq-0.0-docs<br />
$ curl -X PUT -H 'Content-Type: application/x-tar' -H 'Content-Encoding: gzip' --data-binary '@haq-0.0-docs.tar.gz' 'https://$USERNAME:$PASSWORD@hackage.haskell.org/package/haq-0.0/docs'<br />
</code><br />
<br />
=== Summary ===<br />
<br />
The following files were created:<br />
<br />
$ ls<br />
Haq.hs HSpecTests.hs dist haq.cabal<br />
Setup.hs .git haq-0.0.tar.gz QuickTests.hs<br />
<br />
== Libraries ==<br />
<br />
The process for creating a Haskell library is almost identical. The differences<br />
are as follows, for the hypothetical "ltree" library:<br />
<br />
=== Hierarchical source ===<br />
<br />
The source should live under a directory path that fits into the<br />
existing [[Hierarchical module names|module layout guide]].<br />
So we would create the following directory structure, for the module<br />
Data.LTree:<br />
<br />
$ mkdir Data<br />
$ cat > Data/LTree.hs <br />
module Data.LTree where<br />
<br />
So our Data.LTree module lives in Data/LTree.hs<br />
<br />
=== The Cabal file ===<br />
<br />
Cabal files for libraries list the publically visible modules, and have<br />
no executable section:<br />
<br />
$ cat > ltree.cabal <br />
Name: ltree<br />
Version: 0.1<br />
Description: Lambda tree implementation<br />
License: BSD3<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Type: Simple<br />
Cabal-Version: >=1.2<br />
<br />
Library<br />
Build-Depends: base >= 3 && < 5<br />
Exposed-modules: Data.LTree<br />
ghc-options: -Wall<br />
<br />
We can thus build our library:<br />
<br />
$ cabal configure --prefix=$HOME --user<br />
$ cabal build <br />
Preprocessing library ltree-0.1...<br />
Building ltree-0.1...<br />
[1 of 1] Compiling Data.LTree ( Data/LTree.hs, dist/build/Data/LTree.o )<br />
/usr/bin/ar: creating dist/build/libHSltree-0.1.a<br />
<br />
and our library has been created as a object archive. Now install it:<br />
<br />
$ cabal install<br />
Installing: /home/dons/lib/ltree-0.1/ghc-6.6 & /home/dons/bin ltree-0.1...<br />
Registering ltree-0.1...<br />
Reading package info from ".installed-pkg-config" ... done.<br />
Saving old package config file... done.<br />
Writing new package config file... done.<br />
<br />
And we're done!<br />
To try it out, first make sure that your working directory is anything but the source directory of your library:<br />
<br />
$ cd ..<br />
<br />
And then use your new library from, for example, ghci:<br />
<br />
$ ghci -package ltree<br />
Prelude> :m + Data.LTree<br />
Prelude Data.LTree> <br />
<br />
The new library is in scope, and ready to go.<br />
<br />
=== More complex build systems ===<br />
<br />
For larger projects, you may want to store source trees in subdirectories. This can be done simply by creating a directory -- for example, "src" -- into which you will put your src tree.<br />
<br />
To have Cabal find this code, you add the following line to your Cabal<br />
file:<br />
<br />
hs-source-dirs: src<br />
<br />
You can also set up Cabal to run configure scripts, among other features. For more information consult the<br />
[http://www.haskell.org/cabal/users-guide/ Cabal user guide].<br />
<br />
== Licenses ==<br />
<br />
Code for the common base library package must be BSD licensed. Otherwise, it<br />
is entirely up to you as the author.<br />
Choose a licence (inspired by [http://archive.is/http://web.archive.org/web/20031206042644/http://www.dina.dk/~abraham/rants/license.html this]).<br />
Check the licences of things you use (both other Haskell packages and C<br />
libraries), since these may impose conditions you must follow.<br />
Use the same licence as related projects, where possible. The Haskell community is<br />
split into 2 camps, roughly: those who release everything under BSD, and<br />
(L)GPLers. Some Haskellers recommend avoiding LGPL, due to cross-module optimisation<br />
issues. Like many licensing questions, this advice is controversial. Several Haskell projects<br />
(wxHaskell, HaXml, etc) use the LGPL with an extra permissive clause which gets round the<br />
cross-module optimisation problem.<br />
<br />
== Releases ==<br />
<br />
It's important to release your code as stable, tagged tarballs. Don't just rely on your commit hashes for tracking history, tag your released versions and milestones!<br />
<br />
* '''git archive''' generates tarballs directly from a git repository based on the provided tag.<br />
<br />
For example:<br />
<br />
$ cd fps<br />
$ ls <br />
Data LICENSE README Setup.hs TODO .git cbits dist fps.cabal tests<br />
$ git tag v0.8<br />
$ git archive --format=tar.gz v0.8 > fps-0.8.tar.gz<br />
<br />
You can now just post your fps-0.8.tar.gz<br />
<br />
<br />
* Tag each release using '''git tag'''. For example:<br />
<br />
== Hosting ==<br />
<br />
Hosting for repos is available from [http://github.com Github] and the [http://community.haskell.org/ Haskell community server]<br />
<br />
There is also a (minimal) Github equivalent for Darcs at [http://hub.darcs.net/ hub.darcs.net].<br />
<br />
== Web page ==<br />
<br />
Create a web page documenting your project! An easy way to do this is to<br />
add a project specific page to [[HaskellWiki:Contributing|the Haskell wiki]]<br />
<br />
== The user experience ==<br />
<br />
When developing a new Haskell library, it is important to remember how the user expects to be able to build and use a library.<br />
<br />
=== Introductory information and build guide ===<br />
<br />
A typical library user expects to:<br />
<br />
# Visit [[Haskell|Haskell.org]]<br />
# Find the library/program they are looking for:<br />
## if not found, try mailing list; <br />
## if it is hidden, try improving the documentation on haskell.org;<br />
## if it does not exist, try contributing code and documentation) <br />
# Download<br />
# Build and install<br />
# Enjoy<br />
<br />
Each of these steps can pose potential road blocks, and code authors can<br />
do a lot to help code users avoid such blocks. Steps 1..2 may be easy enough, and many coders and users are mainly concerned with step 5. Steps 3..4 are the ones that often get in the way. In particular, the<br />
following questions should have clear answers:<br />
<br />
* Which is the latest version? <br />
* What state is it in? <br />
* What are its aims? <br />
* Where is the documentation?<br />
* Which is the right version for given OS and Haskell implementation?<br />
* How is it packaged, and what tools are needed to get and unpack it?<br />
* How is it installed, and what tools are needed to install it?<br />
* How do we handle dependencies?<br />
* How do we provide/acquire the knowledge and tool-chains needed?<br />
<br />
The best place to answer these questions is a README file,<br />
distributed with the library or application, and often accompanied with<br />
similar text on a more extensive web page.<br />
<br />
=== Tutorials ===<br />
<br />
Generated haddock documentation is usually not enough to help new<br />
programmers learn how to use a library. You must also provide accompanying examples, and even tutorials about the library.<br />
<br />
Please consider providing example code for your library or application. The code should be type-correct and well-commented.<br />
<br />
== Program structure ==<br />
<br />
Monad transformers are very useful for programming in the large,<br />
encapsulating state, and controlling side effects. To learn more about this approach, try [http://www.grabmueller.de/martin/www/pub/Transformers.en.html Monad Transformers Step by Step].<br />
<br />
== Publicity ==<br />
<br />
The best code in the world is meaningless if nobody knows about it. The<br />
process to follow once you've tagged and released your code is:<br />
<br />
=== Join the community ===<br />
<br />
If you haven't already, join the community. The best way to do this is to [http://haskell.org/haskellwiki/Mailing_lists subscribe] to at least haskell-cafe@ and haskell@ mailing lists. Joining the [[IRC_channel|#haskell IRC channel]] is also an excellent idea.<br />
<br />
=== Announce your project on haskell@ ===<br />
<br />
Most important: announce your project releases to the haskell@haskell.org mailing list. Tag your email subject line with "ANNOUNCE: ...". This ensure it will then make it into the [http://haskell.org/haskellwiki/HWN Haskell Weekly News]. To be doubly sure, you can email the release text to the [[HWN|HWN editor]].<br />
<br />
=== Add your code to the public collections ===<br />
<br />
* Add your library or application to the [[Libraries and tools]] page, under the relevant category, so people can find it.<br />
<br />
* If your release is a Cabal package, add it to the [http://hackage.haskell.org/packages/hackage.html Hackage database]<br />
<br />
* If your library stays up to date with its dependencies, add it to the vetted packages on [https://github.com/fpco/stackage Stackage].<br />
<br />
=== Blog about it ===<br />
<br />
Blog about it! Blog about your new code on [http://planet.haskell.org Planet Haskell].<br />
Write about your project in your blog, then email the [http://planet.haskell.org/ Planet Haskell] maintainer (ibid on [[IRC channel|#haskell]]) the RSS feed url for your blog<br />
<br />
[[Category:Community]]<br />
[[Category:Tutorials]]</div>Henk-Jan van Tuyl