https://wiki.haskell.org/api.php?action=feedcontributions&user=HowardBGolden&feedformat=atomHaskellWiki - User contributions [en]2019-10-15T09:48:36ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=99_questions/Solutions/90&diff=6304899 questions/Solutions/902019-09-30T17:56:12Z<p>HowardBGolden: Fix typo: Thanks Inga.Feick for reporting.</p>
<hr />
<div>This is a classical problem in computer science. The objective is to place eight queens on a chessboard so that no two queens are attacking each other; i.e., no two queens are in the same row, the same column, or on the same diagonal.<br />
<br />
The simplest solution is a composition of separate functions to generate the list of candidates and to test each candidate:<br />
<br />
<haskell><br />
queens :: Int -> [[Int]]<br />
queens n = filter test (generate n)<br />
where generate 0 = [[]]<br />
generate k = [q : qs | q <- [1..n], qs <- generate (k-1)]<br />
test [] = True<br />
test (q:qs) = isSafe q qs && test qs<br />
isSafe try qs = not (try `elem` qs || sameDiag try qs)<br />
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs<br />
</haskell><br />
<br />
By definition/data representation no two queens can occupy the same column.<br />
<hask>try `elem` qs</hask> checks for a queen in the same row, <hask>abs (try - q) == colDist</hask> checks for a queen in the same diagonal.<br />
<br />
This is easy to understand, but it's also quite slow, as it generates and tests N^N possible N-queen configurations.<br />
The key to speeding it up is to fuse the composition <hask>filter test . generate</hask> into a semantically equivalent function <hask>queens'</hask> that does the tests as early as possible.<br />
If a list already contains two queens in a line, there's no point in considering all the possible ways of adding more queens.<br />
Now that the recursive call incorporates testing, we avoid recomputing it by interchanging the two generators, and reverse each answer at the end to obtain the original order.<br />
This yields the following version, which is much faster:<br />
<br />
<haskell><br />
queens :: Int -> [[Int]]<br />
queens n = map reverse $ queens' n<br />
where queens' 0 = [[]]<br />
queens' k = [q:qs | qs <- queens' (k-1), q <- [1..n], isSafe q qs]<br />
isSafe try qs = not (try `elem` qs || sameDiag try qs)<br />
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs<br />
</haskell><br />
<br />
<br />
A solution using the <hask>Data.List</hask>'s <hask>permutations</hask> is:<br />
<br />
<haskell><br />
import Prelude.Unicode<br />
import Data.List<br />
<br />
queues ∷ Int → [[Int]]<br />
queues n = filter (\x → test (zip [1..n] x)) candidates<br />
where candidates = permutations [1..n]<br />
unSafe (x₁, y₁) (x₂, y₂) = (y₁ ≡ y₂) ∨<br />
((abs (x₁ - x₂)) ≡ (abs (y₁ - y₂)))<br />
test [] = True<br />
test (q:qs) = (not $ (any (\x → unSafe q x) qs)) ∧ (test qs)<br />
</haskell><br />
<br />
If you approach this problem with an imperative mindset, you might be tempted to use an accumulating parameter for the list of candidates.<br />
This would make the function harder to understand, and would not help much (if at all): the important thing here is the breadth of the search tree, not its depth.<br />
<br />
[[Category:Programming exercise spoilers]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Template:Main/Community&diff=62956Template:Main/Community2019-07-05T02:48:57Z<p>HowardBGolden: Remove link to G+ (defunct)</p>
<hr />
<div><div class="subtitle">Join the Community</div><br />
<br />
* Haskell on [https://www.reddit.com/r/haskell/ reddit], [https://stackoverflow.com/questions/tagged?tagnames=haskell Stack Overflow]<br />
* [[Mailing lists]], [[IRC channel|IRC channels]]<br />
* [[:Category:Haskell|Wiki]] ([[HaskellWiki:Contributing|how to contribute]])<br />
* [[Haskell Communities and Activities Report|Communities and Activities Reports]]<br />
* Haskell in [[Haskell in industry|industry]], [[Haskell in research|research]] and [[Haskell in education|education]].<br />
* [https://planet.haskell.org/ Planet Haskell] [https://planet.haskell.org/rss20.xml https://wiki.haskell.org/wikiupload/7/7c/Rss16.png], [https://themonadreader.wordpress.com/ The Monad.Reader]<br />
* Local [[user groups]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Thunk&diff=62928Thunk2019-06-10T20:21:30Z<p>HowardBGolden: Add link to WP article on lambda calculus reduction</p>
<hr />
<div>[[Category:Glossary]]<br />
A '''thunk''' is a value that is yet to be evaluated.<br />
It is used in Haskell systems, that implement [[non-strict semantics]] by [[lazy evaluation]].<br />
A lazy run-time system does not evaluate a thunk unless it has to.<br />
Expressions are translated into a graph (''not'' a tree, as you might have expected, this enables sharing, and infinite lists!) and a Spineless Tagless G-machine (STG, G-machine is short for graph reduction machine) [https://en.wikipedia.org/wiki/Lambda_calculus#Reduction ''reduces''] it, chucking out any unneeded thunk, unevaluated.<br />
<br />
== Why are thunks useful? ==<br />
Well, if you don't need it, why evaluate it? Take for example the "lazy" <hask>&&</hask> (and) operation. Two boolean expressions joined by <hask>&&</hask> together is true if and only if both of them are. If you find out that one of them is false, you immediately know the joined expression cannot be true.<br />
<haskell><br />
-- the first is false, so is the answer, don't even need to know what the other is<br />
False && _ = False<br />
-- so the first turns out to be true, hmm...<br />
-- if the second is true, then the result is true<br />
-- if it's false, so is the result<br />
-- in other words, the result is the second!<br />
True && x = x<br />
</haskell> <br />
This function only evaluates the first parameter, because that's all that is needed. Even if the first parameter ''is'' true, you don't need to evaluate the second, so don't (so this version effectively is smarter than the explicit truth table). Who knows, the second parameter may get thrown out later as well!<br />
<br />
Perhaps a more convincing example is a (naive but intuitive) algorithm to find out if a given number is prime.<br />
<haskell><br />
-- the non-trivial factors are those who divide the number so no remainder<br />
factors n = filter (\m -> n `mod` m == 0) [2 .. (n - 1)]<br />
-- a number is a prime if it has no non-trivial factors<br />
isPrime n = n > 1 && null (factors n)<br />
</haskell><br />
Fascinatingly, <hask>isPrime</hask> evaluates to <hask>False</hask> as soon as it finds a factor (due to the lazy definition of <hask>null</hask>), and discards the rest of the list.<br />
<br />
== When are thunks not so useful? ==<br />
If you keep building up a very complicated graph to reduce later, it consumes memory (naturally), and can hinder performance, like, (from a blog comment made by Cale Gibbard)<br />
<haskell><br />
foldl (+) 0 [1,2,3]<br />
==> foldl (+) (0 + 1) [2,3]<br />
==> foldl (+) ((0 + 1) + 2) [3]<br />
==> foldl (+) (((0 + 1) + 2) + 3) []<br />
==> ((0 + 1) + 2) + 3<br />
==> (1 + 2) + 3<br />
==> 3 + 3<br />
==> 6<br />
</haskell><br />
and by <hask>==></hask>, "is reduced to" is meant. Lucky, the example is not applied to <hask>[1 .. 2^40]</hask> because it would have taken a very long time to load this page then, and so would your program when run. For more involved (and subtle!) examples, see [[Performance/Strictness]].<br />
<br />
== See also ==<br />
[[Performance/Laziness]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Recursive_function_theory&diff=62925Recursive function theory2019-06-03T23:19:33Z<p>HowardBGolden: /* Bibliography */ Add link to online book on author's website</p>
<hr />
<div>== Introduction ==<br />
<br />
* [http://web.archive.org/web/20121211013803/http://planetmath.org/encyclopedia/RecursiveFunction.html PlanetMath article]<br />
* Dr Matt Fairtlough's [http://web.archive.org/web/20060713051810/http://www.dcs.shef.ac.uk/~matt/teaching/04/com2030/lectures/tomlect13.pdf Introduction to recursive function theory] among his [http://web.archive.org/web/20060713073121/http://www.dcs.shef.ac.uk/~matt/teaching/04/com2030/ lecture notes]<br />
<br />
== Designed languages ==<br />
* Dr Matt Fairtlough's [http://web.archive.org/web/20060713051910/http://www.dcs.shef.ac.uk/~matt/teaching/04/com2030/lectures/tomlect16.pdf Minimal Programming Language (MIN)] is not exactly a recursive function theory language, but it is based on natural numbers, too and its equivalent power with partal recursive functions is shown in its description.<br />
<br />
== Implementations ==<br />
[http://web.archive.org/web/20060713051445/http://www.dcs.shef.ac.uk/~matt/teaching/04/com2030/lectures/Recursion.hs In Haskell], among other implementations (e.g. written in Java) in Dr Matt Fairtlough's [http://web.archive.org/web/20060713073121/http://www.dcs.shef.ac.uk/~matt/teaching/04/com2030/ lecture notes] (see the bottom of the page).<br />
<br />
== Motivations ==<br />
<br />
Well-known concepts are taken from [Mon:MathLog], but several new notations (only notations, not concepts) are introduced to reflect all concepts described in [Mon:MathLog], and some simplifications are made (by allowing zero-arity generalizations). These are plans to achieve formalizations that can allow us in the future to incarnate the main concepts of recursive function theory in a ''toy'' programming language, to play with it so that some interesting concepts can be taught in a funny way.<br />
<br />
The relatedness of this page to Haskell (and to functional programming) is very few. It seems to me that (programming in) recursive functional theory may be rather another world (e.g. currying is missing, too) -- although the lack of variables (even lack of formal parameters) can yield a feeling resembling to [[pointfree]] style programming, or even to [[combinatory logic]].<br />
<br />
But despite of its weak (direct) relatedness to functional programming, maybe this page can be useful for someone in the future<br />
* e.g. when writing on quines (self-printing programs or self-representing formulas) etc. David Madore's [http://www.madore.org/~david/computers/quine.html Quines (self-replicating programs)] page uses recursive function theory for explaining the theoretical roots of quines (e.g. [http://www.madore.org/~david/computers/quine.html#sec_fp fixed point theorem])<br />
* or when writing on other general concepts of [[computer science]].<br />
<br />
Other few relatedness of this topic to Haskell may appear by the fact that the Haskell implementation of the mentioned toy programming language may use<br />
* tricks with types, [[type arithmetic]]<br />
* or metaprogramming concepts, at worst preprocessing steps<br />
because type-safe implementations of <math>\underline\mathbf\dot K^m_n</math> and <math>\underline\mathbf K^m_n</math> does not look straightforward for me.<br />
<br />
== Notations ==<br />
<br />
;<math>\mathbb N</math><br />
:the set of natural numbers, incuding 0<br />
;''Type system''<br />
:I do not use this term in a precise way here: see the following items for explanation. Headlines ''Type system'' may suggest that the type system of the planned recursive function theory programming language implementation can prevent the user from applying a partial function to an out-of-domain value -- but I think that type safety in this sense cannot be achieved.<br />
;<math>f:A\to B</math><br />
:<math>f</math> is a total function from <math>A</math> to <math>B</math>. In an implemented recursion function theory language, it means a function that surely terminates.<br />
;<math>f:A\supset\!\to B</math><br />
:<math>f</math> is a partial function from <math>A</math> to <math>B</math> (it may be either a total function or a proper partial function). In an implemented recursion theory language, maybe this information (being partial) cannot be grasped by the type system. It may mean that proper partial functions simply fail to terminate, without reflecting this possibility in the type system in any way.<br />
;<math>A\times B</math><br />
:Descartes-product of sets is used here for stressing the fact that recursive function theory does not know the concept of ''currying'' (much more other concepts will be needed to achieve something similar to currying, see [http://en.wikipedia.org/wiki/S-m-n_theorem Kleene's <math>s^m_n</math> theorem]). So using <math>f:A\times B\to C</math> (instead of <math>f:A\to B\to C</math>) is intended to stress the lack of currying (at this level).<br />
<br />
== Primitive recursive functions ==<br />
<br />
=== Type system ===<br />
<br />
:<math>\left\lfloor0\right\rfloor = \mathbb N</math><br />
:<math>\begin{matrix}\left\lfloor n + 1\right\rfloor = \underbrace{\mathbb N\times\dots\times\mathbb N}\to\mathbb N\\\;\;\;\;\;\;\;\;n+1\end{matrix}</math><br />
<br />
=== Initial functions ===<br />
<br />
==== Constant ====<br />
<br />
:<math>\mathbf 0 : \left\lfloor0\right\rfloor</math><br />
:<math>\mathbf 0 = 0</math><br />
<br />
This allows us to deal with a concept of zero in recursive function theory.<br />
In the literature (in [Mon:MathLog], too) this aim is achieved in another way: a<br />
:<math>\mathbf{zero} : \left\lfloor1\right\rfloor</math><br />
:<math>\mathbf{zero}\;x = 0</math><br />
is defined instead. Is this approach superfluously overcomplicated? Can we avoid it and use the more simple and indirect looking<br />
:<math>\mathbf 0 : \left\lfloor0\right\rfloor</math><br />
:<math>\mathbf 0 = 0</math><br />
approach?<br />
<br />
Are these approaches equivalent? Is the latter (more simple looking) one as powerful as the former one? Could we define a <math>\mathbf{zero}</math> using the<br />
:<math>\mathbf 0 : \left\lfloor0\right\rfloor</math><br />
:<math>\mathbf 0 = 0</math><br />
approach?<br />
Let us try:<br />
:<math>\mathbf{zero} = \underline\mathbf K^0_1 \mathbf0</math> <br />
(see the definition of <math>\underline\mathbf K^m_n</math> somewhat below).<br />
This looks like working, but raises new questions: what about generalizing operations (here: composition) to deal with zero-arity cases in an appropriate way?<br />
E.g.<br />
:<math>\underline\mathbf\dot K^0_n c\left\langle\right\rangle</math><br />
:<math>\underline\mathbf K^0_n c</math><br />
where <math>c : \left\lfloor0\right\rfloor, n \in \mathbb N</math><br />
can be regarded as <math>n</math>-ary functions throwing all their <math>n</math> arguments away and returning <math>c</math>.<br />
<br />
Does it take a generalization to allow such cases, or can they be inferred?<br />
A practical approach to solve such questions: let us write a Haskell program which implements (at least partially) recursive function theory. Then we can see clearly which things have to be defined and things which are consequences. I think the <math>\underline\mathbf K^0_n c</math> construct is a rather straighforward thing.<br />
<br />
Why all this can be important: it may be exactly <math>\underline\mathbf K^0_n c</math> that saves us from defining the concept of zero in recursive function theory as<br />
:<math>\mathbf{zero} : \left\lfloor1\right\rfloor</math><br />
:<math>\mathbf{zero}\;x = 0</math><br />
-- it may be superfluous: if we need functions that throw away (some or all) of their arguments and return a constant, then we can combine them from <math>\underline\mathbf K^m_n</math>, <math>\mathbf s</math> and <math>\mathbf 0</math>, if we allow concepts like <math>\underline\mathbf K^0_m</math>.<br />
<br />
==== Successor function ====<br />
<br />
:<math>\mathbf s : \left\lfloor1\right\rfloor</math><br />
:<math>\mathbf s = \lambda x . x + 1</math><br />
<br />
==== Projection functions ====<br />
<br />
For all <math>0\leq i<m</math>:<br />
:<math>\mathbf U^m_i : \left\lfloor m\right\rfloor</math><br />
:<math>\mathbf U^m_i x_0\dots x_i \dots x_{m-1} = x_i</math><br />
<br />
=== Operations ===<br />
<br />
==== Composition ====<br />
<br />
:<math>\underline\mathbf\dot K^m_n : \left\lfloor m\right\rfloor \times \left\lfloor n\right\rfloor^m \to \left\lfloor n\right\rfloor</math><br />
:<math>\underline\mathbf\dot K^m_n f \left\langle g_0,\dots, g_{m-1}\right\rangle x_0 \dots x_{n-1} = f \left(g_0 x_0 \dots x_{n-1}\right) \dots \left(g_{m-1} x_0 \dots x_{n-1}\right)</math><br />
This resembles to the <math>\mathbf\Phi^n_m</math> combinator of [[Combinatory logic]] (as described in <nowiki>[HasFeyCr:CombLog1, 171]</nowiki>).<br />
If we prefer avoiding the notion of the nested tuple, and use a more homogenous style (somewhat resembling to currying):<br />
:<math>\begin{matrix}\underline\mathbf K^m_n : \left\lfloor m\right\rfloor \times \underbrace{\left\lfloor n\right\rfloor\times\dots\times\left\lfloor n\right\rfloor} \to \left\lfloor n\right\rfloor\\\;\;\;\;\;\;\;\;\;\;m\end{matrix}</math><br />
Let underbrace not mislead us -- it does not mean any bracing.<br />
:<math>\underline\mathbf K^m_n f g_0\dots g_{m-1} x_0 \dots x_{n-1} = f \left(g_0 x_0 \dots x_{n-1}\right) \dots \left(g_{m-1} x_0 \dots x_{n-1}\right)</math><br />
remembering us to<br />
:<math>\underline\mathbf K^m_n f g_0\dots g_{m-1} x_0 \dots x_{n-1} = \mathbf \Phi^n_m f g_0 \dots g_{m-1} x_0 \dots x_{n-1}</math><br />
<br />
==== Primitive recursion ====<br />
<br />
:<math>\underline\mathbf R^m : \left\lfloor m\right\rfloor \times \left\lfloor m+2\right\rfloor \to \left\lfloor m+1\right\rfloor</math><br />
:<math>\underline\mathbf R^m f h = g\;\mathrm{where}</math><br />
::<math>g x_0 \dots x_{m-1} 0 = f x_0 \dots x_{m-1}</math><br />
::<math>g x_0 \dots x_{m-1} \left(\mathbf s y\right) = h x_0 \dots x_{m-1} y \left(g x_0\dots x_{m-1} y\right)</math><br />
The last equation resembles to the <math>\mathbf S_n</math> combinator of [[Combinatory logic]] (as described in <nowiki>[HasFeyCr:CombLog1, 169]</nowiki>):<br />
:<math>g x_0 \dots x_{m-1} \left(\mathbf s y\right) = \mathbf S_{m+1} h g x_0 \dots x_{m-1} y</math><br />
<br />
== General recursive functions ==<br />
<br />
Everything seen above, and the new concepts:<br />
<br />
=== Type system ===<br />
<br />
:<math> \widehat{\,m\,} = \left\{ f : \left\lfloor m+1\right\rfloor\;\vert\;f \mathrm{\ is\ special}\right\}</math><br />
<br />
See the definition of being ''special'' <nowiki>[Mon:MathLog, 45]</nowiki>. This property ensures, that minimalization does not lead us out of the world of total functions. Its definition is the rather straightforward formalization of this expectation.<br />
:<math>\mathbf{special}^m f \equiv \forall x_0, \dots, x_{m-1} \in \mathbb N\;\;\exists y \in \mathbb N\;\;f x_0 \dots x_{m-1} y = 0</math><br />
It resembles to the concept of inverse -- more exactly, to the existence part.<br />
<br />
<br />
=== Operations ===<br />
<br />
==== Minimalization ====<br />
<br />
:<math>\underline\mu^m : \widehat m \to \left\lfloor m\right\rfloor</math><br />
:<math>\underline\mu^m f x_0 \dots x_{m-1} = \min \left\{y\in\mathbb N\;\vert\;f x_0 \dots x_{m-1} y = 0\right\}</math><br />
Minimalization does not lead us out of the word of total functions, if we use it only for ''special'' functions -- the property of being ''special'' is defined exactly for this purpose [Mon:MatLog, 45].<br />
As we can see, minimalization is a concept resembling somehow to the concept of ''inverse''.<br />
<br />
Existence of the required minimum value of the set -- a sufficient and satisfactory condition for this is that the set is never empty. And this is equivalent to the statement<br />
:<math>\forall x_0, \dots, x_{m-1} \in \mathbb N\;\;\exists y \in \mathbb N\;\;f x_0 \dots x_{m-1} y = 0</math><br />
<br />
== Partial recursive functions ==<br />
<br />
Everything seen above, but new constructs are provided, too.<br />
<br />
=== Type system ===<br />
<br />
:<math>\begin{matrix}\left\lceil n + 1\right\rceil = \underbrace{\mathbb N\times\dots\times\mathbb N}\supset\!\to\mathbb N\\\;\;\;\;\;\;n+1\end{matrix}</math><br />
<br />
Question: is there any sense to define<br />
<math>\left\lceil0\right\rceil</math> in another way than simply <math>\left\lceil0\right\rceil = \left\lfloor0\right\rfloor = \mathbb N</math>? Partial constant?<br />
Is<br />
:<math>\left\lceil0\right\rceil = \mathbb N</math> <br />
<br />
or<br />
:<math>\left\lceil0\right\rceil = \mathbb N\;\cup\;\left\{\bot\right\}</math>? <br />
=== Operations ===<br />
<br />
:<math>\overline\mathbf\dot K^m_n : \left\lceil m\right\rceil \times \left\lceil n\right\rceil^m \to \left\lceil n\right\rceil</math><br />
:<math>\begin{matrix}\overline\mathbf K^m_n : \left\lceil m\right\rceil \times \underbrace{\left\lceil n\right\rceil\times\dots\times\left\lceil n\right\rceil} \to \left\lceil n\right\rceil\\\;\;\;\;\;\;\;\;\;\;m\end{matrix}</math><br />
<br />
:<math>\overline\mathbf R^m : \left\lceil m\right\rceil \times \left\lceil m+2\right\rceil \to \left\lceil m+1\right\rceil</math> <br />
:<math>\overline\mu^m : \left\lceil m+1\right\rceil \to \left\lceil m\right\rceil</math><br />
<br />
Their definitions are straightforward extension of the corresponding total function based definitions.<br />
<br />
Remark: these operations take partial functions as arguments, but they are total operations themselves in the sense that they always yield a result -- at worst an empty function (as an ultimate partial function).<br />
<br />
== Bibliography ==<br />
<br />
;<nowiki>[HasFeyCr:CombLog1]</nowiki><br />
:Curry, Haskell B; Feys, Robert; Craig, William: Combinatory Logic. Volume I. North-Holland Publishing Company, Amsterdam, 1958.<br />
;<nowiki>[Mon:MathLog]</nowiki><br />
:Monk, J. Donald: [http://euclid.colorado.edu/~monkd/monk29.pdf Mathematical Logic]. Springer-Verlag, New York * Heidelberg * Berlin, 1976.<br />
<br />
[[Category:Theoretical foundations]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Category_theory&diff=62851Category theory2019-04-03T04:57:57Z<p>HowardBGolden: /* Haskell libraries and tools */ Update description of category-extras, which has been superseded, with link to Hackage</p>
<hr />
<div>{{Foundations infobox}}<br />
'''Category theory''' can be helpful in understanding Haskell's type system. There exists a [[Hask|"Haskell category"]], of which the objects are Haskell types, and the morphisms from types <hask>a</hask> to <hask>b</hask> are Haskell functions of type <hask>a -> b</hask>.<br />
<br />
__TOC__<br />
<br />
The Haskell wikibooks has [http://en.wikibooks.org/wiki/Haskell/Category_theory an introduction to Category theory], written specifically with Haskell programmers in mind.<br />
<br />
==Definition of a category==<br />
<br />
<br />
A category <math>\mathcal{C}</math>consists of two collections:<br />
<br />
Ob<math>(\mathcal{C})</math>, the objects of <math>\mathcal{C}</math><br />
<br />
Ar<math>(\mathcal{C})</math>, the arrows of <math>\mathcal{C}</math><br />
(which are not the same as [[Arrow]]s defined in [[GHC]])<br />
<br />
Each arrow <math>f</math> in Ar<math>(\mathcal{C})</math> has a<br />
domain, dom <math>f</math>, and a codomain, cod <math>f</math>, each<br />
chosen from Ob<math>(\mathcal{C})</math>. The notation <math>f\colon<br />
A \to B</math> means <math>f</math> is an arrow with domain<br />
<math>A</math> and codomain <math>B</math>. Further, there is a<br />
function <math>\circ</math> called composition, such that <math>g<br />
\circ f</math> is defined only when the codomain of <math>f</math> is<br />
the domain of <math>g</math>, and in this case, <math>g \circ f</math><br />
has the domain of <math>f</math> and the codomain of <math>g</math>. <br />
<br />
In symbols, if <math>f\colon A \to B</math> and <math>g\colon B \to<br />
C</math>, then <math>g \circ f \colon A \to C</math>. <br />
<br />
Also, for each object <math>A</math>, there is an arrow<br />
<math>\mathrm{id}_A\colon A \to A</math>, (often simply denoted as<br />
<math>1</math> or <math>\mathrm{id}</math>, when there is no chance of<br />
confusion). <br />
<br />
===Axioms===<br />
The following axioms must hold for <math>\mathcal{C}</math> to be a category:<br />
<br />
#If <math>f\colon A \to B</math> then <math>f \circ \mathrm{id}_A = \mathrm{id}_B\circ f = f</math> (left and right identity) <br />
#If <math>f\colon A \to B</math> and <math>g \colon B \to C</math> and <math>h \colon C \to D</math>, then <math>h \circ (g \circ f) = (h<br />
\circ g) \circ f</math> (associativity) <br />
<br />
===Examples of categories===<br />
* Set, the category of sets and set functions.<br />
* Mon, the category of monoids and monoid morphisms.<br />
* Monoids are themselves one-object categories.<br />
* Grp, the category of groups and group morphisms.<br />
* Rng, the category of rings and ring morphisms.<br />
* Grph, the category of graphs and graph morphisms.<br />
* Top, the category of topological spaces and continuous maps.<br />
* Preord, the category of preorders and order preserving maps.<br />
* CPO, the category of complete partial orders and continuous functions.<br />
* Cat, the category of categories and functors.<br />
<br />
* [[Hask]]<br />
* the category of data types and functions on data structures <br />
* the category of functions and data flows (~ data flow diagram)<br />
* the category of stateful objects and dependencies (~ object diagram)<br />
* the category of values and value constructors<br />
* the category of states and messages (~ state diagram)<br />
<br />
===Further definitions===<br />
With examples in Haskell at:<br />
* [[Category theory/Functor]]<br />
* [[Category theory/Natural transformation]]<br />
* [[Category theory/Monads]]<br />
<br />
== Categorical programming ==<br />
<br />
Catamorphisms and related concepts, categorical approach to functional programming, categorical programming. Many materials cited here refer to category theory, so as an introduction to this discipline see the [[#See also]] section.<br />
* Erik Meijer, Maarten Fokkinga, Ross Paterson: [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125 Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire]. See also related documents (in the CiteSeer page). Understanding the article does not require knowledge of category theory—the paper is self-contained with regard to understanding catamorphisms, anamorphisms and other related concepts.<br />
* Roland Backhouse, Patrik Jansson, Johan Jeuring and Lambert Mertens. [http://www.cse.chalmers.se/~patrikj/poly/afp98/ Generic Programming - an Introduction]: Detailed introduction to categorial sums, product, polynomial functors and folds for the purpose of generic programming. Supplements the bananas paper.<br />
* Varmo Vene and Tarmo Uustalu: [http://citeseer.ist.psu.edu/vene98functional.html Functional Programming with Apomorphisms / Corecursion]<br />
* Varmo Vene: [http://www.cs.ut.ee/~varmo/papers/thesis.pdf Categorical Programming with Inductive and Coinductive Types]. The book gives Haskell examples to illustrate the deep categorical theory topic.<br />
* Tatsuya Hagino: [http://www.tom.sfc.keio.ac.jp/~hagino/thesis.pdf A Categorical Programming Language]<br />
* [http://pll.cpsc.ucalgary.ca/charity1/www/home.html Charity], a categorical programming language implementation.<br />
* [http://okmij.org/ftp/Haskell/categorical-maxn.lhs Deeply uncurried products, as categorists might like them] article mentions a conjecture: relatedness to [[Combinatory logic]]<br />
<br />
==Haskell libraries and tools==<br />
<br />
* Originally, there was a package, [http://www.eyrie.org/~zednenem/2004/hsce/ Category extras], by [http://www.eyrie.org/~zednenem/about/dave.html David Menendez]: libraries for e.g. comonads, infinite data types. This package has been superseded by other more-focused and self-contained packages, as documented in the [http://hackage.haskell.org/package/category-extras category-extras] metapackage in Hackage.<br />
<br />
==Books==<br />
<br />
*Michael Barr and Charles Wells: [http://www.cwru.edu/artsci/math/wells/pub/ttt.html Toposes, Triples and Theories]. The online, freely available book is both an introductory and a detailed description of category theory. It also contains a category-theoretical description of the concept of ''monad'' (but calling it a ''triple'' instead of ''monad'').<br />
<br />
*R. F. C. Walters: [http://www.cambridge.org/us/catalogue/catalogue.asp?isbn=0521419972 Categories and Computer Science]. Category Theory has, in recent years, become increasingly important and popular in computer science, and many universities now introduce Category Theory as part of the curriculum for undergraduate computer science students. Here, the theory is developed in a straightforward way, and is enriched with many examples from computer science.<br />
<br />
* Arbib&Manes: Arrow, Structures and Functors - The Categorical Imperative. (c)1975 Academic Press, ISBN 0-12-059060-3. Sadly now out of print but very little prerequisite knowledge is needed. It covers monads and the Yoneda lemma.<br />
<br />
==See also==<br />
<br />
* Michael Barr and Charles Wells have a [http://www.math.upatras.gr/~cdrossos/Docs/B-W-LectureNotes.pdf paper] that presents category theory from a computer-science perspective, assuming no prior knowledge of categories.<br />
*[http://wwwhome.cs.utwente.nl/~fokkinga/mmf92b.html A Gentle Introduction to Category Theory - the calculational approach] written by [http://wwwhome.cs.utwente.nl/~fokkinga/index.html Maarten M Fokkinga].<br />
* Wikipedia has a good [http://en.wikipedia.org/wiki/List_of_category_theory_topics collection of category-theory articles], although, as is typical of Wikipedia articles, they are rather dense.<br />
<br />
[[Category:Theoretical foundations]]<br />
[[Category:Mathematics]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Performance/Strictness&diff=62837Performance/Strictness2019-03-23T16:59:16Z<p>HowardBGolden: Change <pre-haskell> and <code-haskell> markup to <haskell> and <hask>, respectively. Thanks to Rory Green for pointing this out.</p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Strictness]]<br />
Haskell is a non-strict language, and most implementations use a strategy called ''laziness'' to run your program. Basically laziness == non-strictness + sharing.<br />
<br />
[[Performance/Laziness|Laziness]] can be a useful tool for improving performance, but more often than not it reduces performance by adding a constant overhead to everything. Because of laziness, the compiler can't evaluate a function argument and pass the value to the function, it has to record the expression in the heap in a ''suspension'' (or ''[[thunk]]'') in case it is evaluated later. Storing and evaluating suspensions is costly, and unnecessary if the expression was going to be evaluated anyway. <br />
<br />
== Strictness analysis ==<br />
<br />
Optimising compilers like GHC try to reduce the cost of laziness using ''strictness analysis'', which attempts to determine which function arguments are always evaluated by the function, and hence can be evaluated by the caller instead. Sometimes this leads to bigger gains; a strict <hask>Int</hask> can be passed as an unboxed value, for example. Strictness analysis sometimes does wonderful things; for example it is very good at optimising <hask>fac</hask>:<br />
<haskell><br />
fac :: Int -> Int<br />
fac n = if n <= 1 then 1 else n * fac (n-1)<br />
</haskell><br />
<br />
Strictness analysis can spot the fact that the argument <hask>n</hask> is strict, and can be represented unboxed. The resulting function won't use any heap while it is running, as you'd expect.<br />
<br />
The common case of misunderstanding of strictness analysis is when [[Fold|folding]] (reducing) lists. If this program<br />
<haskell><br />
main = print (foldl (+) 0 [1..1000000])<br />
</haskell><br />
is compiled in GHC without "-O" flag, it uses a lot of heap and stack. A programmer knows that the long list (<hask>[1..1000000]</hask>) is stored as a thunk, not fully, because the programmer read about [[non-strict semantics]] and [[lazy vs. non-strict]]. The programmer explicitly wrote <hask>sum</hask> as [[Tail recursion|tail recursive]], so the program should use a small amount of stack, because the programmer knows about [[stack overflow]]. So behavior of the program looks mysterious to the programmer.<br />
<br />
The programmer concludes that the program somehow decides to store the long list fully in the heap, or garbage collector is not able to remove dead prefix of the long list. Wrong. The long list is fine.<br />
<br />
Look at the definition from the standard library.<br />
<haskell><br />
foldl :: (a -> b -> a) -> a -> [b] -> a<br />
foldl f z0 xs0 = lgo z0 xs0<br />
where<br />
lgo z [] = z<br />
lgo z (x:xs) = lgo (f z x) xs<br />
</haskell><br />
<br />
<hask>lgo</hask>, instead of adding elements of the long list, creates '''a thunk''' for <hask>(f z x)</hask>. <hask>z</hask> is stored within that thunk, and <hask>z</hask> is a thunk also, created during the previous call to <hask>lgo</hask>. The program creates the long chain of thunks. Stack is bloated when evaluating that chain.<br />
<br />
With "-O" flag GHC performs strictness analysis, then it knows that <hask>lgo</hask> is strict in <hask>z</hask> argument, therefore thunks are not needed and are not created.<br />
<br />
== Limitations of strictness analysis ==<br />
<br />
It's easy to accidentally write functions that aren't strict, though. Often a lazy function can be sitting around eating up your performance, when making it strict wouldn't change the meaning of the program. For example:<br />
<haskell><br />
suminit :: [Int] -> Int -> Int -> (Int,[Int])<br />
suminit xs len acc = case len == 0 of<br />
True -> (acc,xs)<br />
False -> case xs of<br />
[] -> (acc,[])<br />
x:xs -> suminit xs (len-1) (acc+x)<br />
main = print (fst (suminit [1..] 1000000 0))<br />
</haskell><br />
this function sums the first len elements of a list, returning the sum and the remaining list. We've already tried to improve performance by using an [[Performance/Accumulating parameter|accumulating parameter]]. However, the parameter <hask>acc</hask> isn't strict, because there's no guarantee that the caller will evaluate it. The compiler will use a fully boxed <hask>Int</hask> to represent <hask>acc</hask>, although it will probably use an unboxed <hask>Int</hask> to represent <hask>len</hask>. The expression <hask>(acc+x)</hask> will be saved as a suspension, rather than evaluated on the spot. (Incidentally, this is a common pattern we see crop up time and again in small recursive functions with a few parameters).<br />
<br />
== Explicit strictness ==<br />
<br />
We can make an argument strict explicitly.<br />
<br />
In the <hask>foldl</hask> example, replace <hask>foldl</hask> with <hask>foldl'</hask>.<br />
<br />
For <hask>suminit</hask>, we need to make <hask>acc</hask> strict. The way to do this is using <hask>seq</hask>:<br />
<haskell><br />
suminit :: [Int] -> Int -> Int -> (Int,[Int])<br />
suminit xs len acc = acc `seq` case len == 0 of<br />
True -> (acc,xs)<br />
False -> case xs of<br />
[] -> (acc,[])<br />
x:xs -> suminit xs (len-1) (acc+x)<br />
</haskell><br />
<br />
Some other languages (eg. Clean) have strictness annotations on types, which is a less ugly way to express this, but for now there are no Haskell compilers that support this.<br />
<br />
With the <tt>BangPatterns</tt> GHC extension enabled, the above can be written as<br />
<br />
{{Note|For strict data structures, see [[Performance/Data_types]].}}<br />
<br />
<haskell><br />
suminit xs !len !acc = …<br />
</haskell><br />
<br />
Incidentally, GHC will also eliminate the tuple returned by this function if the caller immediately deconstructs it.<br />
<br />
== Evaluating expressions strictly ==<br />
<br />
There's a useful variant of the infix application operator <hask>($)</hask> that evaluates its argument strictly: <hask>($!)</hask>. This can often be used to great effect in eliminating unnecessary suspensions that the compiler hasn't spotted. eg. in a function application<br />
<haskell><br />
f (g x)<br />
</haskell><br />
writing instead<br />
<haskell><br />
f $! (g x)<br />
</haskell><br />
will be more efficient if (a) you were going to evaluate <hask>(g x)</hask> anyway, and (b) <hask>f</hask> isn't visibly strict, or inlined. If <hask>f</hask> is strict or inlined, then the chances are that <hask>($!)</hask> is unnecessary cruft here.<br />
<br />
A good example is the monadic return. If you find yourself writing<br />
<haskell><br />
do …<br />
…<br />
return (fn x)<br />
</haskell><br />
<br />
then consider instead writing<br />
<haskell><br />
do …<br />
…<br />
return $! fn x<br />
</haskell><br />
it is very rare to actually need laziness in the argument of return here.<br />
<br />
Warning: Using any kind of strictness annotations as above can have unexpected impact on program semantics, in particular when certain optimizations are performed by the compiler. See [[correctness of short cut fusion]].<br />
<br />
== Rule of Thumb for Strictness Annotation ==<br />
<br />
A rule of thumb for when strictness annotation might be needed:<br />
<br />
When a function <hask>f</hask> with argument <hask>x</hask> satisfies both conditions:<br />
* <hask>f</hask> calls a function on a function of <hask>x</hask>: <hask>(h (g x))</hask><br />
* is not already strict in <hask>x</hask> (does not inspect <hask>x</hask>'s value), <br />
then it can be helpful to force evaluation:<br />
<br />
Example:<br />
<haskell><br />
-- Force Strict: Make g's argument smaller.<br />
f x = g $! (h x)<br />
<br />
-- Don't force: f isn't building on x, so just let g deal with it.<br />
f x = g x <br />
<br />
-- Don't force: f is already strict in x<br />
f x = case x of <br />
0 -> (h (g x))<br />
</haskell></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Books&diff=62811Books2019-03-05T17:44:39Z<p>HowardBGolden: /* Textbooks */ Added cover image of Julien Dehos's book</p>
<hr />
<div>Books covering many aspects of Haskell.<br />
<br />
==Language and library definition==<br />
<br />
<DL><br />
<br />
<DT>[[Image:Haskell_98_Language_and_Libraries.jpg|frameless|right|Cover]]<br />
Simon Peyton Jones: [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=0521826144 "Haskell 98 language and libraries: the Revised Report"], Cambridge University Press, 2003, Hardback, 272 pages, ISBN 0521826144, £45.00<br />
<DD><br />
<B>Book Description</B><BR> <br />
Haskell is the world's leading lazy functional programming language,<br />
widely used for teaching, research, and applications. The language<br />
continues to develop rapidly, but in 1998 the community decided to<br />
capture a stable snapshot of the language: Haskell 98. All Haskell<br />
compilers support Haskell 98, so practitioners and educators alike<br />
have a stable base for their work. This book constitutes the agreed<br />
definition of the Haskell 98, both the language itself and its<br />
supporting libraries. It has been considerably revised and refined<br />
since the original definition, and appears in print for the first<br />
time. It should be a standard reference work for anyone involved in<br />
research, teaching, or application of Haskell.<br />
<br />
The entire language definition is also available online:<br />
[[Language_and_library_specification|Language and library<br />
specification]].<br />
</DL><br />
<br />
==Textbooks==<br />
<br />
<DL><br />
<br />
<dt>Vitaly Bragilevsky : [[Image: Hid-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/haskell-in-depth Haskell in Depth], ISBN13 9781617295409, Paperback/eBook: 625 pages (estimated). Manning Publications (Fall 2019, estimated)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell in Depth is the perfect second book on Haskell. After a quick refresher on Haskell basics, this hands-on guide dives into examples and application scenarios designed to teach how Haskell works and how to apply it correctly. You’ll learn about managing projects with Cabal and Stack, tackle error-handling and testing, and package programs and libraries for production deployment.<br />
<br />
You’ll appreciate coverage of advanced Haskell features including programming polymorphically, working effectively with types, concurrent programming, data processing, web services, and more. Because it’s organized to make specific topics easy to find, you’ll return to this book again and again as your go-to Haskell reference.<br />
<br />
<dt>Will Kurt : [[Image: Gph-cover.jpg|frameless|right|70px|Cover]] [https://www.manning.com/books/get-programming-with-haskell Get Programming with Haskell], ISBN13 9781617293764, Paperback/eBook: 616 pages. Manning Publications (March 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Get Programming with Haskell leads you through short lessons, examples, and exercises designed to make Haskell your own. It has crystal-clear illustrations and guided practice. You will write and test dozens of interesting programs and dive into custom Haskell modules. You will gain a new perspective on programming plus the practical ability to use Haskell in the everyday world. (The 80 IQ points: not guaranteed!)<br />
<br />
<dt>[[Image:beginning_haskell.jpg|frameless|right|70px|Cover]] Alejandro Serrano Mena: [http://www.apress.com/9781430262503 <em>Beginning Haskell</em>], Paperback / eBook: 498 pages, Apress (January 2014), English, ISBN: 978-1-43026-250-3<br />
<dd><B>Book Description</B><BR><br />
Beginning Haskell provides a broad-based introduction to the Haskell language, its libraries and environment, and to the functional programming paradigm that is fast growing in importance in the software industry. The book takes a project-based approach to learning the language that is unified around the building of a web-based storefront. Excellent coverage is given to the Haskell ecosystem and supporting tools. These include the Cabal build tool for managing projects and modules, the HUnit and QuickCheck tools for software testing, the Scotty framework for developing web applications, Persistent and Esqueleto for database access, and also parallel and distributed programming libraries.<br />
<br />
<dt>[[Image:Lyah.png|frameless|right|70px|Cover]] Miran Lipovača: [http://www.nostarch.com/lyah.htm <em>Learn You a Haskell for Great Good!</em>], Paperback: 360 pages, No Starch Press (April 2011), English, ISBN: 978-1-59327-283-8<br />
<dd><B>Book Description</B><BR><br />
It's all in the name: Learn You a Haskell for Great Good! is a hilarious, illustrated guide to this complex functional language. Packed with the author's original artwork, pop culture references, and most importantly, useful example code, this book teaches functional fundamentals in a way you never thought possible.<br />
<br />
<dt>[[Image:Programming_in_Haskell.jpg|frameless|right|Cover]] Graham Hutton: [http://www.cs.nott.ac.uk/~gmh/book.html <em>Programming in Haskell</em>], Paperback: 200 pages, Cambridge University Press (January 31, 2007), English, ISBN 0521692695<br />
<dd><br />
<B>Book Description</B><BR> <br />
Haskell is one of the leading languages for teaching functional<br />
programming, enabling students to write simpler and cleaner code, and to<br />
learn how to structure and reason about programs. This introduction is<br />
ideal for beginners: it requires no previous programming experience and<br />
all concepts are explained from first principles via carefully chosen<br />
examples. Each chapter includes exercises that range from the<br />
straightforward to extended projects, plus suggestions for further<br />
reading on more advanced topics. The author is a leading Haskell<br />
researcher and instructor, well-known for his teaching skills. The<br />
presentation is clear and simple, and benefits from having been refined<br />
and class-tested over several years. The result is a text that can be<br />
used with courses, or for self-learning. Features include: freely<br />
accessible Powerpoint slides for each chapter; solutions to exercises,<br />
and examination questions (with solutions) available to instructors;<br />
downloadable code that's fully compliant with the latest Haskell<br />
release.<br />
<br />
<dt>[[Image:Rwh-thumb.png|frameless|right|Cover]] Bryan O'Sullivan, Don Stewart, and John Goerzen: [http://book.realworldhaskell.org/ <em>Real World Haskell</em>], Paperback: 700 pages, O'Reilly, November 2008, English, ISBN-10: 0596514980, ISBN-13: 978-0596514983<br />
<dd><br />
See ''[[Real World Haskell]]''. <br />
<br />
<br><br />
<dt>[[Image:pcph-thumb.gif|70px|frameless|right|Cover]] Simon Marlow: [http://community.haskell.org/~simonmar/pcph/ <em>Parallel and Concurrent Programming in Haskell</em>], Paperback: 322 pages, O'Reilly, August 2013, English, ISBN-10: 1449335942, ISBN-13: 978-1449335946<br />
<dd><br />
<B>Book Description</B><BR> <br />
f you have a working knowledge of Haskell, this hands-on book shows you how to use the language’s many APIs and frameworks for writing both parallel and concurrent programs. You’ll learn how parallelism exploits multicore processors to speed up computation-heavy programs, and how concurrency enables you to write programs with threads for multiple interactions.<br />
<br />
Author Simon Marlow walks you through the process with lots of code examples that you can run, experiment with, and extend. Divided into separate sections on Parallel and Concurrent Haskell, this book also includes exercises to help you become familiar with the concepts presented:<br />
<br />
* Express parallelism in Haskell with the Eval monad and Evaluation Strategies<br />
* Parallelize ordinary Haskell code with the Par monad<br />
* Build parallel array-based computations, using the Repa library<br />
* Use the Accelerate library to run computations directly on the GPU<br />
* Work with basic interfaces for writing concurrent code<br />
* Build trees of threads for larger and more complex programs<br />
* Learn how to build high-speed concurrent network servers<br />
* Write distributed programs that run on multiple machines in a network <br />
<br />
<br />
<DT>[[Image:The_Haskell_School_of_Expression.jpg|frameless|right|Cover]] Paul Hudak: [http://www.cs.yale.edu/homes/hudak/SOE/ <EM>The Haskell School of Expression: Learning Functional Programming through Multimedia</EM>], Cambridge University Press, New York, 2000, 416pp, 15 line diagrams, 75 exercises, Paperback $29.95, ISBN 0521644089, Hardback $74.95, ISBN 0521643384<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book teaches functional programming as a way of thinking and<br />
problem solving, using Haskell, the most popular purely functional<br />
language. Rather than using the conventional mathematical examples<br />
commonly found in other programming language textbooks, the author<br />
draws examples from multimedia applications, including graphics,<br />
animation, and computer music, thus rewarding the reader with working<br />
programs for inherently more interesting applications. Aimed at both<br />
beginning and advanced programmers, this tutorial begins with a gentle<br />
introduction to functional programming and moves rapidly on to more<br />
advanced topics. An underlying theme is the design and implementation<br />
of <em>domain specific languages</em>, using three examples: FAL (a Functional<br />
Animation Language), IRL (an Imperative Robot Language), and MDL (a<br />
Music Description Language). Details about programming in Haskell<br />
are presented in boxes throughout the text so they can be easily<br />
referred to and found quickly.<br />
<br />
The book's [http://plucky.cs.yale.edu/soe Web Site] contains source files for all programs in the text, as well as the graphics libraries to run them under Windows and Linux platforms. It also contains PowerPoint slides useful for<br />
teaching a course using the textbook.<br />
<br />
*There is a review of SOE on this wiki: [[The Monad.Reader/Issue3/SoE Review]].<br />
<br />
<DT>[[Image:The_Craft_of_Functional_Programming.jpg|frameless|right|Cover]] Simon Thompson: [http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/ <EM>Haskell: The Craft of Functional Programming</EM>], Second Edition, Addison-Wesley, 507&nbsp;pages, paperback, 1999. ISBN 0-201-34275-8.<br />
<dd><br />
<B>Book Description</B><BR> <br />
The second edition of Haskell: The Craft of Functional Programming is essential reading for beginners to functional programming and newcomers to the Haskell programming language. The emphasis is on the process of crafting programs and the text contains many examples and running case studies, as well as advice an program design, testing, problem solving and how to avoid common pitfalls. <br />
<br />
Building on the strengths of the first edition, the book includes many new and improved features: <br />
*Complete coverage of Haskell 98, the standard version of Haskell which will be stable and supported by implementations for years to come. <br />
*An emphasis on software engineering principles, encouraging a disciplined approach to building reusable libraries of software components. <br />
*Detailed coverage of the Hugs interpreter with an appendix covering other implementations. <br />
*A running case study of pictures emphasizes the built-in functions which appear in the standard prelude and libraries. It is also used to give an early preview of some of the more complex language features, such as high-order functions. <br />
*List comprehensions and the standard functions over lists are covered before recursion. <br />
*Early coverage of polymorphism supporting the "toolkit" approach and encouraging the resuse of built-in functions and types. <br />
*Extensive reference material containing details of further reading in books, journals and on the World Wide Web. <br />
*Accompanying Web Site supporting the book, containing all the program code, further teaching materials and other useful resources. <br />
<B>Synopsis</B><BR> <br />
This books introduces Haskell at a level appropriate for those with little or no prior experience of functional programming. The emphasis is on the process of crafting programs, solving problems, and avoiding common errors.<br />
<br />
<DT>[[Image:Introduction_to_Functional_Programming.jpg|frameless|right|Cover]] Richard Bird: [http://www.prenhall.com/allbooks/ptr_0134843460.html <EM>Introduction to Functional Programming using Haskell</EM>], 2nd edition, Prentice Hall Press, 1998, 460 pp., ISBN 0-13-484346-0.<br />
<dd><br />
From the cover:<br />
<br />
After the success of the first edition, Introduction to Functional Programming using Haskell has been thoroughly updated and revised to provide a complete grounding in the principles and techniques of programming with functions.<br />
<br />
The second edition uses the popular language Haskell to express functional programs. There are new chapters on program optimisation, abstract datatypes in a functional setting, and programming in a monadic style. There are completely new case studies, and many new exercises.<br />
<br />
As in the first edition, there is an emphasis on the fundamental techniques for reasoning about functional programs, and for deriving them systematically from their specifications.<br />
<br />
The book is self-contained, assuming no prior knowledge of programming, and is suitable as an introductory undergraduate text for first- or second-year students.<br />
<br />
<br />
<DT>[[Image:Introduction_to_Functional_Programming_Systems_Using_Haskell.jpg|frameless|right|Cover]] Antony Davie: [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=0521277248 <EM>An Introduction to Functional Programming Systems Using Haskell</EM>], Cambridge University Press, 1992. ISBN 0-521-25830-8 (hardback). ISBN 0-521-27724-8 (paperback).<br />
<dd>Cover:<br />
<br />
Functional programming is a style of programming that has become increasingly popular during the past few years.<br />
Applicative programs have the advantage of being almost immediately expressible as functional descriptions; they can<br />
be proved correct and transformed through the referential transparency property.<br />
<br />
This book presents the basic concepts of functional programming, using the language Haskell for examples. The author<br />
incorporates a discussion of lambda calculus and its relationship with Haskell, exploring the implications for<br />
raparallelism. Contents: SASL for Beginners / Examples of SASL Programming / More Advanced Applicative Programming<br />
Techniques / Lambda Calculus / The Relationship Between Lambda Calculus and SASL / Program Transformation and<br />
Efficiency / Correctness, Equivalence and Program Verification / Landin's SECD Machine and Related<br />
Implementations / Further Implementation Techniques / Special Purpose Hardware / The Applicative Style of<br />
Semantics / Other Applicative Languages / Implications for Parallelism / Functional Programming in Von Neumann<br />
Languages <br />
<br />
<DT>[[Image:Algorithms_A_Functional_Approach.jpg|frameless|right|Cover]] Fethi Rabhi and Guy Lapalme: [http://www.iro.umontreal.ca/~lapalme/Algorithms-functional.html <EM> Algorithms: A functional programming approach</EM>], <br />
Addison-Wesley, 235&nbsp;pages, paperback, 1999. ISBN 0-201-59604-0<BR><br />
<DD><br />
<B>Book Description</B><BR> <br />
The authors challenge more traditional methods of teaching algorithms<br />
by using a functional programming context, with Haskell as an<br />
implementation language. This leads to smaller, clearer and more<br />
elegant programs which enable the programmer to understand the<br />
algorithm more quickly and to use that understanding to explore<br />
alternative solutions. <br><br />
<b>Key features:</b><br />
*Most chapters are self-contained and can be taught independently from each other.<br />
*All programs are in Haskell'98 and provided on a WWW site.<br />
*End of chapter exercises throughout.<br />
*Comprehensive index and bibliographical notes.<br />
<B>Synopsis</B><BR> <br />
The book is organised as a classic algorithms book according to topics<br />
such as Abstract Data Types, sorting and searching. It uses a<br />
succession of practical programming examples to develop in the reader<br />
problem-solving skills which can be easily transferred to other<br />
language paradigms. It also introduces the idea of capturing<br />
algorithmic design strategies (e.g. Divide-and-Conquer, Dynamic<br />
Programming) through higher-order functions.<br><br />
<b>Target audience</b><br><br />
The book is intended for computer science students taking algorithms<br />
and/or (basic or advanced) functional programming courses.<br />
<br />
<dt>[[Image:Fun_of_Programming.jpg|frameless|right|Cover]] Jeremy Gibbons and Oege de Moor (eds.): [http://www.palgrave.com/catalogue/catalogue.asp?Title_Id=0333992857 <em>The Fun of Programming</em>],Palgrave, 2002, 288 pages. ISBN 0333992857.<br />
<dd><br />
<b>Book description:</b><br><br />
In this textbook, leading researchers give tutorial expositions on the current state of the art of functional<br />
programming. The text is suitable for an undergraduate course immediately following an introduction to<br />
functional programming, and also for self-study. All new concepts are illustrated by plentiful examples,<br />
as well as exercises. A [http://web.comlab.ox.ac.uk/oucl/publications/books/fop/ website] gives access to accompanying software.<br />
<br />
<dt>Simon Peyton Jones: [http://research.microsoft.com/Users/simonpj/Papers/slpj-book-1987/index.htm <em>Implementation of Functional Programming] Language</em>], 500 pages, Prentice-Hall, 1987. ISBN 0134533259.<br />
<dd><br />
This 1987 book is now out of print, but it is now available [http://research.microsoft.com/Users/simonpj/Papers/slpj-book-1987/index.htm online] in its entirety.<br />
<br />
<dt>Simon Peyton Jones, David Lester: [http://www.amazon.com/Implementing-Functional-Languages-Prentice-Hall-International/dp/0137219520/sr=1-1/qid=1162002704/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Implementing Functional Languages</em>], Paperback: 288 pages, Prentice Hall (August 1992), English, ISBN 0137219520 <br><br />
<dd><br />
The book is out of print. The full sources and a postscript version are <br />
[http://research.microsoft.com/Users/simonpj/Papers/papers.html available for free].<br />
<br />
This book gives a practical approach to understanding the<br />
implementations of non-strict functional languages using lazy graph<br />
reduction. The emphasis of the book is on building working prototypes of<br />
several functional language implementations (template- instantiation,<br />
G-Machine, TIM, parallel G-Machine. In each case the authors provide a<br />
complete working prototype of a particular implementation, and then lead<br />
the reader through a sequence of improvements which expand its scope.<br />
This enables readers to develop, modify and experiment with their own<br />
implementations and for use as a source of practical laboratory work<br />
material.<br />
<br />
<dt>[[Image:TTFP.jpg|frameless|right|Cover]] Simon Thompson: [http://www.amazon.com/Functional-Programming-International-Computer-Science/dp/0201416670/sr=1-1/qid=1162002856/ref=sr_1_1/104-0009163-6568732?ie=UTF8&s=books <em>Type Theory and Functional Programming</em>], Addison-Wesley, 1991. ISBN 0-201-41667-0. Hardcover: 388 pages.<br />
<dd><br />
Now out of print, the original version is available [http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ here].<br />
<br />
<em>Preface</em>:<br />
Constructive Type theory has been a topic of research interest to computer scientists,<br />
mathematicians, logicians and philosophers for a number of years. For computer scientists it provides<br />
a framework which brings together logic and programming languages in a most elegant and fertile way:<br />
program development and verification can proceed within a single system. Viewed in a different way,<br />
type theory is a functional programming language with some novel features, such as the totality of<br />
all its functions, its expressive type system allowing functions whose result type depends upon the<br />
value of its input, and sophisticated modules and abstract types whose interfaces can contain logical<br />
assertions as well as signature information. A third point of view emphasizes that programs (or<br />
functions) can be extracted from proofs in the logic.<br />
<br />
<DT>[[Image:Uma_Abordagem_Pratica.jpg|frameless|right|Cover]] Claudio Cesar de Sá and Marcio Ferreira da Silva: <em> Haskell: Uma Abordagem Prática</em>, [http://www.novatec.com.br Novatec Editora Ltda.], 2006, 296 pages, ISBN 85-7522-095-0. The price is R$ 62,00 (in Reais). Language: Portuguese<br />
<dd><br />
This book is being published by Novatec Editora Ltda. You can access directly [http://www.novateceditora.com.br/livros/haskell/ here].<br />
<br><br />
<b>Book description:</b><br><br />
This book brings a comprehensive vision of Haskell language. No <br />
knowledge in another functional programming language is expected. In <br />
addition, no background in programming is required. The book presents <br />
issues from basic up to an intermediate level; it also includes some <br />
advanced aspects of Haskell. The title of the book, <em>Haskell: Uma <br />
Abordagem Prática</em>, in English <em>Haskell: A Practical Approach</em>, is the essence of the book. The result is a text that can be used in courses of programming and paradigms languages. Finally, many practical examples can be found throughout the book.<br />
<br />
An additional page containing comments on this book is found here:<br />
[http://www2.joinville.udesc.br/~coca/index.php/Main/PaginaDoLivroDeHaskell].<br />
Other data as bibtex entry, cover's book in several formats, Winhugs-2001 for download, and so on. This page is Portuguese.<br />
<br />
<dt>[[Image:portada.jpg|frameless|right|Cover]] Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo. [http://www.lcc.uma.es/~pepeg/pfHaskell/index.html <em>Razonando con Haskell</em>], Thompson 2004. ISBN 84-9732-277-0. Language: Spanish<br />
<dd><br />
Descripción El objetivo principal de este libro es el de servir como<br />
libro de texto de las asignaturas de Programación Declarativa<br />
correspondientes a los estudios de Informática o Ciencias de la<br />
Computación, y otras ciencias en general ( Matemáticas, Física, etc.).<br />
El texto es fruto de una larga experiencia docente de los autores dentro<br />
de las distintas asignaturas que desarrollan la Programación Funcional<br />
en distintas titulaciones de la Universidad de Málaga. Aún así, su<br />
lectura no queda condicionada a un conocimiento previo sobre lenguajes<br />
de programación (de computadores), ni sobre Informática. De esta forma,<br />
el libro puede ser utilizado por todo aquel que desee tener un<br />
conocimiento amplio sobre la Programación Funcional. <br />
<br />
<dt>[[Image:haskell-jp.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4839919623 Haskell Primer: The first functional language to learn]. Jun Mukai. In Japanese. Yen 2,730.<br />
<dd><br />
<br />
<dt>[[Image:Haskell-jp-2.jpg|frameless|right|Cover]] [http://www.amazon.co.jp/gp/product/4797336021 Practical Haskell Programming], Minero Aoki and Nobuo Yamashita. A primer on functional programming for real world programs. In Japanese. Yen 2,940. <br />
<dd><br />
<br />
<dt>[[Image:Purely_Functional_Data_Structures.jpg|frameless|right|Cover]] [http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=0521663504 Purely Functional Data Structures] [http://www.eecs.usma.edu/webs/people/okasaki/ Chris Okasaki], 232 pp., Cambridge University Press, 1998. ISBN 0-521-63124-6<br />
<dd><br />
From the cover:<BR/> Most books on data structures assume an imperative language like C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Haskell, or Scheme. This book describes data structures and data structure design techniques from the point of view of functional languages. It includes code for a wide assortment both of classical data structures and of data structures developed exclusively for functional languages.This handy reference for professional programmers working with functional languages can also be used as a tutorial or for self-study. [http://www.eecs.usma.edu/webs/people/okasaki/pfds-haskell.tar.gz Haskell source code for the book]<br />
<br />
<DT>[[Функциональное программирование на языке Haskell]]<br />
<br />
<DT>[[Справочник по языку Haskell]]<br />
<br />
<DT>[[Практика работы на языке Haskell]]<br />
<br />
<DT>[[14 занимательных эссе о языке Haskell и функциональном программировании]]<br />
<br />
<dt> <br />
[[Image:Cartea-lui-Dan-Popa-coperta-1.png|frameless|right|Cover]] [http://www.edusoft.ro/detalii.php?id=81 Introducere in Haskell 98 prin exemple ]: Dan Popa, 230 pp., Edusoft Bacau, Romania, (Ian, 31, 2007),Romanian, ISBN 978-973-8934-48-1<br />
<dd><b>De pe coperta</b><BR><br />
(ro) Cartea este simultan un manual introductiv de Haskell si o carte auxiliara pentru studentii de la cursul de limbaje formale. Veti avea satisfactia cunoasterii unui limbaj modern (...) in care algoritmul de sortare Quicksort se scrie pe 6 randuri, asa cum se poate vedea de altfel si in imaginea de pe coperta I. (...) Cartea cuprinde o serie de capitole folosite la Universitatea Bacau in calitate de auxiliare de laborator la disciplina Limbaje Formale si Automate.<br />
<br><br />
(en) This book is simultaneously a manual of Haskell and an auxiliary book for the students of the FLA course (Formal Languges and Automata). You will be satisfied by this modern language,Haskell. Why ? Using Haskell the Quicksort algorithm can be writen on 6 lines (or less), as you can see on the cover. And that's not all ... This book is used at Bacau State University, Romania. <br />
<br />
<dt>James Church : [[Image: Getting_Started_with_Haskell_Data_Analysis.png|frameless|right|70px|Cover]] [https://india.packtpub.com/in/big-data-and-business-intelligence/getting-started-haskell-data-analysis Getting Started with Haskell Data Analysis], ISBN13 9781789802863, Paperback/eBook: 160 pages. Packt October 2018)<br />
<dd><br />
<B>Book Description</B><BR><br />
Every business and organization that collects data is capable of tapping into its own data to gain insights how to improve. Haskell is a purely functional and lazy programming language, well-suited to handling large data analysis problems. This book will take you through the more difficult problems of data analysis in a hands-on manner.<br />
<br />
This book will help you get up-to-speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and progress to more advanced concepts such as understanding the importance of normal distribution. While mathematics is a big part of data analysis, we've tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
By the end of this book, you will have a thorough understanding of data analysis, and the different ways of analyzing data. You will have a mastery of all the tools and techniques in Haskell for effective data analysis.<br />
<br />
<dt>Yogesh Sajanikar : [[Image: Haskell_Cookbook.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-cookbook Haskell Cookbook], ISBN13 9781786461353, Paperback/eBook: 396 pages. Packt (September 2017)<br />
<dd><br />
<B>Book Description</B><BR><br />
Haskell Cookbook provides recipes that start by illustrating the principles of functional programming in Haskell, and then gradually build up your expertise in creating industrial-strength programs to accomplish any goal. The book covers topics such as Functors, Applicatives, Monads, and Transformers. You will learn various ways to handle state in your application and explore advanced topics such as Generalized Algebraic Data Types, higher kind types, existential types, and type families. The book will discuss the association of lenses with type classes such as Functor, Foldable, and Traversable to help you manage deep data structures.<br />
<br />
<dt>[[Image:HaskellDataAnalysis.png|70px|frameless|right|Cover]] Nishant Shukla: [http://haskelldata.com <em>Haskell Data Analysis Cookbook</em>], Paperback: 334 pages, Packt, June 2014, English, ISBN-10: 1783286334, ISBN-13: 978-1783286331<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book will take you on a voyage through all the steps involved in data analysis. It provides synergy between Haskell and data modeling, consisting of carefully chosen examples featuring some of the most popular machine learning techniques.<br />
<br />
You will begin with how to obtain and clean data from various sources. You will then learn how to use various data structures such as trees and graphs. The meat of data analysis occurs in the topics involving statistical techniques, parallelism, concurrency, and machine learning algorithms, along with various examples of visualizing and exporting results. By the end of the book, you will be empowered with techniques to maximize your potential when using Haskell for data analysis.<br />
<br />
The [https://github.com/BinRoot/Haskell-Data-Analysis-Cookbook GitHub public repository] contains over 130 practical recipes to accompany every chapter of the book. Use it as a Swiss Army Knife of algorithms and code snippets. Try a recipe a day, like a kata for your mind.<br />
<br />
<dt>Samuli Thomasson: [[Image: HaskellHighPerformanceProgramming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-high-performance-programming Haskell High Performance Programming Book], ISBN 139781786464217, Paperback, 408 pages Packt, September 2016<br />
<dd><br />
<B>Book Description</B><BR> <br />
Haskell, with its power to optimize the code and its high performance, is a natural candidate for high performance programming. It is especially well suited to stacking abstractions high with a relatively low performance cost. This book addresses the challenges of writing efficient code with lazy evaluation and techniques often used to optimize the performance of Haskell programs.<br />
Learn to use parallelism and explore the concept of streaming. This book demonstrates the benefits of running multithreaded and concurrent applications. Next it will guide you through various profiling tools that will help you identify performance issues in your program. <br />
<br />
<br />
<dt> Ryan Lemmer: [[Image:Haskell Design Patterns.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/haskell-design-patterns/?utm_source=GC-wiki.haskell.org&utm_medium=pod&utm_campaign=178398872X Haskell Design Patterns], Paperback: 166 pages, Packt, November 2015, English, ISBN-10: 1-783-98872-X, ISBN-13: 9781783988723<br />
<dd><br />
<B>Book Description</B><BR> <br />
Design patterns and idioms can widen our perspective by showing us where to look, what to look at, and ultimately how to see what we are looking at. At their best, patterns are a shorthand method of communicating better ways to code (writing less, more maintainable, and more efficient code).<br />
<br />
This book starts with Haskell 98 and through the lens of patterns and idioms investigates the key advances and programming styles that together make "modern Haskell". Your journey begins with the three pillars of Haskell. Then you'll experience the problem with Lazy I/O, together with a solution. You'll also trace the hierarchy formed by Functor, Applicative, Arrow, and Monad. Next you'll explore how Fold and Map are generalized by Foldable and Traversable, which in turn is unified in a broader context by functional Lenses. You'll delve more deeply into the Type system, which will prepare you for an overview of Generic programming. In conclusion you go to the edge of Haskell by investigating the Kind system and how this relates to Dependently-typed programming.<br />
<br />
<dt> James Church: [[Image:Learning_Haskell_Data_Analysis_cov.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/learning-haskell-data-analysis/?utm_source=GCwiki.haskell.org&utm_medium=pod&utm_campaign=1784394707 Learning Haskell Data Analysis], Paperback: 198 pages, Packt, May 2015, English, ISBN-10: 1-784-39470-7, ISBN-13: 9781784394707<br />
<dd><br />
<B>Book Description</B><BR> <br />
This book provides you with the skills to handle large amounts of data, even if that data is in a less than perfect state. Each chapter in the book helps to build a small library of code that will be used to solve a problem for that chapter.<br />
<br />
The book starts with creating databases out of existing datasets, cleaning that data, and interacting with databases within Haskell in order to produce charts for publications. It then moves towards more theoretical concepts that are fundamental to introductory data analysis, but in a context of a real-world problem with real-world data. As you progress in the book, you will be relying on code from previous chapters in order to help create new solutions quickly. By the end of the book, you will be able to manipulate, find, and analyze large and small sets of data using your own Haskell libraries.<br />
</dt><br />
<br />
<dt> Julien Dehos: [[Image:Book-ellipses-jd.jpg|frameless|right|70px|Cover]] [https://www.editions-ellipses.fr/programmation-fonctionnelle-introduction-applications-haskell-lusage-letudiant-developpeur-p-13083.html La programmation fonctionnelle - Introduction et applications en Haskell à l'usage de l'étudiant et du développeur], 264 pages, Ellipses Références sciences, 2019, French, ISBN: 9782340028777<br />
<dd><br />
Ce livre a pour objectif d’initier à la programmation fonctionnelle en général et au langage Haskell en particulier ; ceci de façon réellement exploitable. Il en présente les principales notions ainsi que différentes applications (intelligence artificielle pour des jeux, application web, convertisseur de fichiers textes, etc.). Enfin, il indique comment mettre en oeuvre le style fonctionnel dans des langages comme C++ et JavaScript.<br />
</dt><br />
<br />
</DL><br />
<br />
===Foundations===<br />
<br />
<DL><br />
<DT>[[Image:TaPL.jpg|frameless|right|Cover]]<br />
[http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=pd_sim_b_4/104-0009163-6568732 Types and Programming Languages] by Benjamin C. Pierce. 645 pages, The MIT Press, (February 1, 2002), English. ISBN 0262162091<br />
<DD>From the cover:<BR><br />
A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of type systems--and of programming languages from a type-theoretic perspective-has important applications in software engineering, language design, high-performance compilers, and security. This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages. The approach is pragmatic and operational; each new concept is motivated by programming examples and the more theoretical sections are driven by the needs of implementations. Each chapter is accompanied by numerous exercises and solutions, as well as a running implementation, available via the Web. Dependencies between chapters are explicitly identified, allowing readers to choose a variety of paths through the material. The core topics include the untyped lambda-calculus, simple type systems, type reconstruction, universal and existential polymorphism, subtyping, bounded quantification, recursive types, kinds, and type operators. Extended case studies develop a variety of approaches to modeling the features of object-oriented languages.<br />
<br />
<DT>[[Image:Advanced_TaPL.jpg|frameless|right|Cover]] [http://www.amazon.com/Advanced-Topics-Types-Programming-Languages/dp/0262162288/ref=pd_sim_b_1/104-0009163-6568732 Advanced Topics in Types and Programming Languages] by Benjamin C. Pierce (Editor), Hardcover: 608 pages, The MIT Press (December 23, 2004), Language: English, ISBN 0262162288.<DD><br />
From the cover:<BR><br />
The study of type systems for programming languages now touches many areas of computer science, from language design and implementation to software engineering, network security, databases, and analysis of concurrent and distributed systems. This book offers accessible introductions to key ideas in the field, with contributions by experts on each topic. The topics covered include precise type analyses, which extend simple type systems to give them a better grip on the run time behavior of systems; type systems for low-level languages; applications of types to reasoning about computer programs; type theory as a framework for the design of sophisticated module systems; and advanced techniques in ML-style type inference. Advanced Topics in Types and Programming Languages builds on Benjamin Pierce's Types and Programming Languages (MIT Press, 2002); most of the chapters should be accessible to readers familiar with basic notations and techniques of operational semantics and type systems -- the material covered in the first half of the earlier book. Advanced Topics in Types and Programming Languages can be used in the classroom and as a resource for professionals. Most chapters include exercises, ranging in difficulty from quick comprehension checks to challenging extensions, many with solutions.<br />
<br />
<DT>[http://www-2.cs.cmu.edu/~rwh/plbook/ Programming Languages: Theory and Practice] by Robert Harper. (Draft).<br />
<DD>A working draft of a planned book on the theoretical foundations of practical programming languages.<br />
<br />
<DT>[http://homepages.cwi.nl/~jve/cs/ Computational Semantics and Type Theory]<br />
by Jan van Eijck. Draft.<br />
<DD>[http://www.cwi.nl/~jve/cs/cs.pdf Text online].<br />
<br />
<DT>[http://www.cs.man.ac.uk/~pt/stable/Proofs+Types.html Proofs and Types]<br />
by Jean-Yves Girard translated and with appendices by Paul Taylor and Yves Lafont.<br />
<DD><br />
Based on a short graduate course on typed lambda-calculus given at the Universit Paris VII in the autumn term of 1986-7.<br />
<br />
<DT>[http://www.cs.uu.nl/wiki/Techno/ProgrammingLanguageTheoryTextsOnline Programming language theory texts online]<br />
<DD><br />
Collection of online programming language theory texts maintained by Frank Atanassow<br />
<br />
<DT>[http://www.cs.chalmers.se/Cs/Research/Logic/book/ Programming in Martin-Löf's Type Theory: An Introduction] by Bengt Nordström, Kent Petersson and Jan M. Smith. 1990.<br />
<DD><br />
<br />
</DL><br />
<br />
===Monadic Programming===<br />
<br />
<DL><br />
<br />
<DT>[[Image:Coperta5.jpg|frameless|right|75px|Haskell - PIM]] [[Practica_interpretarii_monadice|Practical monadic interpretation]] by Dan Popa , Language: Romanian<br />
<br />
<DD><br />
Foreword of the book (en):<br />
<br />
I am delighted to introduce this book on the use of monads in Haskell as a way of structuring interpreters. In the early days, Haskell's most distinctive feature was lazy evaluation. Laziness forced us to take a pure approach to input/output, which meant that Haskell's I/O was initially rather weak. This weakness ultimately proved a strength, however, because it led us to the discovery that monads were not just an abstract mathematical concept, but were immediately applicable as a powerful program structuring mechanism.<br />
<br />
Monadic programming is not just to do with input/output: it is much more powerful. That is why I am pleased to see this book, which describes in some detail how to write a language interpreter using a monadic approach.<br />
<br />
In retrospect, the discovery of monads as a practical programming pattern is one of Haskell's most substantial contributions to the world of programming -- and it is one that you will share if you work through this book.<br />
<br />
I am also very happy to see Haskell growing in popularity among our brothers and sisters in Eastern Europe, and in Romania in particular. Enjoy!<br />
<br />
Simon P.J.<br />
</DL><br />
<br />
===Mathematics===<br />
<br />
See [[Books and tutorials/Mathematics]]<br />
<br />
===Miscellaneous===<br />
<br />
[[Real World #haskell]]<br />
<br />
===Videos===<br />
<br />
<dt>Richard Cook : [[Image: Building-an-Application-with-Functional-Haskell-Video.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/building-application-functional-haskell-video Building an Application with Functional Haskell (Video)], ISBN13 9781787285088, Course Length 2 hours 9 minutes. Packt (August 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video is specifically aimed at anybody who knows the essentials of the Haskell programming language and who is interested in moving onto developing real programs that will make use of file I/O, command-line parsers and various third-party packages. This course will take you through the complete journey from writing your first Haskell program to getting familiarized with Haskell and all its functionalities.<br />
<br />
<dt>Richard Cook : [[Image: Writing_Haskell_Programs.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/writing-haskell-programs-video Writing Haskell Programs (Video)], ISBN13 9781787283329, Video Length 2 hours and 43 minutes. Packt (May 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This course builds on the foundations provided by the Fundamentals of Practical Haskell Programming course and helps to bridge the gap between introductory and advanced Haskell by teaching you how to manage and develop complex programs. We'll also dispel the myth that Haskell is only useful for toy programs.<br />
<br />
<dt>Richard Cook : [[Image: Fundamentals_of_Practical_Haskell_Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/fundamentals-practical-haskell-programming-video Fundamentals of Practical Haskell Programming (Video)], ISBN13 9781787288768, Video Length 2 hours and 59 minutes. Packt (March 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
This video course will take you through all the concepts of functional programming (FP) and Haskell language. First, we’ll address all the problems with FP and Haskell. Then we’ll help you distinguish the difference between FP and Haskell. We’ll then guide you through Haskell in depth. We’ll help you create your first Haskell program. You’ll then be given a brief insight into GHCi (Glasgow Haskell Compiler). Later we’ll explore the different values, expressions and programs in Haskell in depth.<br />
<br />
<dt> [[Image: Haskell Data Analysis Made Easy.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/haskell-data-analysis-made-easy Haskell: Data Analysis Made Easy], ISBN13 9781787283633, Course Length 7 hours 30 minutes. Packt (February 2017)<br />
<dd><br />
<B>Course Description</B><BR><br />
This course will introduce the basic concepts of Haskell and move on to discuss how Haskell can be used to solve the issues by using the real-world data.<br />
The course will guide you through the installation procedure, after you have all the tools that you require in place, you will explore the basic concepts of Haskell including the functions, and the data structures.<br />
With a good hold on the basics of Haskell and data analysis, you will then be introduced to advanced concepts of data analysis such as Kernel Density Estimation, Hypothesis testing, Regression analysis, text analysis, clustering, Naïve Bayes Classification, and Principal Component Analysis.<br />
<br />
<dt>Samuel Gélineau : [[Image: Mastering Haskell Programming.png|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/mastering-haskell-programming-video Mastering Haskell Programming (Video)], ISBN13 9781786465016, Course Length 6 hours 4 minutes. Packt (February 2017)<br />
<dd><br />
<B>Video Description</B><BR><br />
In this course, you’ll discover different ways to structure interactions between the program and the outside world. We’ll look at some subtler aspects of the IO monad, such as lazy IO and unsafePerformIO. In addition to the IO monad, we’ll also check out two other structured forms of interaction: streaming libraries and functional reactive programming.<br />
Then we explore parallel, concurrent, and distributed programming. Thanks to purity, Haskell is especially well-suited for the first two, and so there are a number of approaches to cover. As for distributed programming, we focus on the idea of splitting a large monolithic program into smaller microservices, asking whether doing so is a good idea. We’ll also consider a different way of interacting with other microservices, and explore an alternative to microservices.<br />
<br />
<dt>James Church : [[Image:Advanced_data.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/advanced-data-analysis-haskell-video Advanced Data Analysis with Haskell Video], ISBN13 9781785287237, Course Length 4 hours 4 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
In this video, you will be guided on how to find correlations in data, as well as multiple dependent variables. You will be given a theoretical overview of the types of regression and we’ll show you how to install the LAPACK and HMatrix libraries. By the end of the first part, you’ll be familiar with the application of N-grams and TF-IDF.<br />
Once you’ve learned how to analyze data, the next step is organizing that data with the help of machine learning algorithms. You will be briefed on the mathematics and statistical theorems such as Baye’s law and its application, as well as eigenvalues and eigenvectors using HMatrix.<br />
By the end of this course, you’ll have an understanding of data analysis, different ways to analyze data, and the various clustering algorithms available. You’ll also understand Haskell and will be ready to write code with it.<br />
<br />
<dt>Hakim Cassimally : [[Image: Learning_Haskell_Programming.jpeg|frameless|right|70px|Cover]] [https://www.packtpub.com/application-development/learning-haskell-programming Learning Haskell Programming Video], ISBN13 9781786465542, Course Length 4 hours 10 minutes Packt, December 2016<br />
<dd><br />
<B>Video Description</B><BR><br />
This video would begin with the fundamentals and building blocks of Haskell programming language with special emphasis on functional programming. It will be covering how Haskell variables, syntax work alongwith Haskell datatypes and functions.<br />
You will learn how to solve programming problems while creating an application with hands-on experience. You will then move on to learning writing expressions and high-order functions.<br />
At the end of the video, you will be able to build a complete application with Haskell alongwith learning the important functionalities.<br />
<br />
<dt>James Church: [[Image: GettingStartedWithHaskellDataAnalysis1.png|frameless|right|70px|Cover]] [https://www.packtpub.com/big-data-and-business-intelligence/getting-started-haskell-data-analysis-video Getting Started with Haskell Data Analysis Video], Course Length: 3 hours 18 minutes, Packt, July 2016, English, ISBN-13: 9781785880841<br />
<dd><br />
<B>Course Description</B><BR> <br />
Data analysis is part computer science and part statistics. An important part of data analysis is validating your assumptions with real-world data to see if there is a pattern, or a particular user behavior that you can validate. This video course will help you get up to speed with the basics of data analysis and approaches in the Haskell language. You'll learn about statistical computing, file formats (CSV and SQLite3), descriptive statistics, charts, and onto more advanced concepts like understanding the importance of normal distribution. Whilst mathematics is a big part of data analysis, we’ve tried to keep this course simple and approachable so that you can apply what you learn to the real world.<br />
<br />
==Joke==<br />
<br />
<DL><br />
<dt>[[Image:FunctionalIkamusume.jpg|frameless|right|70px|Cover]] Team "Referential Transparent Sea Keepers": [http://www.paraiso-lang.org/ikmsm/ <em>Functional Ikamusume</em>]<br />
[http://www.paraiso-lang.org/ikmsm/books/index.html <em>book series</em>], Japanese<br />
<dd><B>Book Description</B><BR><br />
Functional Ikamusume book series provides a forum for researchers, developers, and anime-watchers to publish their latest work, articles, and “mousou (妄想)” on the design, implementations, principles, and uses of functional programming and Ikamusume. The book series covers the entire spectrum of work, from practice to theory, from frank introduction of functional programming to latest research work, from Ikamusume with some functional flavor to functional programming with some Ikamusume flavor. Let’s enjoy writing articles on functional programming in frank “geso” style de-geso!!<br />
<br />
Past books are written entirely in Japanese, and books are planned to be sold in Japan, but we also accept articles in English. For more information on functional Ikamusume, see the links above (all in Japanese), or ask @xhl_kogitsune or [http://www.paraiso-lang.org/ikmsm/members.html "other members"] on twitter, or xhlkogitsune on Skype. You don’t have to be worried about what is Functional Ikamusume —— she is just Ikamusume who loves functional programming, as you love it.<br />
<br />
If you are interested in writing Functional Ikamusume articles, please contact xhlkogitsune on Skype or the authors on twitter. You can use Japanese or English for discussion. A text chat room is on Skype, and I’ll invite you to the chat room. While the chat is currently in Japanese, most participants can read/write English.<br />
<br />
</DL></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=File:Test.txt&diff=62808File:Test.txt2019-03-04T17:43:31Z<p>HowardBGolden: Testing new wiki's upload feature.</p>
<hr />
<div>Testing new wiki's upload feature.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Learning_Haskell&diff=62790Learning Haskell2019-02-25T05:30:06Z<p>HowardBGolden: /* Reference */ Update broken link to Tour of the Haskell Prelude (issue #17)</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.cse.chalmers.se/edu/course/TDA555/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>HowardBGoldenhttps://wiki.haskell.org/index.php?title=User:HowardBGolden&diff=62712User:HowardBGolden2019-01-07T19:56:15Z<p>HowardBGolden: Created page with "This is a test page."</p>
<hr />
<div>This is a test page.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Template:NewMain/Intro&diff=62502Template:NewMain/Intro2018-06-02T00:15:08Z<p>HowardBGolden: Proposed new main page</p>
<hr />
<div>This is the main page of the Haskell Wiki, which welcomes contributions from the Haskell community. The [https://www.haskell.org Haskell home page] is now separate.<br />
<br />
Haskell is an advanced [[functional programming|purely-functional]]<br />
programming language. An open-source product of more than twenty years of cutting-edge research, <br />
it allows rapid development of robust, concise, correct<br />
software. With strong support for [[Foreign_Function_Interface|integration with other languages]],<br />
built-in [[Parallel|concurrency and parallelism]], debuggers, profilers, [http://hackage.haskell.org/packages/hackage.html rich libraries] and an active community, Haskell makes it easier to produce flexible, maintainable, <br />
high-quality software.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Haskell.org_infrastructure&diff=62484Haskell.org infrastructure2018-05-17T23:49:43Z<p>HowardBGolden: Remove unnecessary underscore in link</p>
<hr />
<div>Haskell.org sub-domains are hosted on a variety of machines. Various machines have individuals responsible for them, and various services in turn have individuals responsible for those services.<br />
<br />
In general, the policy on the usage of the Haskell.org domain name and subdomains is set by the [[Haskell.org committee]]. The committee also manages a small amount of funds, generally garnered from Google Summer of Code payments, and uses them towards the maintenance of Haskell community infrastructure. It therefore also determines the policy on the uses of those machines that it pays for.<br />
<br />
Many people responsible for managing and helping with maintenance of Haskell.org servers are aliased at "admin [at the domain] haskell.org".<br />
<br />
If there are problems with infrastructure, it is good to check [https://status.haskell.org status.haskell.org] to see if they are already known. If not, emailing the admin at h.org mail alias and the #haskell-infrastructure irc channel on freenode are all good ways to get in touch. Automated uptime and status information is provided at [https://auto-status.haskell.org auto-status.haskell.org].<br />
<br />
The centralized location on infrastructure is now maintained at [https://phabricator.haskell.org/w/ the Haskell Phabricator Wiki], cataloging machines, responsibilities, etc.<br />
<br />
See also: [[Haskell Governance]]<br />
<br />
[[Category:Community]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Infrastructure&diff=62483Infrastructure2018-05-17T23:46:13Z<p>HowardBGolden: Correct capitalization</p>
<hr />
<div>#REDIRECT [[Haskell.org infrastructure]]<br />
= Infrastructure =<br />
<br />
'''This page is out-of-date. For more current information, please see [[Haskell Governance]].'''<br />
<br />
This page documents the currently active infrastructure projects in the Haskell community, under guidance of the Haskell infrastructure team.<br />
<br />
== Haskell Wiki move ==<br />
<br />
We want to move the haskell.org wiki to [http://new-www.haskell.org/haskellwiki/Haskell the new machine], and run it with the new version of mediawiki and the new template.<br />
<br />
Timeline:<br />
<br />
* new machine in place [done]<br />
* new template needed [done]<br />
* machine runs a modern mediawiki [done]<br />
* moving mailing lists.<br />
* moving user accounts:<br />
* create accounts on demand<br />
* move project accounts<br />
* policy decision to move project accounts to community.haskell.org - requires vote of haskell.org committee.<br />
* DNS move: depends on moving other services (mailing lists, user accounts).<br />
<br />
== Haskell.org committee ==<br />
<br />
* [http://www.haskell.org/haskellwiki/Haskell.org_committee Committee status]<br />
* Elect new board<br />
* Vote on any outstanding proposals.<br />
<br />
== Haskell.org incorporation ==<br />
<br />
Proposal to be moved to haskell.org committee.<br />
<br />
== New Hackage Server ==<br />
<br />
* Deploy new hackage server.<br />
* Testing? <br />
* Mirrors in place.<br />
* Ask for beta testers to use new hackage.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Infrastructure&diff=62482Infrastructure2018-05-17T23:42:56Z<p>HowardBGolden: Change page to a redirect to Haskell.org Infrastructure</p>
<hr />
<div>#REDIRECT [[Haskell.org Infrastructure]]<br />
= Infrastructure =<br />
<br />
'''This page is out-of-date. For more current information, please see [[Haskell Governance]].'''<br />
<br />
This page documents the currently active infrastructure projects in the Haskell community, under guidance of the Haskell infrastructure team.<br />
<br />
== Haskell Wiki move ==<br />
<br />
We want to move the haskell.org wiki to [http://new-www.haskell.org/haskellwiki/Haskell the new machine], and run it with the new version of mediawiki and the new template.<br />
<br />
Timeline:<br />
<br />
* new machine in place [done]<br />
* new template needed [done]<br />
* machine runs a modern mediawiki [done]<br />
* moving mailing lists.<br />
* moving user accounts:<br />
* create accounts on demand<br />
* move project accounts<br />
* policy decision to move project accounts to community.haskell.org - requires vote of haskell.org committee.<br />
* DNS move: depends on moving other services (mailing lists, user accounts).<br />
<br />
== Haskell.org committee ==<br />
<br />
* [http://www.haskell.org/haskellwiki/Haskell.org_committee Committee status]<br />
* Elect new board<br />
* Vote on any outstanding proposals.<br />
<br />
== Haskell.org incorporation ==<br />
<br />
Proposal to be moved to haskell.org committee.<br />
<br />
== New Hackage Server ==<br />
<br />
* Deploy new hackage server.<br />
* Testing? <br />
* Mirrors in place.<br />
* Ask for beta testers to use new hackage.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Infrastructure&diff=62481Infrastructure2018-05-17T23:38:00Z<p>HowardBGolden: Direct reader to Haskell Governance page</p>
<hr />
<div>= Infrastructure =<br />
<br />
'''This page is out-of-date. For more current information, please see [[Haskell Governance]].'''<br />
<br />
This page documents the currently active infrastructure projects in the Haskell community, under guidance of the Haskell infrastructure team.<br />
<br />
== Haskell Wiki move ==<br />
<br />
We want to move the haskell.org wiki to [http://new-www.haskell.org/haskellwiki/Haskell the new machine], and run it with the new version of mediawiki and the new template.<br />
<br />
Timeline:<br />
<br />
* new machine in place [done]<br />
* new template needed [done]<br />
* machine runs a modern mediawiki [done]<br />
* moving mailing lists.<br />
* moving user accounts:<br />
* create accounts on demand<br />
* move project accounts<br />
* policy decision to move project accounts to community.haskell.org - requires vote of haskell.org committee.<br />
* DNS move: depends on moving other services (mailing lists, user accounts).<br />
<br />
== Haskell.org committee ==<br />
<br />
* [http://www.haskell.org/haskellwiki/Haskell.org_committee Committee status]<br />
* Elect new board<br />
* Vote on any outstanding proposals.<br />
<br />
== Haskell.org incorporation ==<br />
<br />
Proposal to be moved to haskell.org committee.<br />
<br />
== New Hackage Server ==<br />
<br />
* Deploy new hackage server.<br />
* Testing? <br />
* Mirrors in place.<br />
* Ask for beta testers to use new hackage.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Xmonad/Frequently_asked_questions&diff=62313Xmonad/Frequently asked questions2018-02-08T04:20:34Z<p>HowardBGolden: /* What build dependencies does xmonad have? */ Update Ubuntu to xenial</p>
<hr />
<div>{{xmonad}}<br />
<br />
''xmonad: frequently asked questions''<br />
<br />
''For configuration tricks, and using xmonad.hs, see [[Xmonad/General_xmonad.hs_config_tips]]''.<br />
<br />
''For more documentation, see'':<br />
<br />
* [http://xmonad.org/intro.html Building xmonad]<br />
* [http://xmonad.org/contrib.html Configuring and extending xmonad]<br />
* [http://xmonad.org/xmonad-docs/xmonad-contrib/ Extension documentation]<br />
<br />
==When I start xmonad, nothing happens.==<br />
<br />
Don't panic, this is expected behavior. XMonad is a minimal window manager, meaning it doesn't set a background, start a status bar, display a splash screen or play a soothing sound effect when it starts up. Once xmonad has started, the only thing it does is listen for your first command. Try pressing mod-shift-enter (that is Alt, Shift, and Enter pressed at the same time) to bring up an xterm. Once the xterm appears, use it to read xmonad's man page or point a web browser at http://xmonad.org/tour.html. If no xterm appears, see if any other advice on this page applies.<br />
<br />
==Installation==<br />
<br />
===What build dependencies does xmonad have?===<br />
<br />
The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad hackage page for xmonad] lists all dependencies, including:<br />
<br />
* Standard Haskell libraries (you might already have these installed):<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal Cabal]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mtl mtl]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unix unix]<br />
<br />
* Haskell X11 bindings:<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/X11 X11]<br />
<br />
* C libraries:<br />
** libX<br />
** libXext<br />
** libXinerama<br />
<br />
You likely have these already if you've built any programs for X.<br />
<br />
xmonad is also availble pre-packaged for many distributions:<br />
<br />
* [http://www.openbsd.org/cgi-bin/cvsweb/ports/x11/xmonad/ OpenBSD]<br />
* [http://pkgsrc.se/wip/xmonad NetBSD]<br />
* [http://www.freshports.org/x11-wm/xmonad/ FreeBSD]<br />
* [http://packages.gentoo.org/package/xmonad Gentoo]<br />
* [http://packages.debian.org/sid/xmonad Debian]<br />
* [http://packages.ubuntu.com/xenial/xmonad Ubuntu]<br />
* [http://aur.archlinux.org/packages.php?do_Details=1&ID=10593 Arch]<br />
* [http://loupgaroublond.blogspot.com/2007/12/how-to-install-your-very-own-xmonad.html Fedora]<br />
* [http://recipes.gobolinux.org/r/?list=XMonad Gobo]<br />
* [http://nix.cs.uu.nl/nixos/ NixOS]<br />
* [http://codex.sourcemage.org/stable/windowmanagers/xmonad/ Source Mage]<br />
* [http://code.haskell.org/~arossato/xmonad-slack/ Slackware]<br />
<br />
Using your distro package is almost always preferred.<br />
<br />
===Can I install without root permission?===<br />
<br />
Yes, the Haskell libraries that xmonad depends on can all by<br />
installed in the user package database. Simply append --user <br />
to the install phase:<br />
<br />
$ runhaskell Setup.hs install --user<br />
<br />
The library will be registered in your ~/.ghc/ database.<br />
<br />
===How can I use xmonad with a display manager? (xdm, kdm, gdm)===<br />
<br />
The simplest way is to create or modify your ~/.xsession file to run<br />
xmonad. If you don't already have a .xsession, the minimal example<br />
looks like:<br />
<br />
xmonad<br />
<br />
This requires that the ghc and the xmonad executable (or a symlink to them) are in a<br />
directory in the display manager $PATH environment. Alternatively, you can use the full path to xmonad and set ghc's path systemwide. If you do this, you'll also have to change the mod-q binding to use /path/to/xmonad and restart X to have xmonad use the new mod-q (first time only) since the mod-q binding calls xmonad to recompile itself. (See mod-q doesn't work section below.)<br />
<br />
People using 'startx' can use these example [http://code.haskell.org/XMonadContrib/scripts/xinitrc xinitrc] and [http://code.haskell.org/XMonadContrib/scripts/run-xmonad.sh run-xmonad] scripts.<br />
<br />
If you are using xdm, you're done. Login and enjoy xmonad.<br />
<br />
If you're using kdm or gdm (KDE and GNOME's display mangers, respectively),<br />
you're almost done. When logging in, select the entry that says "xsession"<br />
or "default session" from the menu in order to use your ~/.xsession to<br />
start xmonad.<br />
<br />
Alternatively, if you want a menu entry specifically for xmonad, create a<br />
file named "xmonad.desktop" in your /usr/share/xsessions (location varies<br />
by distribution) directory. For example:<br />
<br />
[Desktop Entry]<br />
Encoding=UTF-8<br />
Name=xmonad<br />
Comment=This session starts xmonad<br />
Exec=/usr/local/bin/xmonad<br />
Type=Application<br />
<br />
Replace the "Exec=..." line with the actual path to your xmonad executable,<br />
and you should be able to login by selecting "xmonad" as a session from the<br />
menu in gdm/kdm.<br />
<br />
For instructions on using gdm to launch a full GNOME session with xmonad as<br />
the window manager<br />
[http://haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome#Starting_GNOME_with_xmonad read this].<br />
<br />
===Compiling xmonad on PowerPC and compiler is not interactive===<br />
<br />
If you have ghc installed and are trying to compile xmonad and your compiler <br />
complains about not being interactive, never fear. To compile Setup.hs simply type:<br />
<br />
ghc --make Setup.hs -o Setup<br />
<br />
Now you can:<br />
<br />
./Setup configure<br />
./Setup build<br />
sudo ./Setup install<br />
<br />
If during the build process ghc complains about the "impossible<br />
happening", and mentions that you should change something to "-fvia-C",<br />
just edit the *.cabal file replacing the line that sets the arguments<br />
for ghc, changing "-fasm" to "-fvia-C".<br />
<br />
=== How do I uninstall xmonad? ===<br />
<br />
If you have installed xmonad using your package manager, then just use it.<br />
The following applies if you have built xmonad from source code (either darcs or stable release). Let's assume you've installed xmonad to <br />
<br />
the <code>$PREFIX</code> (that is, gave <code>--prefix=$PREFIX</code> argument to <code>Setup.lhs configure</code>). If unsure, try your <br />
<br />
<code>$HOME</code> and <code>/usr/local</code> as <code>$PREFIX</code>.<br />
<br />
rm -f $PREFIX/bin/xmonad<br />
rm -rf $HOME/.xmonad<br />
rm -rf $PREFIX/lib/xmonad-$VERSION<br />
# If you have installed XMonadContrib:<br />
rm -rf $PREFIX/lib/xmonad-contrib-$VERSION<br />
<br />
If you have installed xmonad 0.5 or newer, also run<br />
ghc-pkg unregister xmonad<br />
# If you have installed XMonadContrib:<br />
ghc-pkg unregister xmonad-contrib<br />
<br />
Do not forget to purge that evil source code!<br />
<br />
=== not found errors or changes to xmonad.hs won't take effect ===<br />
<br />
Ensure that ghc, and the xmonad executable are both in the environment PATH from which you start X. Alternatively symlink them to locations already in the PATH. <code>ghc-pkg list</code> should show ghc, xmonad, X11, etc. without brackets, e.g. {xmonad} is bad. <code>ghc-pkg check</code> will tell you if you have inconsistent dependencies or other registration problems.<br />
<br />
The mod-q action calls the xmonad binary to recompile itself, so if your display manager is starting it with /path/to/xmonad you'll also have to edit your xmonad.hs mod-q binding to use the full path and restart X (or in newer versions use 'xmonad --restart') to restart xmonad with the new mod-q full path binding.<br />
<br />
'''If you recently changed ghc versions''' see [[#Upgraded GHC and now xmonad xmonad-contrib etc are not found]]<br />
<br />
===Configuring xmonad requires GHC, which is 200MB!===<br />
<br />
Yes. You can use [http://braincrater.wordpress.com/2008/09/17/xmonad-light-08-released/ xmonad-light], which allows some of the basic configurations, but if you really want to get the best xmonad experience, you need GHC.<br />
<br />
===Installing xmonad in a sandbox===<br />
<br />
This is possible. However ghc needs to know where the sandbox is, so that your configuration can be recompiled. The best way is to set the environment variable GHC_PACKAGE_PATH to /path/to/ghc/db (where you actually started the sandbox).<br />
<br />
==Configuration==<br />
<br />
===How do I configure xmonad?===<br />
<br />
By creating and editing the ~/.xmonad/xmonad.hs file, a Haskell source file.<br />
<br />
You can use any Haskell you want in this module. The xmonad-contrib package contains many [http://xmonad.org/xmonad-docs/xmonad-contrib/ extension modules] to make customizing xmonad easier. To have your changes take effect, save the xmonad.hs and either restart (mod-q) or exit X and log back in.<br />
<br />
[[Xmonad/Config_archive|Example configurations]] are available on the wiki.<br />
<br />
For extensive information on configuring, see the links at the top of this page, and [http://haskell.org/haskellwiki/Xmonad/General_xmonad.hs_config_tips the configuration tips] page.<br />
<br />
===Rebinding the mod key (Alt conflicts with other apps; I want the ___ key!)===<br />
<br />
xmonad uses 'alt', actually mod1, as the default modifier. You may<br />
bind to other mod keys by editing your xmonad.hs modMask value, or by<br />
using xmodmap to rebind a key to mod1. The apple command key can be<br />
rebound to mod1 in this way. Use xmodmap to find what key your mod1<br />
is bound to, as well.<br />
<br />
You can rebind the Caps Lock key, to mod, if you wish. See this<br />
[http://lists.suckless.org/dwm/0706/2715.html mailing list item].<br />
<br />
If your new key binding doesn't appear to work, double check it doesn't<br />
clash with an existing binding.<br />
<br />
An example, binding to the mod4 (often 'Win') key:<br />
<br />
<haskell><br />
import XMonad<br />
<br />
main = xmonad defaultConfig<br />
{ modMask = mod4Mask<br />
, terminal = "urxvt"<br />
}<br />
</haskell><br />
<br />
===Multi head and workspaces (desktops)===<br />
See also [[#Multi_head_or_xinerama_troubles|xinerama troubles]] if your multi-head setup doesn't behave as described below.<br />
<br />
XMonad's defaults with multiple monitors may seem confusing and chaotic until explained and illustrated. First we'll look at how things work by default, then at common workspace keybinding customizations.<br />
<br />
To ''focus'' visible workspaces rather than ''swapping'' their screens modify your keybindings as shown in [[#Replacing greedyView with view|the next section below]]. See the section about [[#Other multi head customizations|other customizations]] to give each monitor its own set of workspaces.<br />
<br />
The xmonad man page nicely summarizes how multi-head works by default:<br />
:When running with multiple monitors (Xinerama, TwinView, xrandr), each screen has exactly one workspace visible. Pressing '''<code>mod-{w,e,r}</code>''' switches the focus between screens, while pressing '''<code>shift-mod-{w,e,r}</code>''' moves the current window to that screen. When xmonad starts, workspace 1 is on screen 1, workspace 2 is on screen 2, etc. When switching workspaces to one that is already visible, the current and visible workspaces are swapped.<br />
<br />
'''visible workspaces swap''' (default keybindings): When you have multiple workspaces visible and mod-n to a different ''visible'' workspace, your current one swaps with the other one. We'll see how to change that below, if you don't like the swapping -- simply change 'greedyView' to 'view' in your workspace key bindings. To illustrate with two monitors, using the convention "[1*] [3 ]" to mean workspaces 1 and 3 are visible with left monitor the currently active one:<br />
<br />
<pre><br />
-- 'greedyView' (default) workspace switching (easier to swap visible workspaces)<br />
<br />
-- Typical keystrokes are mod-{w,e,r} to a screen, then mod-N a workspace<br />
<br />
[1*] [3 ] -- mod-3 --> [3*] [1 ] -- mod-e, mod-4 --> [3 ] [4*]<br />
<br />
[3 ] [4*] -- mod-w, mod-4 --> [4*] [3 ]<br />
</pre><br />
<br />
'''my focus moves instead''' (custom workspace switching bindings): By replacing the 'greedyView' function with 'view' in the workspace switching bindings you can have your focus shift to the monitor displaying the given workspace, instead of having that workspace 'brought to you.' (See the next section for examples of how to do this.) For example:<br />
<br />
<pre><br />
-- 'view' workspace switching <br />
<br />
-- (easier to focus another visible workspace, harder to swap)<br />
<br />
[1*] [3 ] -- mod-3 --> [1 ] [3*] -- mod-4 --> [1 ] [4*]<br />
<br />
[1 ] [4*] -- mod-w --> [1*] [4 ] -- mod-4 --> [1 ] [4*]<br />
</pre><br />
<br />
<hask>view</hask> users may also want to add key bindings such as shiftNextScreen and swapNextScreen from the xmonad-contrib extension [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-CycleWS.html XMonad.Actions.CycleWS].<br />
<br />
====Replacing greedyView with view====<br />
Here is an example of changing your workspace switching bindings to use <hask>view</hask> rather than <hask>greedyView</hask> '''using XMonad.Util.EZConfig's additionalKeysP:''' <br />
<br />
(See [http://hackage.haskell.org/packages/archive/xmonad-contrib/latest/doc/html/XMonad-Util-EZConfig.html contrib docs for EZConfig] for more details)<br />
<br />
<haskell><br />
import XMonad<br />
-- skipped<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
main = do<br />
xmonad $ defaultConfig {<br />
workspaces = myWorkspaces<br />
-- skipped<br />
} `additionalKeysP` myKeys<br />
<br />
myWorkspaces = ["1","2","3","4","5","6","7","8","9"]<br />
<br />
myKeys = [<br />
<br />
-- other additional keys<br />
<br />
] ++ -- (++) is needed here because the following list comprehension<br />
-- is a list, not a single key binding. Simply adding it to the<br />
-- list of key bindings would result in something like [ b1, b2,<br />
-- [ b3, b4, b5 ] ] resulting in a type error. (Lists must<br />
-- contain items all of the same type.)<br />
<br />
[ (otherModMasks ++ "M-" ++ [key], action tag)<br />
| (tag, key) <- zip myWorkspaces "123456789"<br />
, (otherModMasks, action) <- [ ("", windows . W.view) -- was W.greedyView<br />
, ("S-", windows . W.shift)]<br />
]<br />
</haskell><br />
<br />
'''For use with additionalKeys or default binding style:'''<br />
<br />
<haskell><br />
-- as above<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[((m .|. mod1Mask, k), windows $ f i) -- Replace 'mod1Mask' with your mod key of choice.<br />
| (i, k) <- zip myWorkspaces [xK_1 .. xK_9]<br />
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]<br />
</haskell><br />
<br />
====Other multi head customizations====<br />
By default, XMonad doesn't link all your monitor screens into one workspace like Gnome and friends, neither does it use a model like dwm's where each monitor has its own set of workspaces. To set up dwm style workspaces for each screen, see (0.9 or greater) [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IndependentScreens.html Layout.IndependentScreens]<br />
<br />
==== Screens are in wrong order ====<br />
With xmonad-contrib newer than 0.8.*, (darcs version), see also<br />
[http://haskell.org/haskellwiki/Xmonad/Notable_changes_since_0.8 XMonad.Actions.PhysicalScreens]<br />
<br />
Sometimes drivers don't do what you want, and your screens left to right are something<br />
weird like 1 0 2, so your mod-{w,e,r} bindings are messed up. Your driver may provide a utility to set screen order, but if not, or if you just don't want to mess with<br />
it, here's how to rebind the screen switching bindings:<br />
<br />
Note that if you choose not to use myKeys for the key lists appended together with <hask>++</hask> you will need to add parentheses to get something in the form <hask>`additionalKeys` ( [......] ++ [.......] )</hask>.<br />
<br />
'''Using XMonad.Util.EZConfig's additionalKeysP:'''<br />
<haskell><br />
import XMonad<br />
-- skipped<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
main = do<br />
xmonad $ defaultConfig {<br />
-- skipped<br />
} `additionalKeysP` myKeys<br />
<br />
modm = mod4Mask<br />
<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[ (mask ++ "M-" ++ [key], screenWorkspace scr >>= flip whenJust (windows . action))<br />
| (key, scr) <- zip "wer" [1,0,2] -- was [0..] *** change to match your screen order ***<br />
, (action, mask) <- [ (W.view, "") , (W.shift, "S-")]<br />
]<br />
</haskell><br />
<br />
'''Using default key binding method or XMonad.Util.EZConfig's additionalKeys:'''<br />
<haskell><br />
-- as above<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[((m .|. mod1Mask, key), screenWorkspace sc >>= flip whenJust (windows . f)) -- Replace 'mod1Mask' with your mod key of choice.<br />
| (key, sc) <- zip [xK_w, xK_e, xK_r] [1,0,2] -- was [0..] *** change to match your screen order ***<br />
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]<br />
</haskell><br />
<br />
===I don't want the focus to follow the mouse===<br />
<br />
Easy. There is a setting focusFollowsMouse in the xmonad.hs file; set it to False and restart with mod+q.<br />
<br />
=== How do I configure pointer-follows-focus? ===<br />
If you are using > xmonad-0.7, you can use the already defined XMonad.Actions.UpdatePointer:<br />
<haskell><br />
myLogHook = dynamicLogWithPP .... >> updatePointer<br />
</haskell><br />
<br />
For xmonad-0.7, in your config, import [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-Warp.html XMonad.Actions.Warp] from Xmonad contrib and <br />
<br />
add this function:<br />
<haskell><br />
pointerFollowsFocus :: Rational -> Rational -> X ()<br />
pointerFollowsFocus h v = do<br />
dpy <- asks display<br />
root <- asks theRoot<br />
withFocused $ \w -> do<br />
wa <- io $ getWindowAttributes dpy w<br />
(sameRoot,_,w',_,_,_,_,_) <- io $ queryPointer dpy root<br />
if (sameRoot && w == w') then<br />
return ()<br />
else<br />
io $ warpPointer dpy none w 0 0 0 0<br />
(fraction h (wa_width wa)) (fraction v (wa_height wa))<br />
where fraction x y = floor (x * fromIntegral y)</haskell><br />
<br />
Then set the logHook in your config to &ldquo;pointerFollowsFocus <i>x</i> <i>y</i>&rdquo;. If you already have a logHook, append &ldquo; <br />
<br />
>> pointerFollowsFocus <i>x</i> <i>y</i>&rdquo; to it. For example:<br />
<haskell>myLogHook = dynamicLogWithPP defaultPP { ppCurrent = xmobarColor "#60ff45" ""<br />
, ppVisible = xmobarColor "#fffff0" "" } >> pointerFollowsFocus 1 1</haskell><br />
<br />
===Does xmonad support a statusbar?===<br />
<br />
Yes. The Hooks.DynamicLog and Hooks.ManageDocks modules are your friends for this purpose. <br />
<br />
Arbitrary external programs may be used as a statusbar. See for example<br />
[https://github.com/robm/dzen dzen] or<br />
[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmobar xmobar], an<br />
extensible status bar.<br />
<br />
xmonad lets you use any application as a 'statusbar', as long as it is<br />
visible in a given 'gap' on the screen, and has the override-redirect<br />
property set to true. Many status bar/dock programs already set this<br />
property, for example, dzen. To set other applications, you can<br />
sometimes use normal X resources. For example, to use xclock, launch it<br />
with <br />
<br />
xclock -digital -xrm '*overrideRedirect: True' -geometry 1024x30+0+0<br />
<br />
'''If, like xclock, your app doesn't set wm strut properties''', so that ManageDocks and avoidStruts automatically leaves a gap, '''you can do it manually. Import the Layout.Gaps module and, set a gap of, e.g. (30,0,0,0), in xmonad.hs.''' A similar trick can be done for xsystray.<br />
<br />
Also see the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Monitor.html Layout.Monitor] module.<br />
<br />
You can see screenshots of statusbars on [[Xmonad/Screenshots|the screenshots page]].<br />
<br />
You can also use [http://haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome Gnome] or KDE trays and menus with xmonad. The [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-EwmhDesktops.html Hooks.EwmhDesktops], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Desktop.html Config.Desktop], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Gnome.html Config.Gnome], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Kde.html Config.Kde], etc. modules make desktop environment status bars more useful with xmonad.<br />
<br />
To display xmonad logHook output in gnome-panel, see [http://uhsure.com/xmonad-log-applet.html xmonad log applet].<br />
<br />
==== [https://github.com/robm/dzen dzen] status bars ==== <br />
<br />
xmonad's XMonadContrib library comes with a<br />
really easy function for getting a status bar working with dzen. To use<br />
it, simply have a ~/.xmonad/xmonad.hs containing:<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.DynamicLog<br />
<br />
-- 0.9 main:<br />
main = xmonad =<< dzen defaultConfig<br />
-- 0.8.1 main:<br />
main = dzen xmonad<br />
</haskell><br />
which will launch xmonad with dzen2 if found, set up with nice colours<br />
and workspace information. See [[Xmonad/Config_archive/Don%27s_xmonad.hs|Don's config example]] for more information or [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#v%3Adzen DynamicLog dzen's] documentation.<br />
<br />
There is an excellent command-line option and in-text command reference for the SVN version of dzen2 [http://dzen.geekmode.org/dwiki/doku.php?id=dzen:command-and-option-list here]<br />
<br />
====gkrellm or other monitors that aren't bars====<br />
<br />
Gkrellm does not behave like a dock by default. However, there is an option in <code>.gkrellm2/user_config</code> which says <code>dock = 0</code>. If you set it to 1 xmonad will recognize gkrellm as a dock. <br />
<br />
Unfortunately gkrellm usually won't hide under other windows regardless of any combination of <code>above</code> and <code>below</code> options in said config file. Opening and closing the gkrellm config usually resolves this (right click the top of gkrellm and select Configure.. from the menu).<br />
<br />
In xmonad-darcs (will release as xmonad-0.9) the Layout.Monitor module may be helpful.<br />
<br />
====Make space for a panel dock or tray====<br />
<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageDocks.html ManageDocks] makes it possible for Xmonad to work with panels in the way they expect, automatically leaving the appropriate amount of room for them at the edges of the screen. ''ManageDocks'' has been enabled in the example configuration above. By itself, configuration looks like this:<br />
<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.ManageDocks<br />
main = xmonad defaultConfig<br />
{ manageHook = manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ layoutHook defaultConfig<br />
}<br />
</haskell><br />
<br />
=== Make new windows appear 'below' rather than 'above' the current window ===<br />
See also the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-InsertPosition.html Hooks.InsertPosition] module for placement hooks other than W.SwapDown to use in stack order manageHooks.<br />
<br />
==== Force a few tiled windows down ====<br />
If you only need to position a few windows below rather than above, and can specify window properties that will avoid matching floating dialogs, etc. then adding a few swapDown manageHooks (or similar from Hooks.InsertPosition referenced above) should do the trick.<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
main = xmonad defaultConfig<br />
{ manageHook = composeAll<br />
[ resource =? "downer" --> doF W.swapDown<br />
, title =? "obnoxious window" --> doF W.swapDown<br />
, className =? "MPlayer" --> doFloat<br />
]<br />
}<br />
</haskell><br />
<br />
==== Limit windows forced down by using composeOne ====<br />
To position as many windows as possible below the focus while avoiding problems with z-order while using multiple floating windows, use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html Hooks.ManageHelpers] composeOne and (-?>) in place of composeAll and (-->) to specify hooks that only fire if earlier ones have not matched. You can use this to add swapDown last in your composeOne list, so that it's applied only to windows that haven't earlier been floated or identified as transient or dialog windows.<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageDocks (checkDock)<br />
import XMonad.Hooks.ManageHelpers<br />
<br />
main = xmonad defaultConfig<br />
-- no dialogs, gimp or mplayer windows will get swapped down<br />
-- since they matched earlier in the composeOne list<br />
{ manageHook = composeOne<br />
[ checkDock -?> doIgnore -- equivalent to manageDocks<br />
, isDialog -?> doFloat<br />
, className =? "Gimp" -?> doFloat<br />
, className =? "MPlayer" -?> doFloat<br />
, return True -?> doF W.swapDown<br />
]<br />
}<br />
</haskell><br />
<br />
For a more complex composeOne example, see [http://mauke.ath.cx/stuff/xmonad/xmonad.hs mauke's manageHooks].<br />
<br />
==== Force all new windows down ====<br />
(<hask>doF W.swapDown</hask> is the same as using <hask>insertPosition Lower ____</hask>.) To avoid problems with floating window dialogs it's highly recommended to also add an <hask>isDialog</hask> hook as shown below. Adding <hask>doF W.swapDown</hask> to your manageHook will result in new windows being inserted below the focus; for floating windows this means behind the current window. A minimal config would look like this:<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageHelpers<br />
<br />
main = xmonad defaultConfig<br />
{ manageHook = isDialog --> doF W.shiftMaster <+> doF W.swapDown<br />
-- <br />
-- To prevent unwanted swaps on other workspaces when using<br />
-- this hook with other doShift hooks, make sure to put<br />
-- doF W.swapDown furthest to the right, or last in a <br />
-- composeAll hook list<br />
}<br />
</haskell><br />
<br />
'''Warning:''' <code>doF W.swapDown</code> without restrictions will result in new floating windows popping up ''behind'' focused floating windows, and undesirable focus changes when starting and quickly destroying a window. It is better to only match specific windows to swapDown or use composeOne as shown above.<br />
<br />
==== Avoid the master window, but otherwise manage new windows normally ====<br />
Note that this is not a good solution for people who use floating windows, since many operations on floats put the floating window into the master position. Some transient windows will be swappedDown to appear below the floating parent unless the user keeps a tiled window in master and floating windows lower in the stack at all times. As with swapDown it's best to use it only on specific windows or at the end of a composeOne list if you use floating windows very often.<br />
<br />
<haskell><br />
-- <snip> <br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageHelpers<br />
-- <snip><br />
<br />
myManageHook = fmap not isDialog --> doF avoidMaster<br />
<br />
-- or if you have other stuff in the managehook, more like<br />
-- myManageHook = (otherStuff) <+> (fmap not isDialog --> doF avoidMaster)<br />
<br />
avoidMaster :: W.StackSet i l a s sd -> W.StackSet i l a s sd<br />
avoidMaster = W.modify' $ \c -> case c of<br />
W.Stack t [] (r:rs) -> W.Stack t [r] rs<br />
otherwise -> c<br />
</haskell><br />
<br />
=== Prevent new windows from stealing focus ===<br />
Use a <hask>doF W.focusDown</hask> manageHook on selected windows, or even<br />
on all windows, similar to the swapDown examples above.<br />
<br />
For an avoidMaster that keeps the focus with the master instead of focusing<br />
the newly created window replace <hask>W.Stack t [] (r:rs) -> W.Stack t [r] rs</hask><br />
with <hask>W.Stack t [] (r:rs) -> W.Stack r [] (t:rs)</hask> in the above avoidMaster code.<br />
<br />
===Firefox annoyances===<br />
<br />
====Stop Firefox from taking focus while using EwmhDesktops====<br />
If one uses EWM Hints support, firefox is enabled to choose when you view its workspace, i.e. if you open links from emails or irc or whatever. If you find it annoying... In about:config (vimperator :preferences!) set <code>browser.tabs.loadDivertedInBackground</code> to True to be able to load urls while working elsewhere, then browse them all later when ''you'' choose to shift to the firefox workspace. Also ubuntu users may need to disable the <code>ubufox</code> extension.<br />
<br />
====Firefox's annoying popup downloader====<br />
<br />
Some applications, notably Firefox 1 and 2, create transient windows not<br />
set with the transient property. (e.g. firefox's download manager). When<br />
these windows appear, they can take focus and be annoying. For the case<br />
of firefox, the 'Download Statusbar' extension is useful for disabling<br />
this annoying UI feature.<br />
<br />
=== Watch fullscreen flash video ===<br />
Since approximately November 2010, the stock configuration no longer causes flash windows to immediately disappear. However, tiling flash's windows is often not what you want. Try some or all of the following hooks.<br />
<br />
For browser plugins and most apps, including mplayer floated by manage hook (as in the default manageHook) the following setup allows normal toggling of fullscreen. A few mplayer versions are configured to use a different fullscreen method, but they can be made to work with the isFullscreen hook by adding a line <code>fstype=none</code> to ~/.mplayer/config, or using the <code>-fstype=none</code> flag from the command line. See also the end of the faq regarding using handleEventHook instead.<br />
<br />
Add one of the following manageHooks, and modify layoutHook with smartBorders:<br />
<haskell><br />
-- other imports<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageHelpers<br />
import XMonad.Layout.NoBorders<br />
<br />
main = xmonad defaultConfig {<br />
-- skipped<br />
, layoutHook = smartBorders (yourExistingLayoutHook) -- Don't put borders on fullFloatWindows<br />
, manageHook = myManageHooks<br />
}<br />
<br />
myManageHooks = composeAll<br />
-- Allows focusing other monitors without killing the fullscreen<br />
-- [ isFullscreen --> (doF W.focusDown <+> doFullFloat)<br />
<br />
-- Single monitor setups, or if the previous hook doesn't work<br />
[ isFullscreen --> doFullFloat<br />
-- skipped<br />
]<br />
</haskell><br />
If you have multi-head and the focusDown hook doesn't work for you, in darcs xmonad/xmonad-contrib (greater than 0.9.1) XMonad.Hooks.EwmhDesktops has a fullscreenEventHook that is also worth a try. Add it to any existing handleEventHook with <+>, or simply use it as your handleEventHook if you don't already have one. This also is useful for people who prefer tiling mplayer when not fullscreened, or use totem, vlc, or other players that require something like fullscreenEventHook to work at all.<br />
<br />
=== Floating a window or sending it to a specific workspace by default ===<br />
<br />
See [[Xmonad/General_xmonad.hs_config_tips | General xmonad.hs config tips]] regarding manageHook, and the section [[#I need to find the class title or some other X property of my program | here]] about 'xprop' for this.<br />
<br />
===Startup programs===<br />
<br />
You may launch programs at startup in the usual X manner: by adding<br />
them to your .xsession or .Xinitrc. For example, the following<br />
.xsession file launches xpmroot to<br />
set the background image, xmodmap to rebind caps lock to ctrl. It<br />
then launches a status bar program with dzen, before finally<br />
launching xmonad:<br />
<br />
# .xsession<br />
xpmroot ~/.bg/407511721_eb8559457c_o.xpm &amp;<br />
xrdb -merge .Xresources<br />
<br />
xmodmap -e "remove Lock = Caps_Lock"<br />
xmodmap -e "keysym Caps_Lock = Control_L"<br />
xmodmap -e "add Control = Control_L"<br />
<br />
status | dzen2 -ta r -fg '#a8a3f7' \<br />
-bg '#3f3c6d' \<br />
-fn '-*-terminus-medium-r-normal--16-*' \<br />
-e "button1=exec:xterm" &amp; <br />
urxvt &amp;<br />
<br />
$HOME/bin/xmonad<br />
<br />
You may also launch applications from your xmonad.hs, using startupHook, however this runs each time xmonad is restarted with mod-q. Also in > xmonad-0.8 see spawnPid, mkSpawner, spawnOn.<br />
<br />
Use manageHook to arrange your programs on different workspaces by matching various window properties such as className, appName (resource), title, or role.<br />
<br />
===Using floating windows===<br />
Use the regular swap or focus up and down to navigate them, and regular mod-enter to raise a window to the front. For a mod-enter binding, the darcs shiftMaster works better than swapMaster if you use multiple floats over tiled windows. See also this<br />
[[#Force_all_new_windows_down|swapDown manage hook warning]] above. If you use that manageHook on all windows you will create new floats behind existing ones. If you use lots of floats for some reason for better float usability see SimpleFloat layout, FloatKeys, Hooks.Place, and Config.Bluetile in xmonad-contrib.<br />
<br />
===Setting the X cursor===<br />
<br />
By default xmonad doesn't set a particular X cursor, which usually<br />
means the default X cursor will be used by the system. To set your<br />
own custom cursor, use the xsetroot program, as follows, from your<br />
startup file, i.e. .xinitrc, .xsession, display manager startup or<br />
.Desktop files:<br />
<br />
# For example, a nice left-pointing arrow head cursor<br />
<br />
xsetroot -cursor_name left_ptr<br />
<br />
If you have development headers for X11, other cursors can be found in /usr/include/X11/cursorfont.h<br />
<br />
Note that some display managers, such as "slim", don't unset the changes<br />
they make to the cursor when the window manager starts. This can be worked<br />
around by setting the cursor, as above.<br />
<br />
=== Removing the borders around mplayer ===<br />
<br />
You can also use the fullscreen layout, with the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-NoBorders.html NoBorders] smartBorders layout modifier, which automatically takes care of most cases.<br />
<br />
To add 'smartBorders' to the default tiling modes:<br />
<haskell><br />
import XMonad<br />
import XMonad.Layout.NoBorders<br />
<br />
main = xmonad $ <br />
defaultConfig<br />
{ layoutHook = smartBorders $ layoutHook defaultConfig<br />
-- other fields like terminal, modMask, etc.<br />
}<br />
</haskell><br />
<br />
<br />
<br />
You can also remove borders with a key binding using [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-NoBorders.html Actions.NoBorders] extension. There's drawback: you need manually remove border any time you launch mplayer.<br />
<br />
Although this action should be able to be automated, unfortunately you cannot<br />
currently use manageHook for this purpose. That's because borders are drawn<br />
''after'' runManageHook is executed (see Operations.hs for details).<br />
<br />
Alternatively you can manually move the mplayer window 1 pixel to the left and<br />
one pixel up by importing XMonad.Actions.FloatKeys and adding a keybinding<br />
similar to ((modm, xK_b), withFocused (keysMoveWindow (-1,-1)). (I have not<br />
tested yet if this can be used in combination with the manageHook.)<br />
<br />
===I need to find the class title or some other X property of my program===<br />
<br />
When using XMonad.Layout.IM, ManageHooks, XMonad.Actions.WindowGo, or several other modules you need to specify detailed information about a window's properties.<br />
<br />
See below for a script to nicely format output from the <tt>xprop</tt> program discussed in detail in this FAQ.<br />
<br />
Otherwise, you can generally find what you need by splitting your screen between the window and a terminal; in the terminal, run <tt>xprop WM_CLASS</tt> or the like, and then click on the window. xprop will print out quite a bit of useful information about the window. <br />
* '''resource''' (also known as '''appName''') is the first element in WM_CLASS(STRING)<br />
* '''className''' is the second element in WM_CLASS(STRING)<br />
* '''title''' is WM_NAME(STRING)<br />
<br />
For example, in <code> WM_CLASS(STRING) = "emacs", "Emacs" </code> -- "emacs" is resource (appName), "Emacs" is className.<br />
<br />
(Applications may change the title after window creation, before xprop sees it. If possible, use resource or class in such cases.) stringProperty "WM_WINDOW_ROLE" can also be useful.<br />
<br />
Sample output might look like:<br />
<br />
<pre>_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0<br />
XdndAware(ATOM) = BITMAP<br />
WM_STATE(WM_STATE):<br />
window state: Normal<br />
icon window: 0x0<br />
WM_HINTS(WM_HINTS):<br />
Client accepts input or input focus: True<br />
Initial state is Normal State.<br />
window id # of group leader: 0xf600001<br />
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 257949716<br />
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL<br />
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0xf600013<br />
WM_CLIENT_LEADER(WINDOW): window id # 0xf600001<br />
_NET_WM_PID(CARDINAL) = 476661<br />
WM_LOCALE_NAME(STRING) = "en_US.utf8"<br />
WM_CLIENT_MACHINE(STRING) = "localhost"<br />
WM_NORMAL_HINTS(WM_SIZE_HINTS):<br />
program specified minimum size: 32 by 34<br />
program specified resize increment: 8 by 17<br />
program specified base size: 16 by 0<br />
window gravity: NorthWest<br />
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST<br />
WM_CLASS(STRING) = "emacs", "Emacs"<br />
WM_ICON_NAME(STRING) = "emacs@craft"<br />
_NET_WM_ICON_NAME(UTF8_STRING) = 0x45, 0x4d, 0x41, 0x43, 0x53<br />
WM_NAME(STRING) = "EMACS"<br />
_NET_WM_NAME(UTF8_STRING) = 0x45, 0x4d, 0x41, 0x43, 0x53<br />
</pre><br />
<br />
Note: the last several lines contain useful information like the CLASS and<br />
hinting information.<br />
<br />
==== What about other properties, such as WM_WINDOW_ROLE? ====<br />
Use <code>stringProperty</code> to extract string information, for<br />
example:<br />
<br />
<pre><br />
stringProperty "WM_WINDOW_ROLE" =? "presentationWidget" --> doFloat<br />
</pre><br />
<br />
For non-string properties, try [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html XMonad.Hooks.ManageHelpers].<br />
<br />
Consult the [http://xmonad.org/xmonad-docs/xmonad/XMonad-ManageHook.html XMonad.ManageHook] documentation for more information.<br />
<br />
==== A handy script to print out window information ====<br />
<br />
This script will print window information (if available) in formats usable within <tt>xmonad.hs</tt>. It is also included in the $src/XMonadContrib/scripts directory with<br />
darcs XMonadContrib (>= 0.10).<br />
<br />
#! /bin/sh<br />
exec xprop -notype \<br />
-f WM_NAME 8s ':\n title =\? $0\n' \<br />
-f WM_CLASS 8s ':\n appName =\? $0\n className =\? $1\n' \<br />
-f WM_WINDOW_ROLE 8s ':\n stringProperty "WM_WINDOW_ROLE" =\? $0\n' \<br />
WM_NAME WM_CLASS WM_WINDOW_ROLE \<br />
${1+"$@"}<br />
<br />
It works like <tt>xprop</tt>: by default you click on a window with the crosshairs, or you can specify windows using the <tt>-id</tt> or <tt>-name</tt> options. (The <tt>-root</tt> and <tt>-font</tt> selectors could be used, but are less than useful. Also, <tt>-frame</tt> is unlikely to do anything useful.)<br />
<br />
See [[Xmonad/General_xmonad.hs_config_tips#Matching_specific_windows_by_setting_the_resource_name_or_class|Matching specific windows by setting the resource name or class]] for how you can change what programs use for some of these strings.<br />
<br />
=== What is the xK_ value for this key? ===<br />
Pressing the key of interest while focusing a xev window gives useful information.<br />
To limit xev's output use something like:<br />
<br />
<code>xev | sed -ne '/^KeyPress/,/^$/p'</code><br />
<br />
A complete list can be found at [[Xmonad/Key_codes|XMonad key symbols]].<br />
<br />
=== How can I send a key sequence to a window? ===<br />
<br />
This can be useful when some application uses a hotkey that you<br />
want to use in XMonad, yet be able to send the application window the<br />
hotkey when needed.<br />
<br />
A solution is to use [http://www.semicomplete.com/projects/xdotool/ xdotool], <br />
which can (among other nifty things), send a fake keypress to the<br />
currently focused window. So, for instance, you can use the following<br />
keybinding to send Alt+L to the focused window by pressing Ctrl+Alt+L:<br />
<br />
, ((mod1Mask|controlMask, xK_l), spawn "xdotool key alt+l")<br />
<br />
[http://www.semicomplete.com/projects/xdotool/ xdotool] can also paste<br />
a line of ASCII text into the focused window. For instance, the<br />
following keybinding will insert the email address email@example.org<br />
each time the key Ctrl+Alt+e is pressed:<br />
<br />
, ((mod1Mask|controlMask, xK_e), spawn "xdotool text 'email@example.org'")<br />
<br />
The <code>XMonad.Util.Paste</code> module (in >= xmonad-contrib-0.9) defines functions to to the same with<br />
pure Haskell code.<br />
<br />
=== I don't use a statusbar, but I'd like to have layout displayed for some time when it changes ===<br />
<br />
Let's assume you have <hask>import qualified XMonad.StackSet as W</hask> in xmonad.hs.<br />
<br />
Add the following declaration somewhere in the toplevel:<br />
<haskell>curLayout :: X String<br />
curLayout = gets windowset >>= return . description . W.layout . W.workspace . W.current</haskell><br />
<br />
Then add the keybinding:<br />
<haskell><br />
, ((mod1Mask, xK_a ), sendMessage NextLayout >> (curLayout >>= \d->spawn $"xmessage "++d))<br />
</haskell><br />
<br />
You might want to change xmessage to the more friendly program, such as osd_cat, qt-dialog or dzen2.<br />
<br />
Another option is to use<br />
[http://www.xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ShowWName.html Layout.ShowWName] <br />
which has some user configurable options such as font, color and fade timings.<br />
<br />
More flexible way is to use <code>dynamicLogString</code> from <code>XMonad.Hooks.DynamicLog</code> (was added after 0.6 release), which can also display current workspace, window name, layout, and even arbitrary <hask>[X (Maybe String)]</hask>, and format them nicely, printing them to xmonad's stdout.<br />
<br />
===How can I make xmonad use UTF8?===<br />
<br />
TODO: is this still accurate? Doesn't xmonad-0.8 and greater always use UTF8 with no extra imports or configuration changes?<br />
<br />
Due to extensions like [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html DynamicLog], xmonad is capable of text outputting which is not by default but can be encoded in UTF8. Therefore, if you want to output non-ASCII characters, you can take advantage of the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-string System.IO.UTF8] module.<br />
<br />
For example using DynamicLog you can define its output [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#v%3AppOutput ppOutput] like his:<br />
<haskell><br />
import qualified System.IO.UTF8<br />
-- lots of other stuff<br />
ppLog = defaultPP<br />
{ ppOutput = \s -> do<br />
h <- openFile "/home/$USER/.xmonad/xmonad.log" WriteMode<br />
System.IO.UTF8.hPutStrLn h s<br />
hClose h<br />
}<br />
</haskell><br />
<br />
As it may not be ideal to reopen the file before every writing, you can just place the code somewhere else. See ray's config in xmonad's [[Xmonad/Config_archive|config archive]].<br />
<br />
===How do I use compositing with xmonad?===<br />
<br />
Xmonad has the ability to use some compositing features yet still be actually useable ;-). For example, some really nice transparency can be used with a composite aware app like urxvt and xcompmgr. <br />
<br />
First enable compositing in your X server configuration by including the following in your xorg.conf<br />
<br />
<pre><br />
Section "Extensions"<br />
Option "Composite" "enable"<br />
EndSection<br />
</pre><br />
<br />
restart the X server and confirm it's working with xdpyinfo | grep Composite. If it returns Composite, then good...<br />
<br />
Include this in ~/.Xdefaults<br />
<br />
<pre><br />
URxvt.depth: 32<br />
URxvt*background: rgba:0000/0000/0000/cccc<br />
</pre><br />
<br />
this specifies that urxvt uses 32 bit colors and uses a transparent black background. The four c's specify the amount of alpha with ffff being full black and 0000 being fully transparent. You can also use the fading and blurRadius resources to give some nice effects in the transparency. see man urxvt.<br />
<br />
finally you need to fire up xcompgr so that this will all actually work. probably you'll want to include it in your ~/.xinitrc or ~/.xsession file:<br />
<br />
<pre><br />
xcompmgr -c &<br />
</pre><br />
<br />
the -c option provides a soft shadow around your windows. There are many options, see man xcompmgr. <br />
<br />
For an example with screenshots see andrewsw's config in the [[Xmonad/Config_archive|config archive]].<br />
<br />
On newer versions of XMonad, see also '''XMonad.Hooks.FadeInactive''' documentation.<br />
<br />
=== How do I find a function which does ...? ===<br />
<br />
[http://holumbus.fh-wedel.de/hayoo/hayoo.html Hayoo!] API search can be used to find existing functions within XMonad and XMonadContrib which do useful things. For example, the search string<br />
(next AND screen) package:xmonad<br />
will find all existing functions which mention moving to the next Xinerama screen.<br />
<br />
==Troubleshooting==<br />
<br />
===Multi head or xinerama troubles===<br />
====xmonad does not detect my multi-head setup====<br />
<br />
To diagnose the problem, execute the following on the command line:<br />
<br />
ghc -e Graphics.X11.Xinerama.compiledWithXinerama<br />
<br />
If the output is True, skip to the getScreenInfo test below. If the output is False, your Haskell X11 library was not built against Xinerama. This is true of old Debian and Ubuntu packages, and may also occur if you built from source.<br />
<br />
First, be sure that the Xinerama development headers are installed (libxinerama-dev in Debian and Ubuntu).<br />
<br />
Next, check the configure output for the Haskell X11 library for the following lines (If using cabal: cabal install X11 -v --reinstall):<br />
<br />
checking X11/extensions/Xinerama.h usability... yes<br />
checking X11/extensions/Xinerama.h presence... yes<br />
checking for X11/extensions/Xinerama.h... yes<br />
<br />
If any of these lines end in "no", the Xinerama headers are not installed. If the lines end in "yes", execute:<br />
<br />
runghc Setup clean<br />
runghc Setup configure --user --prefix=$HOME<br />
runghc Setup build<br />
runghc Setup install<br />
<br />
In the X11, xmonad and xmonad-contrib source directories. Try the compiledWithXinerama diagnostic again, this time it should return True. As always, execute "xmonad --recompile" when reinstalling any part of xmonad.<br />
<br />
If compiledWithXinerama is True and multi-head still doesn't work, execute "xmonad --recompile" and press mod-q. If the problem persists, execute this command:<br />
<br />
ghc -e "Graphics.X11.openDisplay [] >>= Graphics.X11.Xinerama.getScreenInfo"<br />
<br />
Here is a sample output from a system with two 1280 by 1024 monitors, oriented side by side:<br />
<br />
[Rectangle {rect_x = 0, rect_y = 0, rect_width = 1280, rect_height = 1024}, Rectangle {rect_x = 1280, rect_y = 0, rect_width = 1280, rect_height = 1024}]<br />
<br />
Check to see whether there is a Rectangle corresponding to each of your screens. If there is not, and the compiledWithXinerama diagnostic returns True, there may be a problem with your X server configuration. The most common one is having your monitors set to ''clone'' one another. See 'man xrandr', or, if using the proprietary nvidia drivers, 'nvidia-settings' to see how reconfigure them.<br />
<br />
Also, there can be two versions of the X11 haskell library installed, one of them built with Xinerama, and other without it. If XMonad is using the one built with Xinerama, and the output of the commands use the version without it, all these tests will work but these problems will persist. Check the output of ghc-pkg to see if there is more than one version of X11 installed.<br />
<br />
====Missing X11 headers====<br />
<br />
Your build will fail if you've not installed the X11 C library headers<br />
at some point. ./configure for the Haskell X11 library will fail. To<br />
install the X11 C libs:<br />
<br />
* debian<br />
<br />
apt-get install libx11-dev<br />
<br />
====X11 fails to find libX11 or libXinerama====<br />
<br />
Cabal has difficulty locating library directories on some<br />
platforms (such as the Mac or RHEL4). First, locate the<br />
directory that contains libX11.so (libX11.dylib on Mac OS<br />
X). Add the following line to the .cabal file for the<br />
package:<br />
<br />
extra-lib-dirs: /your/path/here/<br />
<br />
For example, on a 64 bit machine you might need to add:<br />
<br />
extra-lib-dirs: /usr/X11R6/lib/lib64<br />
<br />
You can also add the paths to your .buildinfo file, or set the<br />
LD_LIBRARY_PATH environment variable.<br />
<br />
====Something is weird with multi head windows or workspaces (desktops)====<br />
See [[#Multi head and workspaces (desktops)|Configuration: Multi head and workspaces]]<br />
<br />
===X Error of failed request: BadAccess (attempt to access private resource denied)===<br />
This message seen at xmonad's stdout when starting xmonad means that another window manager is already running. If the other WM was started from a DE, you can use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-Replace.html Util.Replace] to have xmonad ask the other WM to exit before starting up. Note: If exiting your previously running wm would lead to your X session ending, then this method won't work. <br />
<br />
Otherwise refer to the appropriate page for starting xmonad instead of your other WM ([[Xmonad/Using xmonad in Gnome|Gnome]], [[Xmonad/Using xmonad in KDE|KDE]]).<br />
<br />
===mod-q doesn't work===<br />
====Upgraded GHC and now xmonad xmonad-contrib etc are not found====<br />
When you change ghc versions you need to rebuild or reinstall haskell libraries to make sure they are compatible and registered with the new ghc. Often your distro packagers will try to make this as automatic as possible, by making it just happen. Or at least they will make it easier, e.g. gentoo's ghc-updater and haskell-updater. (This isn't just a Haskell/ghc issue; it's true for other languages, too: c.f. python-updater scripts, distro policies regarding gcc and glibc changes.)<br />
<br />
==== Changes to the config file ignored or 'xmonad not found' when starting X ====<br />
<br />
Both ghc and xmonad must be in your display manager init's $PATH when starting X and xmonad for reconfiguration by mod-q. Make sure the environment from which you start xmonad has the appropriate settings.<br />
<br />
When changing the xmonad.hs and restarting with mod-q, xmonad will attempt to exec the xmonad binary. This means it must be in your $PATH environment variable, or the exec will fail silently and the old xmonad instance keeps running.<br />
<br />
With xmonad 0.5 and later, mod-q will also call ghc on your ~/.xmonad/xmonad.hs file, and will continue with defaults if ghc is not found.<br />
<br />
Additionally, if you change and reinstall the haskell-X11 or XMonadContrib library, changes to that package will not be noticed by xmonad's recompilation<br />
checker, so xmonad.hs won't be recompiled. ''(needs confirmation: is this true?)'' To fix this:<br />
<br />
xmonad --recompile<br />
<br />
after reinstalling the contrib library.<br />
<br />
===Tabbed or other decorated layouts not shown===<br />
Both xmobar and xmonad's default <br />
[http://hackage.haskell.org/packages/archive/xmonad-contrib/latest/doc/html/XMonad-Layout-Tabbed.html Theme] <br />
use the <code>-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*</code> font by default. This is<br />
possibly the most commonly installed font in the *nix world, but if it's not installed,<br />
or core fonts aren't working for some reason, you'll have problems. Without the font<br />
you have set in your Theme....<br />
<br />
tabs and other decorated layouts will simply not draw. There should be font related errors<br />
in .xsession-errors or wherever your display manager directs stderr to help confirm that<br />
this is the cause of missing decorations. xmobar will spit out a cryptic error message<br />
and refuse to run.<br />
<br />
Check with xfontsel that you have the fixed 10 font if you want to use the defaults.<br />
For xft, check that your xmonad and xmobar were compiled with xft support. (They are<br />
by default on most distros) Then customize your theme by using something like the<br />
following in your layoutHook<br />
<haskell><br />
myTabbed = tabbed shrinkText defaultTheme {<br />
fontName = "xft:terminus:size=12" -- choose an installed font<br />
-- more theme customizations<br />
}<br />
<br />
main = do<br />
-- skipped<br />
, layoutHook = avoidStruts $ myTabbed ||| layoutHook defaultConfig<br />
} <br />
</haskell> <br />
<br />
===DE panels pagers or EwmhDesktops are broken (just upgraded to >0.8)===<br />
Starting with 0.9, <br />
EwmhDesktops users ''must'' [http://code.haskell.org/XMonadContrib/XMonad/Hooks/EwmhDesktops.hs change configuration] by removing the obsolete ewmhDesktopsLayout from layoutHook, (it no longer exists), and updating to the current ewmh support which still includes a logHook, but in place of the old layout modifier, uses a startupHook and handleEventHook (see ff.).''(No need to change config if using ewmh via Config.Desktop, Config.Gnome, etc. Your config will automatically be updated to use current ewmh support.)<br />
<br />
Users of defaultConfig that explicitly include EwmhDesktops hooks and the ewmhDesktopsLayout modifier should remove them and instead use the new <hask>ewmh</hask> function which adds EWMH support to <hask>defaultConfig</hask> all at once. You should keep avoidStruts and manageDocks if you're using them.<br />
<br />
The 0.9 way to use EwmhDesktops rather than a desktop config is:<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.EwmhDesktops<br />
<br />
main = xmonad $ ewmh defaultConfig {<br />
-- normal customizations<br />
}<br />
</haskell><br />
<br />
===defaultGaps doesn't work any more! (just upgraded to >0.7)===<br />
See [[#Make space for a panel dock or tray | Make space for a panel]] section: use XMonad.Hooks.ManageDocks avoidStruts for this instead of Gaps, or import XMonad.Layout.Gaps.<br />
<br />
===Showing fractions of lines in gvim, urxvt,etc.===<br />
<br />
This is due to certain layouts doesn't care about so called size hints<br />
(resize increments) specifically the WM_NORMAL_HINTS(WM_SIZE_HINTS) (use<br />
xprop to see it). This, combined with certain programs, like gvim, which<br />
doesn't check if it gets enough size to render the last line and uses it anyway<br />
render this annoying behaviour. Aside from patching the offending program, you can:<br />
<br />
<ol><br />
<li>Use a layout which uses these size hints like Hinted Grid, or HintedTile</li><br />
<li>Use the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutHints.html layoutHints] modifier on any layout</li><br />
<li>Workaround in .vimrc. These lines in your .vimrc lets you change the number of lines with F4/Shift-F4:</li><br />
<pre><br />
map <F4> :let &lines=&lines-1<CR><br />
map &lt;S-F4&gt; :let &lines=&lines+1<CR><br />
</pre><br />
<li>Change the color of default GTK background (white lines), to match gvim background</li><br />
<pre><br />
style "vimfix" { bg[NORMAL] = "#000000" }<br />
widget "vim-main-window.*GtkForm" style "vimfix"<br />
</pre><br />
</ol><br />
<br />
===Emacs mini-buffer starts at wrong size===<br />
ontoillogical says: Most people turn off menus and toolbars and adjust fonts in their .emacs. That's what breaks emacs' display in tiling WMs. To get emacs to look correctly, move all of the stuff that affects how emacs draws a frame to .Xdefaults/.Xresources<br />
<br />
For reference here is the relevant section of mine:<br />
<br />
Emacs.font: DejaVu Sans Mono-12<br />
Emacs.fontBackend: xft<br />
Emacs.menuBar: off<br />
Emacs.toolBar: -1<br />
Emacs.verticalScrollBars: off<br />
<br />
If you're having emacs sizing problems setting these in .Xdefaults is still worth a try even if you don't have any custom .emacs settings.<br />
<br />
===Losing text when resizing xterms===<br />
<br />
Being a dynamic tiling window manager, xmonad, like ion or dwm, makes heavy use of resizing. Clients such as xterm, might not take well to resizing and the window might require a refresh (Ctrl-L). To minimize this, several users recommend urxvt (rxvt-unicode), which handles resizing much better.<br />
<br />
=== I just resized my terminal, but the terminal app didn't resize. ===<br />
This is a SIGWINCH bug in the Linux kernel, believe it or not, in the 2.6.26 series. Details here: http://groups.google.com/group/fa.linux.kernel/browse_thread/thread/8044876def45c0b0/4b7f4cd87feafe5e?show_docid=4b7f4cd87feafe5e.<br />
<br />
The simplest solution is to up/downgrade to a kernel version without this bug.<br />
<br />
===Double encoding of command lines in ghc 7.8 and later===<br />
Because earlier versions of ghc had runtimes that just truncated characters, use of Unicode outside the range '\0' .. '\255' required that xmonad and utilities (notably [[XMonad.Util.Run|http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-Run.html]]) encode such to UTF-8 before passing them to e.g. <code>executeFile</code>.<br />
<br />
ghc 7.8 and later perform this encoding themselves, leading to double encoding from functions such as <code>spawnPipe</code>. (<code>spawn</code> would not have been affected in versions of xmonad that do not use the <code>utf8-string</code> package; current versions ''are'' affected.)<br />
<br />
A quick way to work around this is to<br />
<br />
<code>import qualified GHC.IO.Encoding as GIO</code><br />
<br />
at the top of <code>xmonad.hs</code>, and then as the first thing in your <code>main</code> put<br />
<br />
<code>GIO.setFileSystemEncoding GIO.char8</code><br />
<br />
which will restore the old behavior. Bugs have been recorded against the main offenders, so they can be updated to behave correctly according to the ghc version.<br />
<br />
===XMonad is frozen!===<br />
<br />
==== XMonad stops but the current window still responds to keys ====<br />
<br />
Usually this is because a dynamicLog is writing to a pipe handle that's not being read. For example the xmonad.hs writes to some status bar in the logHook, but the status bar is not installed, not in $PATH, not set up to read its stdin, or just plain not running. Eventually the pipe fills up and blocks and xmonad waits for it to be read before continuing.<br />
<br />
To cat the full pipe and free up xmonad, find xmonad's pid via pgrep or htop, etc. let's say it's 1001, then <code>ls -l /proc/1001/fd/</code> and look for the largest numbered pipe. Let's use 4. Then <code>cat /proc/1001/fd/4</code> to unblock xmonad so you can fix your xmonad.hs and xmobarrc to work correctly. (If catting that pipe doesn't spew out a bunch of stuff and unfreeze things, try the others listed.)<br />
<br />
With the post 0.9 <hask>=<< xmobar</hask> and <hask>statusBar</hask> modifiers it isn't obvious that xmonad is writing to a pipe. If you don't want xmonad info shown in your<br />
status bar, you will probably be better off launching it by other means such as .xinitrc. You can also customize your PP's ppOutput field to use the default <hask>hPutStrLn</hask> to write to stdout, or change it to <hask>\s -> return ()</hask> to do nothing at all.<br />
<br />
<em>With xmobar</em>, if your logHook is writing to its stdin via <hask>ppOutput = hPutStrLn foo</hask>, make sure the .xmobarrc <hask>commands</hask> include a <hask>Run StdinReader</hask> line, and the <hask>template</hask> includes <hask>%StdinReader%</hask>.<br />
<br />
For examples of an .xmobarrc with working StdinReader, see this [https://wiki.archlinux.org/index.php/Xmonad#Using_xmobar_with_xmonad arch linux help page] or [[Xmonad/Config_archive/John_Goerzen%27s_Configuration|John Goerzen's xmonad config tutorial]].<br />
<br />
See also [http://code.google.com/p/xmonad/issues/detail?id=91 this issue] on the xmonad bug tracker.<br />
<br />
==== XMonad stops responding to keys (usually due to unclutter) ====<br />
<br />
The number one cause for this is the 'unclutter' program, which can fool<br />
some clients into thinking they've lost the pointer, when in fact they have<br />
not. See the '-noevents' flag to unclutter.<br />
Or use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-Warp.html XMonad.Actions.Warp] or [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-UpdatePointer.html XMonad.Actions.UpdatePointer] xmonad-contrib extension instead.<br />
<br />
==== An app seems to have frozen and xmonad stops responding to keys ====<br />
<br />
Often you can get X to behave again by running 'xclock -display :0' on the appropriate display via ssh or from a virtual terminal. If that's not enough kill suspect apps similarly.<br />
<br />
There is also an option in (pre evdev versions of) xorg.conf which enables the key combination '''Ctrl+Alt+Keypad-Divide''' to break active keyboard and mouse grabs. <br />
<br />
This may allow xmonad to continue normally in such cases. To enable this key combination, add the following line to your xorg.conf in the Section ''Server Flags'' then restart X:<br />
<br />
Option "AllowDeactivateGrabs" "on"<br />
<br />
=== Problems with Java applications, Applet java console ===<br />
<br />
There are two classes of problems: blank, grey windows and windows that can't be focused for keyboard input. The latter should be fixed in the newest xmonad, so follow the instructions on the website for getting a copy of the darcs repository and build it. Remember to rebuild xmonad-contrib (preferably also from darcs) afterwards! The remainder of this section covers the blank, grey window problems.<br />
<br />
The Java gui toolkit has a hardcoded list of so-called "non-reparenting"<br />
window managers. xmonad is not on this list (nor are many of the newer window<br />
managers). Attempts to run Java applications may result in `grey blobs' where<br />
windows should be, as the Java gui code gets confused.<br />
<br />
====Preferred Method====<br />
If you are using openjdk6 >= 1.6.1, the cleanest way to work around the hardcoded list is to warn the vm that xmonad is non-reparenting by exporting the appropriate environment variable:<br />
<br />
_JAVA_AWT_WM_NONREPARENTING=1<br />
<br />
Using JDK 7 seems to work well, too, see below.<br />
<br />
====Using SetWMName====<br />
Otherwise, you can lie to Java about what window manager you are using, by having the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-SetWMName.html SetWMName] extension convince Java that xmonad is '''"LG3D"'''. (**WARNING: This *breaks* recent versions of gtk+3!** Use the Preferred Method above instead, if necessary upgrading your Java to a version which supports it.) Normally you would use this in the startup hook, like this:<br />
<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = do<br />
xmonad $ defaultConfig<br />
{ modMask = mod4Mask<br />
, startupHook = setWMName "LG3D"<br />
-- other customizations<br />
}<br />
</haskell><br />
'''However''', modules using Hooks.EwmhDesktops, such as Config.Gnome, Config.Desktops, etc. also set WM Name as part of supporting Extended Window Manager Hints. Combining EWMH support with the "LG3D" workaround takes special attention to modifying the appropriate hook for your xmonad version:<br />
<br />
'''Starting with xmonad-0.9'''. the window manager name is set once in EWMH '''''startupHook''''' after each mod-q, along with other EWMH initialization, but after that can be changed and not overwritten till the next mod-q. See below for example startupHooks combining both startupHooks.<br />
<br />
'''In xmonad versions 0.7 and 0.8''' the EWMH configs setWMName to "xmonad" on each '''''logHook''''' event, so to use "LG3D" instead, it's necessary to either<br />
* patch the XMonad.Hooks.EwmhDesktops source and rebuild xmonad-contrib<br />
OR<br />
* use the version 0.8.* hack shown below to repeatedly setWMName "LG3D" after the ewmh logHook runs.<br />
<br />
==== Using SetWMName with EwmhDesktops ====<br />
<br />
For '''xmonad-0.9 0.9.1 or darcs''':<br />
<br />
Add ewmhDesktopsStartup, (or 'startupHook gnomeConfig', etc.) to '''''startupHook''''' ''before'' setWMName.<br />
<br />
Defining the EWMH hooks yourself:<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = xmonad defaultConfig<br />
{ -- skipped<br />
, startupHook = ewmhDesktopsStartup >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
Using a desktop config as your base:<br />
<haskell><br />
xmonad desktopConfig<br />
{ -- skipped<br />
, startupHook = startupHook desktopConfig >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
If instead you're using the ewmh config modifier to add EWMH support, then define your config at top-level to allow over-riding the startupHook definition with your own version:<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.SetWMName<br />
<br />
-- define an EWMH base config to use later in main<br />
conf = ewmh defaultConfig<br />
{ manageHook = myManageHooks <+> manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ myLayout ||| layoutHook defaultConfig<br />
, logHook = dynamicLogWithPP xmobarPP<br />
{ ppOutput = hPutStrLn xmproc<br />
, ppLayout = const ""<br />
, ppTitle = xmobarColor "green" "" . shorten 80<br />
}<br />
}<br />
<br />
-- Override the WM Name setting for the "LG3D" workaround<br />
-- but still use the rest of the EWMH base config you just<br />
-- defined, including its startupHook ewmh initialization<br />
<br />
main = do<br />
xmproc <- spawnPipe "xmobar"<br />
xmonad conf<br />
{ startupHook = startupHook conf >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
For '''xmonad-0.8.*''' :<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.ManageDocks<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = do<br />
xmproc <- spawnPipe "xmobar"<br />
xmonad $ defaultConfig<br />
{ manageHook = myManageHooks <+> manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ ewmhDesktopsLayout $ myLayout ||| layoutHook defaultConfig<br />
-- NOTE: no '$' is used between dynamicLogWithPP and xmobarPP<br />
, logHook = dynamicLogWithPP xmobarPP<br />
{ ppOutput = hPutStrLn xmproc<br />
, ppLayout = const ""<br />
, ppTitle = xmobarColor "green" "" . shorten 80<br />
}<br />
>> ewmhDesktopsLogHook<br />
>> setWMName "LG3D"<br />
<br />
---- or with a desktop config, e.g.<br />
-- , logHook = logHook gnomeConfig >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
With xmonad-0.9 or greater there is no need to spam the X server with setWMName in logHook, see above for how to modify startupHook instead.<br />
<br />
==== Changing AWT Toolkit ====<br />
Another option is to use an AWT toolkit that is more window manager agnostic, (Some report that this causes keyboard to fail in some java applications. It also doesn't seem to work as widely or reliably as setWMName or other preferred methods above.) If you want to try it, set the environment variable:<br />
<br />
AWT_TOOLKIT=MToolkit<br />
<br />
This seems to fix some versions of:<br />
<br />
* MATLAB<br />
* cgoban3<br />
* Netbeans<br />
* processing [http://processing.org]<br />
<br />
Even if you don't use Bash, you can often set environmental variables by putting them in .profile and logging back in:<br />
<br />
export AWT_TOOLKIT=MToolkit<br />
<br />
Using the free blackdown java runtime also seems to work correctly to fix this issue.<br />
<br />
==== Use JDK 7 ====<br />
* Using JDK 7 also seems to work well.<br />
<br />
Anthony Brown writes: <blockquote>I just downloaded and early binary release of JDK 7 and it looks like the new Java version behaves properly ... I tried using some Gui apps that gave me the infamous grey windows with Java6 (or Java5 without setting AWT_TOOLKIT=MToolkit) and so far no problems occured.</blockquote><br />
<br />
Gunnar Ahlberg #xmonad: <blockquote>JDK 7 solved problems remaining even when using setWMName "LG3D" in logHook.</blockquote><br />
<br />
==== Persuade a java application to use a specific java runtime (JRE) ====<br />
<br />
Sometimes it turns out that a program works with a specific JRE version, but not with another. Commercial programs tend to ship with their own JRE, so you may even notice that one program works while another doesn't. (For example, I've had a setup where Maple had problems while Matlab behaved well.) A java symlink in the right place can do wonders here. See [https://bugs.launchpad.net/xorg-server/+bug/185311 this Ubuntu bug report] for a number of examples.<br />
<br />
===XMonad doesn't save my layouts and windows===<br />
<br />
xmonad will remember your workspace layouts during dynamic restart<br />
(mod-q), but not when quitting X altogether. Note that this means <br />
if you add or remove layouts to the config.hs file, the changes won't be<br />
noticed during a hot-restart (the state from the previous session will<br />
be used).<br />
<br />
You can reinitialise the xmonad state dynamically with mod-shift-space.<br />
<br />
===Some keys not working===<br />
If you've an unusual keyboard, X may not know precisely which keys<br />
you've bound xmonad actions to. An example is when you use a<br />
French keyboard layout. You may need to set your own mod key, or use<br />
different key bindings in xmonad.hs. See the xmonad.org docs on configuring and customizing for advice on rebinding keys. Also currently xmonad only handles the first of duplicate key symbols bound, so if you have for example multiple xK_Backspace keys not all will be bound. There are patches available on the xmonad mailing list (or darcswatch) to change this.<br />
<br />
====Media keys====<br />
XMonad.Util.EZConfig additionalKeysP or Graphics.X11.ExtraTypes are the best way to bind the XF86 family of special keys. Note that some special laptop keys are handled by acpi and may show up as button events instead, or even bypass X completely.<br />
<br />
====French keyboard workspace switching====<br />
See XMonad.Config.Azerty for an azertyConfig to use in place of defaultConfig. This will adjust keybindings for the azerty layout, fixing workspaces switching, etc.<br />
<br />
====Numeric keypad keys like xK_KP_2 not working====<br />
Bind to the non-numeric versions of these keys. They work regardless of NumLock status. To avoid conflicts with other apps you probably want to use them with modifiers. Here is an example of using them to navigate workspaces in the usual mod-N mod-shift-N way, but on the key pad:<br />
<br />
<haskell><br />
myWorkspaces = ["1","2","3","4","5","6","7","8","9","0"]<br />
<br />
modm = mod4Mask -- win key for mod<br />
<br />
myKeys = -- use with EZConfig.additionalKeys or edit to match your key binding method<br />
[<br />
-- more custom keybindings<br />
]<br />
++<br />
[((m .|. modm, k), windows $ f i)<br />
| (i, k) <- zip myWorkspaces numPadKeys<br />
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]<br />
]<br />
<br />
-- Non-numeric num pad keys, sorted by number <br />
numPadKeys = [ xK_KP_End, xK_KP_Down, xK_KP_Page_Down -- 1, 2, 3<br />
, xK_KP_Left, xK_KP_Begin, xK_KP_Right -- 4, 5, 6<br />
, xK_KP_Home, xK_KP_Up, xK_KP_Page_Up -- 7, 8, 9<br />
, xK_KP_Insert] -- 0 <br />
</haskell><br />
<br />
====Keybindings dont work with rdesktop====<br />
Try running with the "-K" (keep window manager key bindings) switch. For example, <code>rdesktop -K -f 666.666.666.666</code> then press Ctrl-Alt-Enter, or simply <code>rdesktop -K 666.666.666.666</code><br />
<br />
===Copy and Paste on the Mac===<br />
<br />
When using X11 for Mac OS X, and you switch from the quartz WM to<br />
xmonad, you can lose copy/paste functionality between X windows and<br />
normal Mac apps. To fix this, and restore copy and paste, add<br />
<br />
quartz-wm --only-proxy &<br />
<br />
in your .xinitrc above the line that runs xmonad. It will capture and<br />
syncronize copy/paste events in both environments. More specifically,<br />
it mirrors OS X copy actions into both PRIMARY and CLIPBOARD, but only<br />
CLIPBOARD into OS X paste.<br />
<br />
===OpenOffice looks bad===<br />
<br />
OpenOffice won't use (strangely) the GTK look, unless the following<br />
environment variable is set:<br />
<br />
OOO_FORCE_DESKTOP=gnome<br />
<br />
Use this if you don't like the default look of OpenOffice in xmonad.<br />
<br />
=== Help! xmonad just segfaulted ===<br />
<br />
Due to this bug in GHC's recompilation checker,<br />
<br />
http://hackage.haskell.org/trac/ghc/ticket/1372<br />
<br />
if you updated a previously built xmonad, or XMonadContrib, when a<br />
dependent library has changed in the meantime, GHC will happily go ahead<br />
and link your libraries together, into a broken binary. This will at<br />
best produce a linker error, and at worst, a version of xmonad that will<br />
segfault. <br />
<br />
The rule is: when rebuilding, for example, XMonadContrib, always clean<br />
first if any library it depends on has changed.<br />
<br />
runhaskell Setup.lhs clean<br />
<br />
You may also want to make sure your config gets rebuilt:<br />
<br />
xmonad --recompile<br />
<br />
Another possibility is your xmonad was compiled against a very old<br />
version of the haskell-x11 library. Use haskell-X11-1.4.2 or newer.<br />
This version incorporates a couple of WM_HINTS related segfault bug<br />
fixes.<br />
<br />
=== Cabal: Executable stanza starting with field 'flag small_base description' ===<br />
<br />
When using ghc 6.6, or old versions of Cabal, you may get errors when configuring:<br />
<br />
*** Exception: getSection got a line without a '{'. Consider this a bug.<br />
<br />
These are all symptoms of trying to compile xmonad with an old version<br />
of cabal.<br />
<br />
The darcs version after xmonad 0.4 switched to requiring Cabal 1.2 to<br />
build xmonad. You '''must''' have Cabal 1.2 or newer to build xmonad<br />
older than 0.4. It will work fine with ghc 6.6.1, and you do not need to<br />
updated ghc. This will also not break older packages. Get cabal from Hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal<br />
<br />
Build and install as usual, then rebuild xmonad.<br />
<br />
To build Cabal with ghc 6.6.1 you will also need the filepath library,<br />
which is also (of course) available from hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath<br />
<br />
=== configure: error: cannot run C compiled programs. ===<br />
<br />
This typically means that you have /tmp mounted with noexec. To use another directory, make an alias that temporarily changes $TMPDIR, like<br />
<br />
alias cabal="TMPDIR=[insert directory here, eg ~/.cabal/build but make sure the directory exists] cabal"<br />
<br />
=== A manage hook is having no effect ===<br />
<br />
If a manage hook that checks an attribute of a window(e.g. resource =? "foo"<br />
--> bar) doesn't work even though the property is the same as reported by<br />
xprop, it can be caused by a program setting the corresponding property after<br />
the window has been created. To debug whether or not the term on the right<br />
hand side is at fault, it is useful to log which resource (or other property)<br />
xmonad sees:<br />
<br />
<haskell><br />
(resource >>= io . appendFile "/home/<youruser>/xmonad_debug" >> idHook)<br />
</haskell><br />
<br />
If opening the desired window causes xmonad to produce a log entry with the<br />
resource you were interested in, it means that the term on the right-hand side<br />
of --> is not working.<br />
<br />
[[Category:XMonad]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Regex_Posix&diff=61613Regex Posix2017-03-10T03:30:59Z<p>HowardBGolden: /* regex-posix-unittest */ Update link to testregex.c</p>
<hr />
<div>= regex-posix Bugs =<br />
<br />
Executive summary: If you want a bug-free and/or portable POSIX extended regular expression library to use from Haskell, then regex-posix will not help you. You should use the regex-tdfa package instead.<br />
<br />
The regular expressions provided by the GHC bundle (up to 6.10.1) are<br />
through a wrapping of the operating system's native C library. The C<br />
library calls in<br />
[http://www.opengroup.org/onlinepubs/009695399/basedefs/regex.h.html "regex.h"]<br />
have been imported via FFI and wrapped by<br />
[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/regex-posix regex-posix]<br />
, either the older 0.72.* version or the newer version (> 0.94.*).<br />
Note that the matchAll semantics changed in regex-posix with version<br />
0.94.0 (see mailing list announcement).<br />
<br />
Unfortunately the native platforms provide Posix regular expressions<br />
support that contains bugs and/or violates the<br />
[http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html specification]. This is especially true for the GNU C library (GLIBC)<br />
used by Linux distributions and the BSD C library used by OS X and<br />
FreeBSD and NetBSD (XBSD). More discussion of the standard is<br />
available from [http://gsf.cococlyde.org/download Glenn Fowler]<br />
formerly of AT&T Labs.<br />
<br />
A capsule summary of the Posix rules:<br />
* regular expressions (REs) take the leftmost starting match, and the longest match starting there<br />
* earlier subpatterns have leftmost-longest priority over later subpatterns<br />
* higher-level subpatterns have leftmost-longest priority over their component subpatterns<br />
* REs have right associative concatenation which can be changed with parenthesis<br />
* parenthesized subexpressions return the match from their last usage<br />
* text of component subexpressions must be contained in the text of the higher-level subexpressions<br />
* if "p" and "q" can never match the same text then "p|q" and "q|p" are equivalent, up to trivial renumbering of captured subexpressions<br />
* if "p" in "p*" is used to capture non-empty text then additional repetitions of "p" will not capture an empty string<br />
<br />
All of the above rules will be violated by one or another bug described below.<br />
<br />
= regex-posix-unittest =<br />
<br />
Many of these unittests come from<br />
[https://sites.google.com/a/cococlyde.org/gsf/download testregex.c] available from Glenn Fowler, the rest from the author of regex-tdfa ([[ChrisKuklewicz]]). Note that all of these tests are passed by regex-tdfa-0.97.1 (but not below<br />
this). Since then additional bugs have been found and fixed, so regex-tdfa is now on at least version 0.97.4, and a future regex-posix-unittest may include the additional test cases.<br />
<br />
These problems are documented here, but examples of the bugs are<br />
testable on your system by way of the regex-posix-unittest package on<br />
Hackage. This package can be installed either as "--user" or<br />
"--global", and provides three things:<br />
<br />
# The "regex-posix-unittest" binary executable<br />
# The "test-manifest.txt" file which lists files to load test from<br />
# A set of ".txt" files containing one unit test per line<br />
<br />
Running the regex-posix-unittest program produces output for the<br />
passing or failing of each test in each file listed in "test-manifest.txt",<br />
which is shipped listing all the test files. This is followed a<br />
summary list of failing test id numbers.<br />
<br />
Each unit test line has four fields, separated by white-space (one tab<br />
in the above):<br />
<br />
# The test identification Int, negative if this is expected to fail<br />
# The regular expression pattern (extended regular expression)<br />
# The text to search (no white-space) # The expected result<br />
## NOMATCH if the matching should fail ## "(n,m)(..)" if the match succeeds<br />
##* Each pair of numbers denotes a substring of the text to search as two 0-based indexes<br />
##* The length of the substring is (m-n)<br />
##* The first pair is the whole match, further pairs are for parenthesized subexpression captures<br />
##* Subexpressions that do not match are lists as "(?,?)" instead of with numbers<br />
<br />
You can add and delete but please do not change existing tests.<br />
<br />
If your platform is not mentioned in this wiki page (see below) then<br />
please either add it and your summary results or email the results to<br />
"TestRegexLazy -at- mightyreason -dot- com".<br />
<br />
One can also pass two strings to "regex-posix-unittest" to run your own test:<br />
<pre><br />
user@ubuntu810desktop:~/test/regex-posix-unittest$ ~/.cabal/bin/regex-posix-unittest "abcd" "([^c])+"<br />
Test for [Char], Version {versionBranch = [1,0], versionTags = []}<br />
"abcd"<br />
"([^c])+"<br />
Posix<br />
("","ab","cd",["b"])<br />
POSIX count = (2,2)<br />
array (0,1) [(0,(0,2)),(1,(1,1))]<br />
array (0,1) [(0,(3,1)),(1,(3,1))]<br />
</pre><br />
<br />
This actually is a slightly return format. The strings are echoed and<br />
the ("","ab","cd",["b"]) is the "" before the first match, the "ab" of<br />
the whole first match, and the "cd" after the first match, which the<br />
captures in the list ["b"]. The arrays lines are the results of<br />
consecutive non-overlapping matches, in (capture #, (start index,<br />
length)) format. So (1,(1,1)) is the 1st parenthesis and starts after<br />
the 1st character and is 1 character long: "b". The (1,(3,1)) is "d".<br />
<br />
= Types of failure =<br />
<br />
There are four classes of failures:<br />
# Critical failures that find the wrong whole match (XBSD as of January 2009, Solaris)<br />
# Serious failures that find impossible subexpressions (XBSD)<br />
# Serious failures that violate well-formed subexpressions (GLIBC)<br />
# Failure to choose Posix captures when the answer is ambiguous (GLIBC, XBSD, Solaris)<br />
<br />
Example of an ambiguous situation: Matching "a" with the the pattern<br />
"(.)?(a)?" or the pattern "(.)|(a)". Each pattern can use either<br />
"(.)" or "(a)" to match the "a', but not both; thus only one of the<br />
two subexpressions must succeed and the other must fail. In this case<br />
the right answer is that "(.)" succeeds in both cases, so the full<br />
answer is (0,1)(0,1)(?,?). The first pattern uses the right<br />
associativity rule for concatenation and the second pattern uses the<br />
leftmost subpattern bias.<br />
<br />
= Results and Bugs =<br />
<br />
== OS X, FreeBSD, NetBSD ==<br />
<br />
On a G4 version of OS X 10.5.6 I see:<br />
<pre><br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/basic3.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/class.txt",[3,9])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/left-assoc.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/right-assoc.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/forced-assoc.txt",[5,6,7,8,15,16,21,22])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/nullsub3.txt",[50,51])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/repetition2.txt",[101,102,103,104,105,106,107,<br />
110,111,112,113,114,115,116,117,260,261,262,263,266,267,268,270,271])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/totest.txt",[5,30,33,209])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[1,-1,2,-2,3,-3,14,-14])<br />
</pre><br />
The "osx-bsd-critical.txt" unexpected failures are:<br />
<pre><br />
############################# Unexpected Fail # 1 #############################<br />
<br />
Searched text: "ab"<br />
Regex pattern: "(()|.)(b)"<br />
Expected output: "(0,2)(0,1)(-1,-1)(1,2)"<br />
Actual result : "(1,2)(1,1)(1,1)(1,2)"<br />
<br />
############################# Unexpected Fail # 2 #############################<br />
<br />
Searched text: "ab"<br />
Regex pattern: "(()|[ab])(b)"<br />
Expected output: "(0,2)(0,1)(-1,-1)(1,2)"<br />
Actual result : "(1,2)(1,1)(1,1)(1,2)"<br />
<br />
############################# Unexpected Fail # 3 #############################<br />
<br />
Searched text: "aaab"<br />
Regex pattern: "(()|[ab])+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(3,4)(3,3)(3,3)"<br />
<br />
############################# Unexpected Fail # 14 #############################<br />
<br />
Searched text: "aaab"<br />
Regex pattern: "([ab]|())+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(0,4)(3,3)(3,3)"<br />
</pre><br />
<br />
Tests 1 and 2 should match the whole (0,2) or "ab" but only match the<br />
(1,2) of "b". Test 3 should match the (0,3) of "aabb" but only<br />
matches the (3,4) of "b". These are critical failures to match the<br />
whole text properly. This problem was found by QuickCheck and<br />
reported to OS X and FreeBSD and NetBSD (the latter two checked over<br />
IRC). OpenBSD reportedly did not show this bug (anecdote on IRC).<br />
<br />
This also infects sed, and can be seen as<br />
<pre><br />
prompt$ echo "ab" | sed -En 's/(()|.)(b)/[&][\1]/p'<br />
a[b][]<br />
</pre><br />
instead of the correct "[ab][a]" output.<br />
<br />
The failure in Test 14 is different. Instead of the whole match being<br />
wrong the pattern being repeated by the "+" operator is matched 3<br />
times against "a" and "a" and "a", followed by a fourth empty match at<br />
(3,3) before the final "b". Once the repeated pattern "[ab]|()" has<br />
matched a non-empty string it should not be used to match an<br />
empty-string.<br />
<br />
OS X also gets this wrong in "totext.txt" #209:<br />
<pre><br />
Searched text: "yyyyyy"<br />
Regex pattern: "(yyy|(x?)){2,4}"<br />
Expected output: "(0,6)(3,6)(-1,-1)"<br />
Actual result : "(0,6)(6,6)(6,6)"<br />
</pre><br />
where the (x?) matches the empty string at (6,6) instead of stopping<br />
after 2 repetitions of "yyy".<br />
<br />
But OS X is getting this right on numerous tests in "nullsub3.txt" such as<br />
<pre><br />
Expected Pass #8<br />
text and pattern: "a"<br />
Regex pattern: "(a*)*"<br />
Outputs agree: "(0,1)(0,1)"<br />
<br />
Expected Pass #47<br />
text and pattern: "ax"<br />
Regex pattern: "(a*)*(x)"<br />
Outputs agree: "(0,2)(0,1)(1,2)"<br />
</pre><br />
<br />
Where (a*) matches "a" and is reported as (0,1) and the no additional repetition<br />
matches the empty string at (1,1).<br />
<br />
The OS X failure in "totest.txt" #33 illustrates the "impossible" capture:<br />
<pre><br />
Searched text: "ababa"<br />
Regex pattern: "(aba|ab|a)*"<br />
Expected output: "(0,5)(2,5)"<br />
Actual result : "(0,5)(0,3)"<br />
</pre><br />
The whole match is (0,5) and the correct repetition has "ab" then<br />
"aba" matching, so the correct last repetition is the "aba" between<br />
indexes (2,5). The OS X code recognizes the whole match then does a<br />
second pass of greedy repetitions, so the first repetition is "aba"<br />
between indexes (0,3). The OS X code then fails to match the "ba" in<br />
this second pass but not care. It is logically impossible that the<br />
last iteration of the above subexpression ends before the whole match,<br />
but OS X reports the last repetition ended at index 3 even though the<br />
whole match ends at index 5.<br />
<br />
This is also shown in numerous failed tests in "repetition2.txt" such as #260:<br />
<pre><br />
Searched text: "ababcd"<br />
Regex pattern: "(a|ab|c|bcd){0,}(d*)"<br />
Expected output: "(0,6)(3,6)(6,6)"<br />
Actual result : "(0,6)(4,5)(6,6)"<br />
</pre><br />
The correct repetitions are "ab" then "a" then "bcd", reported as (3,6). The incorrect greedy pass uses by OS X matches "ab" then "c" as (4,5) and then gives up even though (5,6) is still not matched in the second pass. As a sed test:<br />
<pre><br />
prompt$ echo "ababcd" | sed -En 's/(a|ab|c|bcd)*/[&][\1]/p'<br />
[ababcd][c]<br />
</pre><br />
The above output should be impossible; the correct output is [ababcd][bcd].<br />
<br />
The "forced-assoc.txt" failures show that one cannot use parenthesis<br />
to force the naturally right associative concatenation to be left<br />
associative. This is a violation of the Posix standard, and of the<br />
"man 7 re_format" page form OS X 10.5.6: "Subexpressions also match<br />
the longest possible substrings, subject to the constraint that the<br />
whole match be as long as possible, with subexpressions starting<br />
earlier in the RE taking priority over ones starting later. Note that<br />
higher-level subexpressions thus take priority over their lower-level<br />
component subexpressions". Take #15 as an example:<br />
<pre><br />
Searched text: "abc"<br />
Regex pattern: "((a*)(b|abc))(c*)"<br />
Expected output: "(0,3)(0,3)(0,0)(0,3)(3,3)"<br />
Actual result : "(0,3)(0,2)(0,1)(1,2)(2,3)"<br />
</pre><br />
Here ((a*)(b|abc))(c*) should be parsed as ((a*)(b|abc)) followed by<br />
(c*). As ((a*)(b|abc)) started earlier it should be as long as<br />
possible, at the expense of (c*). The longest match for this is the<br />
correct (0,3) not the incorrect (0,2) returned by OS X. And<br />
((a*)(b|abc)) is a higher-level than its lower-level component (a*),<br />
so (a*) should match with the side constraint that ((a*)(b|abc))<br />
matches (0,3), which means (a*) should match (0,0) instead of the<br />
longer (0,1). OS X gets this associativity this wrong.<br />
<br />
In "repetitions2.txt" there is a series:<br />
<pre><br />
Expected Pass #100<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){0,}Y"<br />
Outputs agree: "(0,9)(7,8)"<br />
<br />
############################# Unexpected Fail # 101 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){1,}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
...<br />
############################# Unexpected Fail # 107 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){7,}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
Expected Pass #108<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){8,}Y"<br />
Outputs agree: "(0,9)(8,8)"<br />
<br />
############################# Unexpected Fail # 110 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){0,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
############################# Unexpected Fail # 111 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){1,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
...<br />
<br />
############################# Unexpected Fail # 117 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){7,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
Expected Pass #118<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){8,8}Y"<br />
Outputs agree: "(0,9)(8,8)"<br />
</pre><br />
<br />
The good news is that #108 and #118 are correct, as the last<br />
repetition is forced to match the empty string after the "7" and<br />
before the "Y". The {1,} through {7,} and {1,8} through {7,8} are all<br />
wrong: they all should match the "7" at (7,8) but XBSD returns the<br />
null at (8,8). The {0,} answer is right, but {0,8} and {1,} are both<br />
wrong. So {0,} seems to handled specially, probably because {0,} is<br />
precisely the "*" operator, though the wrong {1,} is precisely the "+"<br />
operator.<br />
<br />
The failures of XBSD in "repetitions2.txt" in the 260 to 271 range<br />
show a different ambiguity where {0,} is not matched correctly. It<br />
gets these wrong by being greedy in the expanded form of the {n,m}<br />
operators. The "a|ab|c|bcd" should choose "ab" then "a" then "bcd" at<br />
(3,6) to match "ababcd", then (d*) should match nothing at (6,6). But<br />
XBSD is matching "ab" then "ab" then "c" at (4,5) and then uses (d*)<br />
to match the last "d" at (5,6). Changing the pattern to<br />
"((a|ab|c|bcd){3,10})(d*)" fails to force the grouping and<br />
associativity.<br />
<br />
== OpenBSD ==<br />
<br />
There is no report from OpenBSD. One would be quite welcome!<br />
<br />
== GNU C library (aka GLIBC) ==<br />
<br />
The system being tested is a current Ubuntu 8.10 distribution:<br />
<pre><br />
user@ubuntu810desktop:~$ uname -a<br />
Linux ubuntu810desktop 2.6.27-11-generic #1 SMP Wed Jan 28 00:02:01 UTC 2009 i686 GNU/Linux<br />
</pre><br />
The failing tests are<br />
<pre><br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/basic3.txt",[71])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/class.txt",[3,5,10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/left-assoc.txt",[-1,-2,-9,-10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/right-assoc.txt",[1,2,9,10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/forced-assoc.txt",[7,8,9,10,15,16,21,22,27])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/nullsub3.txt",[41])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/repetition2.txt",[26,28,34,41,42,108,110,111,112,113,114,115,116])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/totest.txt",[5,24,26,27,36,42,83,84,110,206,207,208,209,215,250,251])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[3])<br />
</pre><br />
<br />
The GLIBC engine has an API for its own GNU regular expression<br />
standard which differs from Posix. It also exposes a Posix compatible<br />
"regex.h" API, and GNU sed has a "--posix" switch. But the library is<br />
not really trying to get the Posix answer.<br />
<br />
First is nested subexpressions. In Posix sets of nested parenthesis<br />
that return captures must return nested captures: the inner<br />
subexpressions return substrings of the outer substrings. Consider<br />
"totest.txt" #215:<br />
<pre><br />
Searched text: "ab"<br />
Regex pattern: "((a)|(b)){2,}"<br />
Expected output: "(0,2)(1,2)(-1,-1)(1,2)"<br />
Actual result : "(0,2)(1,2)(0,1)(1,2)"<br />
</pre><br />
Where "(a)" matches the "a" at (0,1), and the next repetion matches<br />
"(b)" matches the "b" at (1,2). Under Posix rules the "(a)" did not<br />
match in the last use of the parent subexpression ((a)|(b)), so it<br />
should be (-1,-1). Under GLIBC rules it should return (0,1). The<br />
above could largely be fixed by a filter that unsets child patterns<br />
that are not properly nested, though I worry about edge cases and<br />
empty matches.<br />
<br />
In GLIBC this is not the case, take "osx-bsd-critical" #3 and #14 as an example:<br />
<pre><br />
############################# Unexpected Fail # 3 #############################<br />
Searched text: "aaab"<br />
Regex pattern: "(()|[ab])+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(0,4)(2,3)(0,0)"<br />
<br />
Expected Pass #14<br />
text and pattern: "aaab"<br />
Regex pattern: "([ab]|())+b"<br />
Outputs agree: "(0,4)(2,3)(-1,-1)"<br />
</pre><br />
<br />
In #3, the "()" does match at the initial position, so it gets its<br />
capture reported, even though (0,0) is not a substring of (2,3). This<br />
is contradicted by #14 where "()" does not match at the initial<br />
position. This is an example of where "p|q" should be the same as<br />
"q|p" but returns a different answer.<br />
<br />
The failure of some of the "right-assoc.txt" tests shows that GLIBC<br />
uses neither right nor left associative concatenation:<br />
<pre><br />
############################# Unexpected Fail # 1 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "(a|ab)(c|bcd)(d*)"<br />
Expected output: "(0,4)(0,2)(2,3)(3,4)"<br />
Actual result : "(0,4)(0,1)(1,4)(4,4)"<br />
<br />
############################# Unexpected Fail # 2 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "(a|ab)(bcd|c)(d*)"<br />
Expected output: "(0,4)(0,2)(2,3)(3,4)"<br />
Actual result : "(0,4)(0,1)(1,4)(4,4)"<br />
<br />
Expected Pass #3<br />
text and pattern: "abcd"<br />
Regex pattern: "(ab|a)(c|bcd)(d*)"<br />
Outputs agree: "(0,4)(0,2)(2,3)(3,4)"<br />
<br />
Expected Pass #4<br />
text and pattern: "abcd"<br />
Regex pattern: "(ab|a)(bcd|c)(d*)"<br />
Outputs agree: "(0,4)(0,2)(2,3)(3,4)"<br />
</pre><br />
<br />
Test #1 through #4 check all four orderings of "a" versus "ab" and "c"<br />
versus "bcd". And GLIBC seems to be applying a greedy strategy to the<br />
"a" or "ab" subpattern. Consider these in "forced-assoc.txt":<br />
<pre><br />
Expected Pass #5<br />
text and pattern: "abcd"<br />
Regex pattern: "((a|ab)(c|bcd))(d*)"<br />
Outputs agree: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
<br />
Expected Pass #6<br />
text and pattern: "abcd"<br />
Regex pattern: "((a|ab)(bcd|c))(d*)"<br />
Outputs agree: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
<br />
############################# Unexpected Fail # 7 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "((ab|a)(c|bcd))(d*)"<br />
Expected output: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
Actual result : "(0,4)(0,3)(0,2)(2,3)(3,4)"<br />
<br />
############################# Unexpected Fail # 8 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "((ab|a)(bcd|c))(d*)"<br />
Expected output: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
Actual result : "(0,4)(0,3)(0,2)(2,3)(3,4)"<br />
</pre><br />
In the above the extra parenthesis around the first two subexpression<br />
ought to have forced the pair to match the longest possible string<br />
"abcd" from (0,4). But #7 and #8 failed to match this because "ab"<br />
was greedily chosen.<br />
<br />
This greedy approach is not entirely consistent, see "repetition2.txt" #108:<br />
<pre><br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){8,}Y"<br />
Expected output: "(0,9)(8,8)"<br />
Actual result : "(0,9)(7,8)"<br />
</pre><br />
The first seven repetitions should match 1234567 and the 8th<br />
repetition would then match an empty string at (8,8) after the "7" and<br />
before the "Y". But GLIBC does something I do not understand and<br />
ensures that the last repetition is not empty.<br />
<br />
Another not-greedy-enough example is "basic3.txt" #71:<br />
<pre><br />
Searched text: "-"<br />
Regex pattern: "(^)*"<br />
Expected output: "(0,0)(0,0)"<br />
Actual result : "(0,0)(-1,-1)"<br />
</pre><br />
The ^ should match and capture at (0,0), but GLIBC uses zero<br />
repetitions of (^). Changing "*" to "+" causes GLIBC to correctly<br />
return the capture at (0,0).<br />
<br />
== Solaris C library ==<br />
<br />
Christian Maeder ran regex-posix-unittest and sent in Solaris 10 results with the message:<br />
<pre><br />
Same results for:<br />
SunOS 5.10 Generic_138889-03 i86pc i386 i86pc<br />
SunOS 5.10 Generic_138888-02 sun4u sparc SUNW,Sun-Fire-280R<br />
</pre><br />
<br />
The summary is <br />
<pre><br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/basic3.txt",[4,65,67,71,76])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/class.txt",[3,5])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/left-assoc.txt",[-1,-2,-9,-10])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/right-assoc.txt",[1,2,9,10])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/forced-assoc.txt",[7,8,9,10,13,14,15,16,19,20,21,22,27])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/nullsub3.txt",[2,18,26,38,40,46])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/repetition2.txt",[])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/totest.txt",[3,5,24,26,27,42,43,44,45,110,204,211,212])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[])<br />
</pre><br />
<br />
The above is similar to but not the same as the GLIBC bugs.<br />
<br />
The "basic3.txt" #4 is a syntax error reported for the "^$" pattern,<br />
which seems allowed to me: Error message: (ReturnCode 22,"unknown regex error")<br />
<br />
The "basic3.txt" #65 is a new bug:<br />
<pre><br />
Searched text: "-"<br />
Regex pattern: "(a*)*"<br />
Expected output: "(0,0)(0,0)"<br />
Actual result : "(0,0)(-1,-1)"<br />
</pre><br />
<br />
The "a*" can accept 0 characters so (a*)* should match once at (0,0). There are several other examples of this in "basic3.txt" and "nullsub3.txt"<br />
<br />
The too-greedy behavior of GLIBC and the lack of forced association is present in the Solaris bugs.<br />
<br />
But in "forced-assoc.txt" #13 I see something far more critical! A critical bug indeed:<br />
<pre><br />
Searched text: "abc"<br />
Regex pattern: "(a*)(b|abc)"<br />
Expected output: "(0,3)(0,0)(0,3)"<br />
Actual result : "(0,2)(0,1)(1,2)"<br />
</pre><br />
Note that the whole match should be "abc" but Solaris matches only "ab". (a*) is far far too greedy!<br />
<br />
This is also caught in "totest.txt" #3, #43, #44, #45, showing #3 below:<br />
<pre><br />
Searched text: "ab"<br />
Regex pattern: "(a?)((ab)?)"<br />
Expected output: "(0,2)(0,0)(0,2)(0,2)"<br />
Actual result : "(0,1)(0,1)(1,1)(-1,-1)"<br />
</pre><br />
<br />
== AT&T Software Technology (aka AST or libast) ==<br />
<br />
AT&T Research has an [http://www.research.att.com/sw/download/ open source suite] of libraries and binaries. This includes a [http://www.research.att.com/~gsf/testregex/re-interpretation.html POSIX regular expression implementation] in the "libast" library. Most of the unit tests used here are from their [http://www.research.att.com/~gsf/testregex/ "testregex"] program.<br />
<br />
I, [[ChrisKuklewicz]], have managed to compile a "regex-ast" Haskell wrapper to this POSIX engine to allow for testing. The difficulties with the AT&T headers prevent me from releasing this to hackage. The AST engine passes the whole set of unit tests.<br />
<br />
But randomized testing has found a few (probably 2, maybe 3) bugs in the AST engine as of 2009-02-24. In return, testing against AST has lead to the regex-tdfa-0.97.4 bug fix release. As regex-tdfa and AST improve they will hopefully reach a state where no differences can be found; this will likely be a fully correct state since their designs and implementations are completely different.<br />
<br />
<pre><br />
Bug in AST engine<br />
Pattern: "((.?)?)*."<br />
Text to search: "x"<br />
Expected: (0,1)(0,0)(0,0)<br />
Returned: (0,1)(0,0)(-1,-1)<br />
<br />
For the next group the Text to search is "x" and<br />
Expected: (0,0)(0,0)(0,0)<br />
Pattern and Returned:<br />
"((.?)?){0,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){3,}." (0,0)(0,0)(-1,-1)<br />
<br />
"((.?)?){0,1}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,2}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,2}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,3}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,3}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,3}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){3,4}." (0,0)(0,0)(0,0) <br />
</pre><br />
<br />
If someone else is interested in "regex-ast" then write to me at "haskell _at_ mightyreason _dot_ com".<br />
<br />
= Other implementations =<br />
<br />
== Boost (C++ library) ==<br />
<br />
There is a [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/index.html Boost Regex] library, which includes [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/ref/posix.html "POSIX Compatible C API's"]. But their definition of the [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/syntax/leftmost_longest_rule.html "The Leftmost Longest Rule"] is a different interpretation than the POSIX standard described above.<br />
<br />
In the POSIX standard, the rule applies to subpatterns, regardless of capturing. Boost only applies it to captured subexpressions. Their [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/background_information/faq.html FAQ] explains:<br />
<br />
; Q. Why does using parenthesis in a POSIX regular expression change the result of a match?<br />
<br />
: A. For POSIX (extended and basic) regular expressions, but not for perl regexes, parentheses don't only mark; they determine what the best match is as well. When the expression is compiled as a POSIX basic or extended regex then Boost.Regex follows the POSIX standard leftmost longest rule for determining what matched. So if there is more than one possible match after considering the whole expression, it looks next at the first sub-expression and then the second sub-expression and so on. So...<br />
<br />
: "(0*)([0-9]*)" against "00123" would produce $1 = "00" $2 = "123"<br />
<br />
: where as<br />
<br />
: "0*([0-9])*" against "00123" would produce $1 = "00123"<br />
<br />
:If you think about it, had $1 only matched the "123", this would be "less good" than the match "00123" which is both further to the left and longer. If you want $1 to match only the "123" part, then you need to use something like:<br />
<br />
: "0*([1-9][0-9]*)"<br />
<br />
The POSIX subpattern rules would always have the "0*" match "00" and the "[0-9]*" match "123", regardless of whether either is parenthesized.<br />
<br />
== HSRex / Postgresql / TCL ==<br />
<br />
This is from [http://www.arglist.com/regex/] which is named after Henry Spencer. This has been used in TCL 8.2 (at least) and postgresql 7.4 (at least) and wxWidgets. I tested the "Walter Waldo's port" listed on that page (hsrex.tar.gz). It has a different spectrum of non-Posix bugs. An interesting new one is:<br />
<br />
<pre><br />
test '(aba|ab|a)*' 'ababa'<br />
(0,5)(4,5)<br />
</pre><br />
<br />
Where the expected answer is (0,5)(2,5). It has picked a possible match, but has not maximized the second capture, using (ab) instead of (aba). It finds the right answer for explicit repetitions because it does find the longest match:<br />
<br />
<pre><br />
test '(aba|ab|a)(aba|ab|a)' 'ababa'<br />
(0,5)(0,2)(2,5)<br />
</pre><br />
<br />
<pre><br />
test '(aba|ab|a)(aba|ab|a)(aba|ab|a)' 'ababa'<br />
(0,5)(0,2)(2,4)(4,5)<br />
</pre></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Regex_Posix&diff=61612Regex Posix2017-03-10T03:19:43Z<p>HowardBGolden: /* regex-posix Bugs */ Update link to Glenn Fowler</p>
<hr />
<div>= regex-posix Bugs =<br />
<br />
Executive summary: If you want a bug-free and/or portable POSIX extended regular expression library to use from Haskell, then regex-posix will not help you. You should use the regex-tdfa package instead.<br />
<br />
The regular expressions provided by the GHC bundle (up to 6.10.1) are<br />
through a wrapping of the operating system's native C library. The C<br />
library calls in<br />
[http://www.opengroup.org/onlinepubs/009695399/basedefs/regex.h.html "regex.h"]<br />
have been imported via FFI and wrapped by<br />
[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/regex-posix regex-posix]<br />
, either the older 0.72.* version or the newer version (> 0.94.*).<br />
Note that the matchAll semantics changed in regex-posix with version<br />
0.94.0 (see mailing list announcement).<br />
<br />
Unfortunately the native platforms provide Posix regular expressions<br />
support that contains bugs and/or violates the<br />
[http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html specification]. This is especially true for the GNU C library (GLIBC)<br />
used by Linux distributions and the BSD C library used by OS X and<br />
FreeBSD and NetBSD (XBSD). More discussion of the standard is<br />
available from [http://gsf.cococlyde.org/download Glenn Fowler]<br />
formerly of AT&T Labs.<br />
<br />
A capsule summary of the Posix rules:<br />
* regular expressions (REs) take the leftmost starting match, and the longest match starting there<br />
* earlier subpatterns have leftmost-longest priority over later subpatterns<br />
* higher-level subpatterns have leftmost-longest priority over their component subpatterns<br />
* REs have right associative concatenation which can be changed with parenthesis<br />
* parenthesized subexpressions return the match from their last usage<br />
* text of component subexpressions must be contained in the text of the higher-level subexpressions<br />
* if "p" and "q" can never match the same text then "p|q" and "q|p" are equivalent, up to trivial renumbering of captured subexpressions<br />
* if "p" in "p*" is used to capture non-empty text then additional repetitions of "p" will not capture an empty string<br />
<br />
All of the above rules will be violated by one or another bug described below.<br />
<br />
= regex-posix-unittest =<br />
<br />
Many of these unittests come from<br />
[http://www.research.att.com/~gsf/testregex/testregex.html testregex by AT&T]<br />
, the rest from the author of regex-tdfa ([[ChrisKuklewicz]]). Note<br />
that all of these tests are passed by regex-tdfa-0.97.1 (but not below<br />
this). Since then additional bugs have been found and fixed, so regex-tdfa is now<br />
on at least version 0.97.4, and a future regex-posix-unittest may include the<br />
additional test cases.<br />
<br />
These problems are documented here, but examples of the bugs are<br />
testable on your system by way of the regex-posix-unittest package on<br />
Hackage. This package can be installed either as "--user" or<br />
"--global", and provides three things:<br />
<br />
# The "regex-posix-unittest" binary executable<br />
# The "test-manifest.txt" file which lists files to load test from<br />
# A set of ".txt" files containing one unit test per line<br />
<br />
Running the regex-posix-unittest program produces output for the<br />
passing or failing of each test in each file listed in "test-manifest.txt",<br />
which is shipped listing all the test files. This is followed a<br />
summary list of failing test id numbers.<br />
<br />
Each unit test line has four fields, separated by white-space (one tab<br />
in the above):<br />
<br />
# The test identification Int, negative if this is expected to fail<br />
# The regular expression pattern (extended regular expression)<br />
# The text to search (no white-space) # The expected result<br />
## NOMATCH if the matching should fail ## "(n,m)(..)" if the match succeeds<br />
##* Each pair of numbers denotes a substring of the text to search as two 0-based indexes<br />
##* The length of the substring is (m-n)<br />
##* The first pair is the whole match, further pairs are for parenthesized subexpression captures<br />
##* Subexpressions that do not match are lists as "(?,?)" instead of with numbers<br />
<br />
You can add and delete but please do not change existing tests.<br />
<br />
If your platform is not mentioned in this wiki page (see below) then<br />
please either add it and your summary results or email the results to<br />
"TestRegexLazy -at- mightyreason -dot- com".<br />
<br />
One can also pass two strings to "regex-posix-unittest" to run your own test:<br />
<pre><br />
user@ubuntu810desktop:~/test/regex-posix-unittest$ ~/.cabal/bin/regex-posix-unittest "abcd" "([^c])+"<br />
Test for [Char], Version {versionBranch = [1,0], versionTags = []}<br />
"abcd"<br />
"([^c])+"<br />
Posix<br />
("","ab","cd",["b"])<br />
POSIX count = (2,2)<br />
array (0,1) [(0,(0,2)),(1,(1,1))]<br />
array (0,1) [(0,(3,1)),(1,(3,1))]<br />
</pre><br />
<br />
This actually is a slightly return format. The strings are echoed and<br />
the ("","ab","cd",["b"]) is the "" before the first match, the "ab" of<br />
the whole first match, and the "cd" after the first match, which the<br />
captures in the list ["b"]. The arrays lines are the results of<br />
consecutive non-overlapping matches, in (capture #, (start index,<br />
length)) format. So (1,(1,1)) is the 1st parenthesis and starts after<br />
the 1st character and is 1 character long: "b". The (1,(3,1)) is "d".<br />
<br />
= Types of failure =<br />
<br />
There are four classes of failures:<br />
# Critical failures that find the wrong whole match (XBSD as of January 2009, Solaris)<br />
# Serious failures that find impossible subexpressions (XBSD)<br />
# Serious failures that violate well-formed subexpressions (GLIBC)<br />
# Failure to choose Posix captures when the answer is ambiguous (GLIBC, XBSD, Solaris)<br />
<br />
Example of an ambiguous situation: Matching "a" with the the pattern<br />
"(.)?(a)?" or the pattern "(.)|(a)". Each pattern can use either<br />
"(.)" or "(a)" to match the "a', but not both; thus only one of the<br />
two subexpressions must succeed and the other must fail. In this case<br />
the right answer is that "(.)" succeeds in both cases, so the full<br />
answer is (0,1)(0,1)(?,?). The first pattern uses the right<br />
associativity rule for concatenation and the second pattern uses the<br />
leftmost subpattern bias.<br />
<br />
= Results and Bugs =<br />
<br />
== OS X, FreeBSD, NetBSD ==<br />
<br />
On a G4 version of OS X 10.5.6 I see:<br />
<pre><br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/basic3.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/class.txt",[3,9])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/left-assoc.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/right-assoc.txt",[])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/forced-assoc.txt",[5,6,7,8,15,16,21,22])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/nullsub3.txt",[50,51])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/repetition2.txt",[101,102,103,104,105,106,107,<br />
110,111,112,113,114,115,116,117,260,261,262,263,266,267,268,270,271])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/totest.txt",[5,30,33,209])<br />
("/Users/chrisk/local/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[1,-1,2,-2,3,-3,14,-14])<br />
</pre><br />
The "osx-bsd-critical.txt" unexpected failures are:<br />
<pre><br />
############################# Unexpected Fail # 1 #############################<br />
<br />
Searched text: "ab"<br />
Regex pattern: "(()|.)(b)"<br />
Expected output: "(0,2)(0,1)(-1,-1)(1,2)"<br />
Actual result : "(1,2)(1,1)(1,1)(1,2)"<br />
<br />
############################# Unexpected Fail # 2 #############################<br />
<br />
Searched text: "ab"<br />
Regex pattern: "(()|[ab])(b)"<br />
Expected output: "(0,2)(0,1)(-1,-1)(1,2)"<br />
Actual result : "(1,2)(1,1)(1,1)(1,2)"<br />
<br />
############################# Unexpected Fail # 3 #############################<br />
<br />
Searched text: "aaab"<br />
Regex pattern: "(()|[ab])+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(3,4)(3,3)(3,3)"<br />
<br />
############################# Unexpected Fail # 14 #############################<br />
<br />
Searched text: "aaab"<br />
Regex pattern: "([ab]|())+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(0,4)(3,3)(3,3)"<br />
</pre><br />
<br />
Tests 1 and 2 should match the whole (0,2) or "ab" but only match the<br />
(1,2) of "b". Test 3 should match the (0,3) of "aabb" but only<br />
matches the (3,4) of "b". These are critical failures to match the<br />
whole text properly. This problem was found by QuickCheck and<br />
reported to OS X and FreeBSD and NetBSD (the latter two checked over<br />
IRC). OpenBSD reportedly did not show this bug (anecdote on IRC).<br />
<br />
This also infects sed, and can be seen as<br />
<pre><br />
prompt$ echo "ab" | sed -En 's/(()|.)(b)/[&][\1]/p'<br />
a[b][]<br />
</pre><br />
instead of the correct "[ab][a]" output.<br />
<br />
The failure in Test 14 is different. Instead of the whole match being<br />
wrong the pattern being repeated by the "+" operator is matched 3<br />
times against "a" and "a" and "a", followed by a fourth empty match at<br />
(3,3) before the final "b". Once the repeated pattern "[ab]|()" has<br />
matched a non-empty string it should not be used to match an<br />
empty-string.<br />
<br />
OS X also gets this wrong in "totext.txt" #209:<br />
<pre><br />
Searched text: "yyyyyy"<br />
Regex pattern: "(yyy|(x?)){2,4}"<br />
Expected output: "(0,6)(3,6)(-1,-1)"<br />
Actual result : "(0,6)(6,6)(6,6)"<br />
</pre><br />
where the (x?) matches the empty string at (6,6) instead of stopping<br />
after 2 repetitions of "yyy".<br />
<br />
But OS X is getting this right on numerous tests in "nullsub3.txt" such as<br />
<pre><br />
Expected Pass #8<br />
text and pattern: "a"<br />
Regex pattern: "(a*)*"<br />
Outputs agree: "(0,1)(0,1)"<br />
<br />
Expected Pass #47<br />
text and pattern: "ax"<br />
Regex pattern: "(a*)*(x)"<br />
Outputs agree: "(0,2)(0,1)(1,2)"<br />
</pre><br />
<br />
Where (a*) matches "a" and is reported as (0,1) and the no additional repetition<br />
matches the empty string at (1,1).<br />
<br />
The OS X failure in "totest.txt" #33 illustrates the "impossible" capture:<br />
<pre><br />
Searched text: "ababa"<br />
Regex pattern: "(aba|ab|a)*"<br />
Expected output: "(0,5)(2,5)"<br />
Actual result : "(0,5)(0,3)"<br />
</pre><br />
The whole match is (0,5) and the correct repetition has "ab" then<br />
"aba" matching, so the correct last repetition is the "aba" between<br />
indexes (2,5). The OS X code recognizes the whole match then does a<br />
second pass of greedy repetitions, so the first repetition is "aba"<br />
between indexes (0,3). The OS X code then fails to match the "ba" in<br />
this second pass but not care. It is logically impossible that the<br />
last iteration of the above subexpression ends before the whole match,<br />
but OS X reports the last repetition ended at index 3 even though the<br />
whole match ends at index 5.<br />
<br />
This is also shown in numerous failed tests in "repetition2.txt" such as #260:<br />
<pre><br />
Searched text: "ababcd"<br />
Regex pattern: "(a|ab|c|bcd){0,}(d*)"<br />
Expected output: "(0,6)(3,6)(6,6)"<br />
Actual result : "(0,6)(4,5)(6,6)"<br />
</pre><br />
The correct repetitions are "ab" then "a" then "bcd", reported as (3,6). The incorrect greedy pass uses by OS X matches "ab" then "c" as (4,5) and then gives up even though (5,6) is still not matched in the second pass. As a sed test:<br />
<pre><br />
prompt$ echo "ababcd" | sed -En 's/(a|ab|c|bcd)*/[&][\1]/p'<br />
[ababcd][c]<br />
</pre><br />
The above output should be impossible; the correct output is [ababcd][bcd].<br />
<br />
The "forced-assoc.txt" failures show that one cannot use parenthesis<br />
to force the naturally right associative concatenation to be left<br />
associative. This is a violation of the Posix standard, and of the<br />
"man 7 re_format" page form OS X 10.5.6: "Subexpressions also match<br />
the longest possible substrings, subject to the constraint that the<br />
whole match be as long as possible, with subexpressions starting<br />
earlier in the RE taking priority over ones starting later. Note that<br />
higher-level subexpressions thus take priority over their lower-level<br />
component subexpressions". Take #15 as an example:<br />
<pre><br />
Searched text: "abc"<br />
Regex pattern: "((a*)(b|abc))(c*)"<br />
Expected output: "(0,3)(0,3)(0,0)(0,3)(3,3)"<br />
Actual result : "(0,3)(0,2)(0,1)(1,2)(2,3)"<br />
</pre><br />
Here ((a*)(b|abc))(c*) should be parsed as ((a*)(b|abc)) followed by<br />
(c*). As ((a*)(b|abc)) started earlier it should be as long as<br />
possible, at the expense of (c*). The longest match for this is the<br />
correct (0,3) not the incorrect (0,2) returned by OS X. And<br />
((a*)(b|abc)) is a higher-level than its lower-level component (a*),<br />
so (a*) should match with the side constraint that ((a*)(b|abc))<br />
matches (0,3), which means (a*) should match (0,0) instead of the<br />
longer (0,1). OS X gets this associativity this wrong.<br />
<br />
In "repetitions2.txt" there is a series:<br />
<pre><br />
Expected Pass #100<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){0,}Y"<br />
Outputs agree: "(0,9)(7,8)"<br />
<br />
############################# Unexpected Fail # 101 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){1,}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
...<br />
############################# Unexpected Fail # 107 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){7,}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
Expected Pass #108<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){8,}Y"<br />
Outputs agree: "(0,9)(8,8)"<br />
<br />
############################# Unexpected Fail # 110 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){0,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
############################# Unexpected Fail # 111 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){1,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
...<br />
<br />
############################# Unexpected Fail # 117 #############################<br />
<br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){7,8}Y"<br />
Expected output: "(0,9)(7,8)"<br />
Actual result : "(0,9)(8,8)"<br />
<br />
Expected Pass #118<br />
text and pattern: "X1234567Y"<br />
Regex pattern: "X(.?){8,8}Y"<br />
Outputs agree: "(0,9)(8,8)"<br />
</pre><br />
<br />
The good news is that #108 and #118 are correct, as the last<br />
repetition is forced to match the empty string after the "7" and<br />
before the "Y". The {1,} through {7,} and {1,8} through {7,8} are all<br />
wrong: they all should match the "7" at (7,8) but XBSD returns the<br />
null at (8,8). The {0,} answer is right, but {0,8} and {1,} are both<br />
wrong. So {0,} seems to handled specially, probably because {0,} is<br />
precisely the "*" operator, though the wrong {1,} is precisely the "+"<br />
operator.<br />
<br />
The failures of XBSD in "repetitions2.txt" in the 260 to 271 range<br />
show a different ambiguity where {0,} is not matched correctly. It<br />
gets these wrong by being greedy in the expanded form of the {n,m}<br />
operators. The "a|ab|c|bcd" should choose "ab" then "a" then "bcd" at<br />
(3,6) to match "ababcd", then (d*) should match nothing at (6,6). But<br />
XBSD is matching "ab" then "ab" then "c" at (4,5) and then uses (d*)<br />
to match the last "d" at (5,6). Changing the pattern to<br />
"((a|ab|c|bcd){3,10})(d*)" fails to force the grouping and<br />
associativity.<br />
<br />
== OpenBSD ==<br />
<br />
There is no report from OpenBSD. One would be quite welcome!<br />
<br />
== GNU C library (aka GLIBC) ==<br />
<br />
The system being tested is a current Ubuntu 8.10 distribution:<br />
<pre><br />
user@ubuntu810desktop:~$ uname -a<br />
Linux ubuntu810desktop 2.6.27-11-generic #1 SMP Wed Jan 28 00:02:01 UTC 2009 i686 GNU/Linux<br />
</pre><br />
The failing tests are<br />
<pre><br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/basic3.txt",[71])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/class.txt",[3,5,10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/left-assoc.txt",[-1,-2,-9,-10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/right-assoc.txt",[1,2,9,10])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/forced-assoc.txt",[7,8,9,10,15,16,21,22,27])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/nullsub3.txt",[41])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/repetition2.txt",[26,28,34,41,42,108,110,111,112,113,114,115,116])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/totest.txt",[5,24,26,27,36,42,83,84,110,206,207,208,209,215,250,251])<br />
("/home/user/.cabal/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[3])<br />
</pre><br />
<br />
The GLIBC engine has an API for its own GNU regular expression<br />
standard which differs from Posix. It also exposes a Posix compatible<br />
"regex.h" API, and GNU sed has a "--posix" switch. But the library is<br />
not really trying to get the Posix answer.<br />
<br />
First is nested subexpressions. In Posix sets of nested parenthesis<br />
that return captures must return nested captures: the inner<br />
subexpressions return substrings of the outer substrings. Consider<br />
"totest.txt" #215:<br />
<pre><br />
Searched text: "ab"<br />
Regex pattern: "((a)|(b)){2,}"<br />
Expected output: "(0,2)(1,2)(-1,-1)(1,2)"<br />
Actual result : "(0,2)(1,2)(0,1)(1,2)"<br />
</pre><br />
Where "(a)" matches the "a" at (0,1), and the next repetion matches<br />
"(b)" matches the "b" at (1,2). Under Posix rules the "(a)" did not<br />
match in the last use of the parent subexpression ((a)|(b)), so it<br />
should be (-1,-1). Under GLIBC rules it should return (0,1). The<br />
above could largely be fixed by a filter that unsets child patterns<br />
that are not properly nested, though I worry about edge cases and<br />
empty matches.<br />
<br />
In GLIBC this is not the case, take "osx-bsd-critical" #3 and #14 as an example:<br />
<pre><br />
############################# Unexpected Fail # 3 #############################<br />
Searched text: "aaab"<br />
Regex pattern: "(()|[ab])+b"<br />
Expected output: "(0,4)(2,3)(-1,-1)"<br />
Actual result : "(0,4)(2,3)(0,0)"<br />
<br />
Expected Pass #14<br />
text and pattern: "aaab"<br />
Regex pattern: "([ab]|())+b"<br />
Outputs agree: "(0,4)(2,3)(-1,-1)"<br />
</pre><br />
<br />
In #3, the "()" does match at the initial position, so it gets its<br />
capture reported, even though (0,0) is not a substring of (2,3). This<br />
is contradicted by #14 where "()" does not match at the initial<br />
position. This is an example of where "p|q" should be the same as<br />
"q|p" but returns a different answer.<br />
<br />
The failure of some of the "right-assoc.txt" tests shows that GLIBC<br />
uses neither right nor left associative concatenation:<br />
<pre><br />
############################# Unexpected Fail # 1 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "(a|ab)(c|bcd)(d*)"<br />
Expected output: "(0,4)(0,2)(2,3)(3,4)"<br />
Actual result : "(0,4)(0,1)(1,4)(4,4)"<br />
<br />
############################# Unexpected Fail # 2 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "(a|ab)(bcd|c)(d*)"<br />
Expected output: "(0,4)(0,2)(2,3)(3,4)"<br />
Actual result : "(0,4)(0,1)(1,4)(4,4)"<br />
<br />
Expected Pass #3<br />
text and pattern: "abcd"<br />
Regex pattern: "(ab|a)(c|bcd)(d*)"<br />
Outputs agree: "(0,4)(0,2)(2,3)(3,4)"<br />
<br />
Expected Pass #4<br />
text and pattern: "abcd"<br />
Regex pattern: "(ab|a)(bcd|c)(d*)"<br />
Outputs agree: "(0,4)(0,2)(2,3)(3,4)"<br />
</pre><br />
<br />
Test #1 through #4 check all four orderings of "a" versus "ab" and "c"<br />
versus "bcd". And GLIBC seems to be applying a greedy strategy to the<br />
"a" or "ab" subpattern. Consider these in "forced-assoc.txt":<br />
<pre><br />
Expected Pass #5<br />
text and pattern: "abcd"<br />
Regex pattern: "((a|ab)(c|bcd))(d*)"<br />
Outputs agree: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
<br />
Expected Pass #6<br />
text and pattern: "abcd"<br />
Regex pattern: "((a|ab)(bcd|c))(d*)"<br />
Outputs agree: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
<br />
############################# Unexpected Fail # 7 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "((ab|a)(c|bcd))(d*)"<br />
Expected output: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
Actual result : "(0,4)(0,3)(0,2)(2,3)(3,4)"<br />
<br />
############################# Unexpected Fail # 8 #############################<br />
<br />
Searched text: "abcd"<br />
Regex pattern: "((ab|a)(bcd|c))(d*)"<br />
Expected output: "(0,4)(0,4)(0,1)(1,4)(4,4)"<br />
Actual result : "(0,4)(0,3)(0,2)(2,3)(3,4)"<br />
</pre><br />
In the above the extra parenthesis around the first two subexpression<br />
ought to have forced the pair to match the longest possible string<br />
"abcd" from (0,4). But #7 and #8 failed to match this because "ab"<br />
was greedily chosen.<br />
<br />
This greedy approach is not entirely consistent, see "repetition2.txt" #108:<br />
<pre><br />
Searched text: "X1234567Y"<br />
Regex pattern: "X(.?){8,}Y"<br />
Expected output: "(0,9)(8,8)"<br />
Actual result : "(0,9)(7,8)"<br />
</pre><br />
The first seven repetitions should match 1234567 and the 8th<br />
repetition would then match an empty string at (8,8) after the "7" and<br />
before the "Y". But GLIBC does something I do not understand and<br />
ensures that the last repetition is not empty.<br />
<br />
Another not-greedy-enough example is "basic3.txt" #71:<br />
<pre><br />
Searched text: "-"<br />
Regex pattern: "(^)*"<br />
Expected output: "(0,0)(0,0)"<br />
Actual result : "(0,0)(-1,-1)"<br />
</pre><br />
The ^ should match and capture at (0,0), but GLIBC uses zero<br />
repetitions of (^). Changing "*" to "+" causes GLIBC to correctly<br />
return the capture at (0,0).<br />
<br />
== Solaris C library ==<br />
<br />
Christian Maeder ran regex-posix-unittest and sent in Solaris 10 results with the message:<br />
<pre><br />
Same results for:<br />
SunOS 5.10 Generic_138889-03 i86pc i386 i86pc<br />
SunOS 5.10 Generic_138888-02 sun4u sparc SUNW,Sun-Fire-280R<br />
</pre><br />
<br />
The summary is <br />
<pre><br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/basic3.txt",[4,65,67,71,76])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/class.txt",[3,5])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/left-assoc.txt",[-1,-2,-9,-10])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/right-assoc.txt",[1,2,9,10])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/forced-assoc.txt",[7,8,9,10,13,14,15,16,19,20,21,22,27])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/nullsub3.txt",[2,18,26,38,40,46])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/repetition2.txt",[])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/totest.txt",[3,5,24,26,27,42,43,44,45,110,204,211,212])<br />
("/home/maeder/.cabal/share/regex-posix-unittest-1.0/osx-bsd-critical.txt",[])<br />
</pre><br />
<br />
The above is similar to but not the same as the GLIBC bugs.<br />
<br />
The "basic3.txt" #4 is a syntax error reported for the "^$" pattern,<br />
which seems allowed to me: Error message: (ReturnCode 22,"unknown regex error")<br />
<br />
The "basic3.txt" #65 is a new bug:<br />
<pre><br />
Searched text: "-"<br />
Regex pattern: "(a*)*"<br />
Expected output: "(0,0)(0,0)"<br />
Actual result : "(0,0)(-1,-1)"<br />
</pre><br />
<br />
The "a*" can accept 0 characters so (a*)* should match once at (0,0). There are several other examples of this in "basic3.txt" and "nullsub3.txt"<br />
<br />
The too-greedy behavior of GLIBC and the lack of forced association is present in the Solaris bugs.<br />
<br />
But in "forced-assoc.txt" #13 I see something far more critical! A critical bug indeed:<br />
<pre><br />
Searched text: "abc"<br />
Regex pattern: "(a*)(b|abc)"<br />
Expected output: "(0,3)(0,0)(0,3)"<br />
Actual result : "(0,2)(0,1)(1,2)"<br />
</pre><br />
Note that the whole match should be "abc" but Solaris matches only "ab". (a*) is far far too greedy!<br />
<br />
This is also caught in "totest.txt" #3, #43, #44, #45, showing #3 below:<br />
<pre><br />
Searched text: "ab"<br />
Regex pattern: "(a?)((ab)?)"<br />
Expected output: "(0,2)(0,0)(0,2)(0,2)"<br />
Actual result : "(0,1)(0,1)(1,1)(-1,-1)"<br />
</pre><br />
<br />
== AT&T Software Technology (aka AST or libast) ==<br />
<br />
AT&T Research has an [http://www.research.att.com/sw/download/ open source suite] of libraries and binaries. This includes a [http://www.research.att.com/~gsf/testregex/re-interpretation.html POSIX regular expression implementation] in the "libast" library. Most of the unit tests used here are from their [http://www.research.att.com/~gsf/testregex/ "testregex"] program.<br />
<br />
I, [[ChrisKuklewicz]], have managed to compile a "regex-ast" Haskell wrapper to this POSIX engine to allow for testing. The difficulties with the AT&T headers prevent me from releasing this to hackage. The AST engine passes the whole set of unit tests.<br />
<br />
But randomized testing has found a few (probably 2, maybe 3) bugs in the AST engine as of 2009-02-24. In return, testing against AST has lead to the regex-tdfa-0.97.4 bug fix release. As regex-tdfa and AST improve they will hopefully reach a state where no differences can be found; this will likely be a fully correct state since their designs and implementations are completely different.<br />
<br />
<pre><br />
Bug in AST engine<br />
Pattern: "((.?)?)*."<br />
Text to search: "x"<br />
Expected: (0,1)(0,0)(0,0)<br />
Returned: (0,1)(0,0)(-1,-1)<br />
<br />
For the next group the Text to search is "x" and<br />
Expected: (0,0)(0,0)(0,0)<br />
Pattern and Returned:<br />
"((.?)?){0,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){3,}." (0,0)(0,0)(-1,-1)<br />
<br />
"((.?)?){0,1}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,2}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,2}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,3}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,3}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,3}." (0,0)(0,0)(0,0)<br />
<br />
"((.?)?){0,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){1,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){2,4}." (0,0)(0,0)(-1,-1)<br />
"((.?)?){3,4}." (0,0)(0,0)(0,0) <br />
</pre><br />
<br />
If someone else is interested in "regex-ast" then write to me at "haskell _at_ mightyreason _dot_ com".<br />
<br />
= Other implementations =<br />
<br />
== Boost (C++ library) ==<br />
<br />
There is a [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/index.html Boost Regex] library, which includes [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/ref/posix.html "POSIX Compatible C API's"]. But their definition of the [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/syntax/leftmost_longest_rule.html "The Leftmost Longest Rule"] is a different interpretation than the POSIX standard described above.<br />
<br />
In the POSIX standard, the rule applies to subpatterns, regardless of capturing. Boost only applies it to captured subexpressions. Their [http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/boost_regex/background_information/faq.html FAQ] explains:<br />
<br />
; Q. Why does using parenthesis in a POSIX regular expression change the result of a match?<br />
<br />
: A. For POSIX (extended and basic) regular expressions, but not for perl regexes, parentheses don't only mark; they determine what the best match is as well. When the expression is compiled as a POSIX basic or extended regex then Boost.Regex follows the POSIX standard leftmost longest rule for determining what matched. So if there is more than one possible match after considering the whole expression, it looks next at the first sub-expression and then the second sub-expression and so on. So...<br />
<br />
: "(0*)([0-9]*)" against "00123" would produce $1 = "00" $2 = "123"<br />
<br />
: where as<br />
<br />
: "0*([0-9])*" against "00123" would produce $1 = "00123"<br />
<br />
:If you think about it, had $1 only matched the "123", this would be "less good" than the match "00123" which is both further to the left and longer. If you want $1 to match only the "123" part, then you need to use something like:<br />
<br />
: "0*([1-9][0-9]*)"<br />
<br />
The POSIX subpattern rules would always have the "0*" match "00" and the "[0-9]*" match "123", regardless of whether either is parenthesized.<br />
<br />
== HSRex / Postgresql / TCL ==<br />
<br />
This is from [http://www.arglist.com/regex/] which is named after Henry Spencer. This has been used in TCL 8.2 (at least) and postgresql 7.4 (at least) and wxWidgets. I tested the "Walter Waldo's port" listed on that page (hsrex.tar.gz). It has a different spectrum of non-Posix bugs. An interesting new one is:<br />
<br />
<pre><br />
test '(aba|ab|a)*' 'ababa'<br />
(0,5)(4,5)<br />
</pre><br />
<br />
Where the expected answer is (0,5)(2,5). It has picked a possible match, but has not maximized the second capture, using (ab) instead of (aba). It finds the right answer for explicit repetitions because it does find the longest match:<br />
<br />
<pre><br />
test '(aba|ab|a)(aba|ab|a)' 'ababa'<br />
(0,5)(0,2)(2,5)<br />
</pre><br />
<br />
<pre><br />
test '(aba|ab|a)(aba|ab|a)(aba|ab|a)' 'ababa'<br />
(0,5)(0,2)(2,4)(4,5)<br />
</pre></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Base_package&diff=61278Base package2016-11-08T18:43:01Z<p>HowardBGolden: /* Versions */ Add 7.10.2 and 7.10.3</p>
<hr />
<div>The '''base package''' contains the [[Prelude]] and its support libraries, and a large collection of useful libraries ranging from data structures to parsing combinators and debugging utilities. It is specific to the GHC implementation of Haskell.<br />
<br />
This package includes the following: <br />
<br />
*[[Arrays]]<br />
<br />
*[[Arrow]]s<br />
<br />
*[[Functor]]s<br />
<br />
*[[Maybe]]<br />
<br />
*[[Monad]]s<br />
<br />
and many others.<br />
<br />
== Versions ==<br />
<br />
The base package is shipped alongside the GHC compiler itself, but version numbers for the base package do not match the GHC version number. Here is a table indicating which base package versions ship with which GHC. Data is taken from GHC release notes, and, since base 4.7.0.0, the changelog.md file in the base package's source code. Only GHC versions in which the base package's version number was bumped are listed here. (Last updated Nov 2016.)<br />
<br />
On the GHC Trac wiki, one can find a more comprehensive [https://ghc.haskell.org/trac/ghc/wiki/Commentary/Libraries/VersionHistory table of versions that includes ''all'' boot libraries].<br />
<br />
{|<br />
|-<br />
! GHC version<br />
! base version<br />
|-<br />
| 6.10.1 (Nov 2008)<br />
| 4.0.0.0<br />
|-<br />
| 6.10.2 (Apr 2009)<br />
| 4.1.0.0<br />
|-<br />
| 6.12.1 (Dec 2009)<br />
| 4.2.0.0<br />
|-<br />
| 6.12.2 (Apr 2010)<br />
| 4.2.0.1<br />
|-<br />
| 6.12.3 (Jun 2010)<br />
| 4.2.0.2<br />
|-<br />
| 7.0.1 (Nov 2010)<br />
| 4.3.0.0<br />
|-<br />
| 7.0.2 (Mar 2011)<br />
| 4.3.1.0<br />
|-<br />
| 7.2.1 (Aug 2011)<br />
| 4.4.0.0<br />
|-<br />
| 7.2.2 (Nov 2011)<br />
| 4.4.1.0<br />
|-<br />
| 7.4.1 (Feb 2012)<br />
| 4.5.0.0<br />
|-<br />
| 7.4.2 (Jun 2012)<br />
| 4.5.1.0<br />
|-<br />
| 7.6.1 (Sep 2012)<br />
| 4.6.0.0<br />
|-<br />
| 7.6.2 (Jan 2013)<br />
| 4.6.0.1<br />
|-<br />
| 7.8.1 (Apr 2014)<br />
| 4.7.0.0<br />
|-<br />
| 7.8.3 (Jul 2014)<br />
| 4.7.0.1<br />
|-<br />
| 7.8.4 (Dec 2014)<br />
| 4.7.0.2<br />
|-<br />
| 7.10.1 (Apr 2015)<br />
| 4.8.0.0<br />
|-<br />
| 7.10.2 (Jul 2015)<br />
| 4.8.1.0<br />
|-<br />
| 7.10.3 (Dec 2015)<br />
| 4.8.2.0<br />
|-<br />
| 8.0.1 (May 2016)<br />
| 4.9.0.0<br />
|}<br />
<br />
See also the [https://hackage.haskell.org/package/base hackage page for the base package].<br />
<br />
[[Category:Standard packages]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Unboxed_type&diff=61044Unboxed type2016-08-26T22:12:44Z<p>HowardBGolden: /* See Also */ Update broken links; spell out SLPJ's name</p>
<hr />
<div>'''Unboxed types''' are [[type]]s that represent raw values. Unboxed types have [[kind]] <TT>#</TT>.<br />
<br />
Note that unboxed types of different storage behaviours (four bytes, eight bytes etc.) are all lumped together under kind <tt>#</tt>. As a result, [[type variable]]s must have kinds which are <tt>#</tt>-free.<br />
<br />
[[Category:Language]]<br />
<br />
Since Haskell values may contain unevaluated thunks in addition to specific<br />
values, in general values must be represented by a pointer to a<br />
heap-allocated object. This is fairly slow so compilers attempt to replace<br />
these boxed values with unboxed raw values when possible. Unboxed values are<br />
a feature of some compilers that allows directly manipulating these low<br />
level values. Since they behave differently than normal haskell types,<br />
generally the type system is extended to type these unboxed values. how it<br />
is done is compiler specific.<br />
<br />
[[Compiler Specific]]<br />
<br />
[[GHC]]<br />
In GHC, by convention(?), unboxed values have a hash mark as a suffix to<br />
their name. For instance, the unboxed reprsentation of <code>42</code> is<br />
<code>42#</code>. There are some restrictions to their use. In particular,<br />
you can't pass them to polymorphic functions (like <hask>show</hask> or<br />
<hask>($)</hask> for instance).<br />
<br />
In this example, <hask>I#</hask> is a constructor that takes an unboxed<br />
integer and returns the <hask>Int</hask> that we know and love.<br />
<br />
<haskell><br />
module Main where<br />
import GHC.Exts<br />
<br />
showUnboxedInt :: Int# -> String<br />
showUnboxedInt n = (show $ I# n) ++ "#"<br />
</haskell><br />
Here we wrap the unboxed Int <hask>n</hask> with the <hask>I#</hask><br />
constructor and show the regular-old <hask>Int</hask>, with a hash mark on<br />
the end.<br />
<br />
[[JHC]]<br />
<br />
Jhc unboxed values behave similarly to ghc but with some differences, jhc<br />
doesn't allow the # in identifiers so by convention uses a trailing<br />
underscore to indicate an unboxed type. However it does use the trailing<br />
hash for unboxed literals like ghc. <br />
<br />
In addition jhc allows a limited polymorphism on unboxed values, they may be<br />
used polymorphically but if an exact type is not determined at the end of<br />
typechecking, they are defaulted to specific unboxed types. So 1# can be a<br />
Bits8_, Int_ or Bool_. The rules for when polymorphic unboxed types may be<br />
used without annotation are the same as for when rank n types can be used.<br />
<br />
=== Unboxed Tuples and Arrays ===<br />
<br />
Unboxed tuples use the syntax (# a,b,c #) and may not be assigned to values, they must be immediately scrutinized or used.<br />
<br />
=== When to use Unboxed Types ===<br />
<br />
...<br />
<br />
=== See Also ===<br />
<br />
#See the [http://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#unboxed-types-and-primitive-operations discussion on unboxed types and primitive operations] in the [http://www.haskell.org/ghc/docs/latest/html/users_guide/ GHC's User's Guide].<br />
#See the [http://hackage.haskell.org/package/base/docs/GHC-Exts.html GHC.Exts] module.<br />
#See Simon L. Peyton Jones and John Launchbury's paper [https://www.microsoft.com/en-us/research/wp-content/uploads/1991/01/unboxed-values.pdf "Unboxed values as first class citizens"].<br />
<br />
----<br />
This page is a work in progress by IsaacJones. More input welcome :)</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Backpack&diff=61006Backpack2016-08-11T20:05:00Z<p>HowardBGolden: Stub to get article started</p>
<hr />
<div>See the paper: http://plv.mpi-sws.org/backpack/<br />
<br />
ABSTRACT: <br />
<br />
Module systems like that of Haskell permit only a weak form of modularity in which module implementations directly depend on other implementations and must be processed in dependency order. Module systems like that of ML, on the other hand, permit a stronger form of modularity in which explicit interfaces express assumptions about dependencies, and each module can be typechecked and reasoned about independently.<br />
<br />
In this paper, we present Backpack, a new language for building separately-typecheckable packages on top of a weak module system like Haskell's. The design of Backpack is inspired by the MixML module calculus of Rossberg and Dreyer, but differs significantly in detail. Like MixML, Backpack supports explicit interfaces and recursive linking. Unlike MixML, Backpack supports a more flexible applicative semantics of instantiation. Moreover, its design is motivated less by foundational concerns and more by the practical concern of integration into Haskell, which has led us to advocate simplicity—in both the syntax and semantics of Backpack—over raw expressive power. The semantics of Backpack packages is defined by elaboration to sets of Haskell modules and binary interface files, thus showing how Backpack maintains interoperability with Haskell while extending it with separate typechecking. Lastly, although Backpack is geared toward integration into Haskell, its design and semantics are largely agnostic with respect to the details of the underlying core language.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Parsec&diff=58840Parsec2014-09-19T21:24:31Z<p>HowardBGolden: /* Usage */ Fix broken link to homepage with web archive version</p>
<hr />
<div>{{Template:Stub}}<br />
<br />
[[Category:Compiler tools]]<br />
[[Category:Combinators]]<br />
[[Category:Packages]]<br />
[[Category:Libraries]]<br />
<br />
<br />
== Introduction ==<br />
Parsec is an industrial strength, monadic parser combinator library for<br />
Haskell. It can parse context-sensitive, infinite look-ahead grammars<br />
but it performs best on predictive (LL[1]) grammars. <br />
<br />
The latest stable release with Haddock documentation is available on [http://hackage.haskell.org/package/parsec Hackage] and development versions are [http://code.haskell.org/parsec3/ available via the Darcs repository].<br />
<br />
<br />
== Usage ==<br />
<br />
Parsec lets you construct parsers by combining higher-order<br />
[[Combinator]]s to create larger expressions. Combinator parsers are<br />
written and used within the same programming language as the rest of the<br />
program. The parsers are first-class citizens of the language, unlike<br />
[[Happy]] parsers, which must be generated via a preprocessor.<br />
<br />
An example for parsing a simple grammar of expressions can be found [http://www.haskell.org/haskellwiki/Parsing_expressions_and_statements here].<br />
<br />
Much more documentation can be found on [https://web.archive.org/web/20140528151730/http://legacy.cs.uu.nl/daan/parsec.html the parsec website].<br />
<br />
== Examples ==<br />
<br />
* [http://book.realworldhaskell.org/read/using-parsec.html "Using Parsec"] chapter on [http://book.realworldhaskell.org/ Real World Haskell].<br />
<br />
* [http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing Write Yourself a Scheme in 48 Hours/Parsing]. Note, that where the example uses the read function, the Token module of Parsec could have been used, to handle numbers.<br />
<br />
See also the [http://packdeps.haskellers.com/reverse/parsec list of reverse dependencies for Parsec].<br />
<br />
<br />
== Parsec clones in other languages ==<br />
<br />
* PCL for OCaml [http://lprousnth.files.wordpress.com/2007/08/pcl.pdf] (PDF)<br />
* JParsec for Java [http://jparsec.codehaus.org/JParsec+Overview]<br />
* NParsec, JParsec ported to C# [http://jparsec.codehaus.org/NParsec+Tutorial]<br />
* Ruby Parsec, JParsec ported to Ruby [http://jparsec.codehaus.org/Ruby+Parsec]]<br />
* FParsec for F# [http://www.quanttec.com/fparsec/]<br />
* XParsec for F# [http://corsis.github.com/XParsec/] is a type-and-source-polymorphic, generalized and extensible parsec implementation in F# 3.0 which supports powerful domain-specific non-linear navigation combinators (such as for XML trees)<br />
* Parsec-Erlang [https://bitbucket.org/dmercer/parsec-erlang/], is a faithful reproduction of Parsec in Erlang (there is also an older toy Parsec-like parser that isn't monadic, nor does it give error messages: [http://www.engr.uconn.edu/~jeffm/Source/Erlang/])<br />
* AliceParsec for Alice ML [http://www.ps.uni-sb.de/alice/contribs.html]<br />
* Parsnip for C++ [http://parsnip-parser.sourceforge.net/]<br />
* A Nemerle port [http://kriomant.net/nparsec.zip] (Zip file)<br />
* Pysec for Python [http://www.valuedlessons.com/2008/02/pysec-monadic-combinatoric-parsing-in.html]<br />
* JSParsec for JavaScript: [http://code.google.com/p/jsparsec/]<br />
* Bennu JavaScript Parser Combinator Library: [https://github.com/mattbierner/bennu/]<br />
<br />
Interesting non-Parsec parser combinator libraries:<br />
* Parse::RecDescent for Perl [https://metacpan.org/module/Parse::RecDescent]<br />
* Spirit for C++ [http://boost-spirit.com/home/doc/]<br />
<br />
== Links == <br />
<br />
=== Docs ===<br />
<br />
* [http://legacy.cs.uu.nl/daan/parsec.html on Parsec website] (old)<br />
* [http://research.microsoft.com/en-us/people/daan/ on Microsoft] <br />
<br />
=== Blog articles ===<br />
<br />
* [http://therning.org/magnus/archives/289 Adventures in parsing] by Magnus Therning <br />
* [http://therning.org/magnus/archives/290 More adventures in parsing]<br />
* [http://therning.org/magnus/archives/295 Adventures in parsing, part 3]<br />
* [http://therning.org/magnus/archives/296 Adventures in parsing, part 4]<br />
<br />
* [http://panicsonic.blogspot.com/2009/12/adventures-in-parsec.html Adventures in Parsec] by Antoine Latter<br />
<br />
=== Other ===<br />
<br />
* [http://stackoverflow.com/questions/tagged/parsec Parsec] on Stack Overflow</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Extensible_record&diff=58638Extensible record2014-08-07T23:52:27Z<p>HowardBGolden: /* Papers and libraries */ Updated link to HList paper</p>
<hr />
<div>__TOC__<br />
<br />
Proposals, implementations can be found on the [http://hackage.haskell.org/trac/haskell-prime/wiki/FirstClassLabels FirstClassLabels] page of Haskell' Wiki.<br />
<br />
== Papers and libraries ==<br />
* [[CTRex]] Extensible records as a library using closed type families and type literals.<br />
* [http://www.researchgate.net/publication/234806693_Strongly_typed_heterogeneous_collections/file/72e7e51e92fd6109e3.pdf HList – a Haskell library for strongly typed heterogeneous collections] includes also extensible records. Its relatedness to database programming is described in the articles, see also its [http://hackage.haskell.org/trac/summer-of-code/ticket/33 possible] relatedness to [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] project.<br />
* Daan Leijen: [http://www.cs.uu.nl/~daan/pubs.html#fclabels First-class labels for extensible rows]. See also the description of the Haskell-like language [http://www.cs.uu.nl/~daan/morrow/ Morrow], it is based on the concepts of the article. And [http://www.cs.uu.nl/~daan/pubs.html#scopedlabels Extensible records with scoped labels]: "We describe a natural approach to typing polymorphic and extensible records that is simple, easy to use in practice, and straightforward to implement."<br />
* Simon Peyton Jones and Greg Morrisett: [http://research.microsoft.com/~simonpj/Haskell/records.html A proposal for records in Haskell]<br />
* Mark Jones and Simon Peyton Jones: [http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
* Mark P. Jones: [http://www.cs.sfu.ca/CourseCentral/SW/Haskell/hugs/TREX A prototype implementation of extensible records for Hugs]<br />
* Didier Remy's [http://www.cs.uu.nl/wiki/Uhc/ErikKnoop#Typing_record_concatenation_for Typing record concatenation for free] on Erik Knoop's page<br />
* Benedict R. Gaster, Mark P. Jones: [http://web.cecs.pdx.edu/~mpj/pubs/polyrec.html A Polymorphic Type System for Extensible Records and Variants]<br />
* [http://www.comp.nus.edu.sg/~sulzmann/chameleon/ Chameleon], a Haskell-like language, see its [http://www.comp.nus.edu.sg/~sulzmann/chameleon/download/haskell.html#record records] [dead link as of 2011-09-15]<br />
* [[Grapefruit]] contains the package grapefruit-records which implements a record system in Haskell with GHC extensions. This record system allows field selection and dropping of fields using pattern matching. It also supports defaulting.<br />
* [http://www.informatik.tu-cottbus.de/~jeltsch/research/ppdp-2010-paper.pdf Generic Record Combinators with Static Type Checking] describes a record system with several novel features, which is provided by the [http://hackage.haskell.org/package/records records package]. It is derived from the record system of [[Grapefruit]].<br />
<br />
=== Libraries on hackage ===<br />
<br />
* [http://hackage.haskell.org/package/extensible-data extensible-data]<br />
* [http://hackage.haskell.org/package/has has]<br />
* [http://hackage.haskell.org/package/HList HList]<br />
* [http://hackage.haskell.org/package/named-records named-records]<br />
* [http://hackage.haskell.org/package/records records] / [http://hackage.haskell.org/package/grapefruit-records grapefruit-records]<br />
* [http://hackage.haskell.org/package/vinyl vinyl]<br />
<br />
== Applications ==<br />
<br />
=== Declarative database management ===<br />
<br />
Such systems can achieve more type safety (compared to direct SQL handling).<br />
They usually formulate a [[relational algebra]] concept in a declarative language.<br />
<br />
==== HaskellDB ====<br />
<br />
A problem where some concepts of extensible records could be useful is described in the [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] project. More precisely, the problem is described in the paper downloadable from<br />
* [http://haskelldb.sourceforge.net/ Chalmers version of HaskellDB] (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
* which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ Daan Leijen's original HaskellDB] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] uses its own extensible record system, but see also [[Libraries and tools/Database interfaces/HaskellDB#Future|HaskellDB#Future]].<br />
<br />
==== CoddFish ====<br />
<br />
[[Libraries and tools/Database interfaces/CoddFish|CoddFish]] is another declarative, type safe database system. As for extensible record system, it uses [http://homepages.cwi.nl/~ralf/HList/ HList --- a Haskell library for strongly typed heterogeneous collections].<br />
<br />
=== Functional Reactive Programming ===<br />
<br />
[[Functional Reactive Programming|FRP]] often makes it necessary to deal with very large tuples as arrow inputs and outputs. For example, a GUI component would receive the behavior of all its writeable properties as its input. Extensible records can therefore make FRP more usable, especially if they provide defaulting.<br />
<br />
==== Grapefruit ====<br />
<br />
[[Grapefruit]] uses extensible records which support pattern matching and defaulting for functional reactive GUI programming.<br />
<br />
== Related concepts ==<br />
<br />
[[Dependent type]] -- as an explanation for its relatedness here, see [http://www.dcs.st-andrews.ac.uk/~james/RESEARCH/ydtm-submitted.pdf Why Dependent Types Matter] written by Thorsten Altenkirch, Conor McBride, James McKinna -- or see at least its ''Conclusions'' section (section 8, pages 18--19).<br />
<br />
[[Type arithmetic]] seems to me also a way yielding some tastes from [[dependent type]] theory.<br />
<br />
[[Relational algebra]] implementations usually use extensible records.<br />
<br />
[[Category:Proposals]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=$&diff=55996$2013-05-22T23:59:31Z<p>HowardBGolden: Add note about $ signaling the start of a splice in Template Haskell</p>
<hr />
<div>'''$''' is an infix operator often seen in Haskell code. It applies the function on its left to the value on its right. At first glance this operator appears redundant, since ordinary application <hask>(f x)</hask> means the same as <hask>(f $ x)</hask>. However, <hask>$</hask> has the lowest, right-associative binding precedence (infixr 0), so it sometimes allows parentheses to be omitted; for example:<br />
<br />
f $ g $ h x = f (g (h x))<br />
<br />
If <hask>$</hask> were omitted, the parse would be different:<br />
<br />
f g h x = ((f g) h) x<br />
<br />
It is also useful in higher-order situations, such as <hask>map ($ 0) xs</hask>, or <hask>zipWith ($) fs xs</hask>.<br />
<br />
==Definition==<br />
$ comes from the [[Prelude]], where it is defined as:<br />
<br />
infixr 0 $<br />
($) :: (a -> b) -> a -> b<br />
f $ x = f x<br />
<br />
==Note==<br />
The $ syntax is also used in [[Template Haskell]] with an entirely different meaning. If the $ is ''immediately followed'' by a letter or a left parenthesis (with no intervening white space), then it is understood by the GHC compiler as a Template Haskell splice and not the infix operator described above. To get the infix operator be sure to separate the $ from the right argument by at least one white space.<br />
<br />
==See also==<br />
*[[$!]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=55995Template Haskell2013-05-22T23:19:51Z<p>HowardBGolden: /* Template Haskell tutorials and papers */ Update link to latest GHC documentation</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 />
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 />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html The user manual section on Template Haskell]<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html#th-quasiquotation 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 />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.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://www.haskell.org/ghc/docs/7.0-latest/html/libraries/template-haskell-2.5.0.0/Language-Haskell-TH.html The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 [formerly /bz/thdoc.htm]]<br />
** [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj [formerly /bz/th3.htm]]<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 />
<!--<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 />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<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.<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 :: [String]<br />
as = ["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 = [ "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 are given in [http://hackage.haskell.org/package/haskell-src-meta haskell-src-meta].<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 />
[[Category:Language extensions]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Cookbook/Files&diff=55964Cookbook/Files2013-05-17T22:52:40Z<p>HowardBGolden: /* Writing a filter */ Describe interact in words</p>
<hr />
<div>== Reading from a file ==<br />
The System.IO library contains the functions needed for file IO. The program<br />
below displays the contents of the file c:\test.txt.<br />
<br />
<haskell><br />
import System.IO<br />
<br />
main = do<br />
h <- openFile "c:\\test.txt" ReadMode<br />
contents <- hGetContents h<br />
putStrLn contents<br />
</haskell><br />
<br />
''Note: It is important never to call ''<code>hClose</code>'' on a file-handle which has had ''<code>hGetContents</code>'' run on it already. The file handle is in a semi-closed state, and will be closed when the resulting string is garbage collected. Closing it manually may result in a random truncation of the input.''<br />
<br />
The same program, with some higher-level functions:<br />
<br />
<haskell><br />
main = do<br />
contents <- readFile "c:\\test.txt"<br />
putStrLn contents<br />
</haskell><br />
<br />
== Writing to a file ==<br />
<br />
The following program writes the first 100 squares to a file:<br />
<haskell><br />
-- generate a list of squares with length 'num' in string-format.<br />
numbers num = unlines $ take num $ map (show . \x -> x*x) [1..]<br />
<br />
main = do<br />
writeFile "test.txt" (numbers 100)<br />
putStrLn "successfully written"<br />
</haskell><br />
<br />
This will override the old contents of the file, or create a new file if the file doesn't exist yet. If you want to append to a file, you can use <hask>appendFile</hask>.<br />
<br />
== Creating a temporary file ==<br />
<br />
TODO: abstract via 'withTempFile', handle exception<br />
<br />
<haskell><br />
import System.IO<br />
import System.Directory<br />
<br />
main = do<br />
tmpDir <- getTemporaryDirectory<br />
(tmpFile, h) <- openTempFile tmpDir "foo"<br />
hPutStr h "Hello world"<br />
hClose h<br />
removeFile tmpFile<br />
</haskell><br />
<br />
== Writing a filter ==<br />
Using [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:interact interact], you can easily do things with stdin and stdout. <hask>interact</hask> takes a function from <hask>string</hask> to <hask>string</hask> and applies it lazily to the input from stdin, writing the output to stdout.<br />
<br />
A program to sum up numbers:<br />
<br />
<haskell>main = interact $ show . sum . map read . lines</haskell><br />
<br />
A program that adds line numbers to each line:<br />
<br />
<haskell><br />
main = interact numberLines<br />
numberLines = unlines . zipWith combine [1..] . lines<br />
where combine lineNumber text = concat [show lineNumber, " ", text]<br />
</haskell><br />
<br />
== Logging to a file ==<br />
<br />
TODO</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Memoization&diff=55633Memoization2013-04-01T22:45:15Z<p>HowardBGolden: /* Memoising CAFS */ Spell out and link to Constant applicative form</p>
<hr />
<div>[[Category:Idioms]]<br />
<br />
'''Memoization''' is a technique for storing values of a function instead of recomputing them each time the function is called.<br />
<br />
== Memoization without recursion ==<br />
<br />
You can just write a memoization function using a data structure that is suitable for your application.<br />
We don't go into the details of this case.<br />
If you want a general solution for several types,<br />
you need a type class, say <hask>Memoizable</hask>.<br />
<haskell><br />
memoize :: Memoizable a => (a->b) -> (a->b)<br />
</haskell><br />
<br />
Now, how to implement something like this? Of course, one needs a finite<br />
map that stores values <hask>b</hask> for keys of type <hask>a</hask>.<br />
It turns out that such a map can be constructed recursively based on the structure of <hask>a</hask>:<br />
<haskell><br />
Map () b := b<br />
Map (Either a a') b := (Map a b, Map a' b)<br />
Map (a,a') b := Map a (Map a' b)<br />
</haskell><br />
<br />
Here, <hask>Map a b</hask> is the type of a finite map from keys <hask>a</hask> to values <hask>b</hask>.<br />
Its construction is based on the following laws for functions<br />
<haskell><br />
() -> b =~= b<br />
(a + a') -> b =~= (a -> b) x (a' -> b) -- = case analysis<br />
(a x a') -> b =~= a -> (a' -> b) -- = currying<br />
</haskell><br />
<br />
For further and detailed explanations, see<br />
<br />
* Ralf Hinze: [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.3272 Memo functions, polytypically !]<br />
* Ralf Hinze: [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069 Generalizing generalized tries]<br />
* Conal Elliott: [http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/ Elegant memoization with functional memo tries] and other [http://conal.net/blog/tag/memoization/ posts on memoization].<br />
* Conal Elliott [http://conal.net/papers/type-class-morphisms/ Denotational design with type class morphisms], section 9 (Memo tries).<br />
<br />
== Memoization with recursion ==<br />
<br />
Things become more complicated if the function is recursively defined<br />
and it should use memoized calls to itself.<br />
A classic example is the recursive computation of [[The Fibonacci sequence|Fibonacci numbers]].<br />
<br />
The naive implementation of Fibonacci numbers without memoization is horribly slow.<br />
Try <hask>slow_fib 30</hask>, not too much higher than that and it hangs.<br />
<haskell><br />
slow_fib :: Int -> Integer<br />
slow_fib 0 = 0<br />
slow_fib 1 = 1<br />
slow_fib n = slow_fib (n-2) + slow_fib (n-1)<br />
</haskell><br />
<br />
The memoized version is much faster.<br />
Try <hask>memoized_fib 10000</hask>.<br />
<br />
<haskell><br />
memoized_fib :: Int -> Integer<br />
memoized_fib = (map fib [0 ..] !!)<br />
where fib 0 = 0<br />
fib 1 = 1<br />
fib n = memoized_fib (n-2) + memoized_fib (n-1)<br />
</haskell><br />
<br />
<br />
=== Memoizing fix point operator ===<br />
<br />
You can factor out the memoizing trick to a function, the memoizing fix point operator,<br />
which we will call <hask>memoFix</hask> here.<br />
<br />
<haskell><br />
fib :: (Int -> Integer) -> Int -> Integer<br />
fib f 0 = 1<br />
fib f 1 = 1<br />
fib f n = f (n-1) + f (n-2)<br />
<br />
fibonacci :: Int -> Integer<br />
fibonacci = memoFix fib<br />
<br />
</haskell><br />
<br />
I suppose if you want to "put it in a library",<br />
you should just put <hask>fib</hask> in,<br />
and allow the user to call <hask>memoFix fib</hask> to make a new version when necessary.<br />
This allows the user e.g. to define the data structure used for memoization.<br />
<br />
The memoising fixpoint operator works<br />
by putting the result of the first call of the function<br />
for each natural number into a data structure and<br />
using that value for subsequent calls ;-)<br />
<br />
In general it is<br />
<haskell><br />
memoFix :: ((a -> b) -> (a -> b)) -> a -> b<br />
memoFix f =<br />
let mf = memoize (f mf) in mf<br />
</haskell><br />
<br />
== Efficient tree data structure for maps from Int to somewhere ==<br />
<br />
Here we present a special tree data type<br />
({{HackagePackage|id=data-inttrie}})<br />
which is useful as memoizing data structure e.g. for the Fibonacci function.<br />
<haskell><br />
memoizeInt :: (Int -> a) -> (Int -> a)<br />
memoizeInt f = (fmap f (naturals 1 0) !!!)<br />
</haskell><br />
<br />
A data structure with a node corresponding to each natural number to use as a memo.<br />
<haskell><br />
data NaturalTree a = Node a (NaturalTree a) (NaturalTree a)<br />
</haskell><br />
<br />
Map the nodes to the naturals in this order:<br />
<br />
<code><br />
0<br />
1 2<br />
3 5 4 6<br />
7 ...<br />
</code><br />
<br />
Look up the node for a particular number<br />
<br />
<haskell><br />
Node a tl tr !!! 0 = a <br />
Node a tl tr !!! n =<br />
if odd n<br />
then tl !!! top<br />
else tr !!! (top-1)<br />
where top = n `div` 2<br />
</haskell><br />
<br />
We surely want to be able to map on these things...<br />
<br />
<haskell><br />
instance Functor NaturalTree where<br />
fmap f (Node a tl tr) = Node (f a) (fmap f tl) (fmap f tr)<br />
</haskell><br />
<br />
If only so that we can write cute,<br />
but inefficient things like the below,<br />
which is just a <hask>NaturalTree</hask><br />
such that <hask>naturals!!!n == n</hask>:<br />
<br />
<haskell><br />
naturals = Node 0 (fmap ((+1).(*2)) naturals) (fmap ((*2).(+1)) naturals)<br />
</haskell><br />
<br />
The following is probably more efficient<br />
(and, having arguments won't hang around at top level, I think)<br />
-- have I put more <hask>$!</hask>s than necessary?<br />
<br />
<haskell><br />
naturals r n =<br />
Node n<br />
((naturals $! r2) $! (n+r))<br />
((naturals $! r2) $! (n+r2))<br />
where r2 = 2*r<br />
</haskell><br />
<br />
==Memoising CAFS==<br />
'''Note: This is migrated from the old wiki.'''<br />
<br />
Memoising constructor functions gives you HashConsing, and you can sometimes use MemoisingCafs ([[constant applicative form]]s) to implement that.<br />
<br />
The MemoisingCafs idiom also supports recursion.<br />
<br />
Consider, for example:<br />
<br />
<haskell><br />
wonderous :: Integer -> Integer<br />
wonderous 1 = 0<br />
wonderous x<br />
| even x = 1 + wonderous (x `div` 2)<br />
| otherwise = 1 + wonderous (3*x+1)<br />
</haskell><br />
This function is not at all understood by mathematicians and has a surprisingly complex recursion pattern, so if you need to call it many times with different values, optimising it would not be easy.<br />
<br />
However, we can memoise some of the domain using an array CAF:<br />
<haskell><br />
wonderous2 :: Integer -> Integer<br />
wonderous2 x<br />
| x <= maxMemo = memoArray ! x<br />
| otherwise = wonderous2' x<br />
where<br />
maxMemo = 100<br />
memoArray = array (1,maxMemo)<br />
[ (x, wonderous2' x) | x <- [1..maxMemo] ]<br />
<br />
wonderous2' 1 = 0<br />
wonderous2' x<br />
| even x = 1 + wonderous2 (x `div` 2)<br />
| otherwise = 1 + wonderous2' (3*x+1)<br />
</haskell><br />
When using this pattern in your own code, note carefully when to call the memoised version (wonderous2 in the above example) and when not to. In general, the partially memoised version (wonderous2' in the above example) should call the memoised version if it needs to perform a recursive call. However, in this instance, we only memoize for small values of x, so the branch of the recursion that passes a larger argument need not bother checking the memo table. (This does slow the array initialization, however.)<br />
Thanks to [[lazy evaluation]], we can even memoise an infinite domain, though we lose constant time lookup. This data structure is O(log N):<br />
<br />
<haskell><br />
type MemoTable a = [(Integer, BinTree a)]<br />
data BinTree a = Leaf a | Node Integer (BinTree a) (BinTree a)<br />
<br />
wonderous3 :: Integer -> Integer<br />
wonderous3 x<br />
= searchMemoTable x memoTable<br />
where<br />
memoTable :: MemoTable Integer<br />
memoTable = buildMemoTable 1 5<br />
<br />
buildMemoTable n i<br />
= (nextn, buildMemoTable' n i) : buildMemoTable nextn (i+1)<br />
where<br />
nextn = n + 2^i<br />
<br />
buildMemoTable' base 0<br />
= Leaf (wonderous3' base)<br />
buildMemoTable' base i<br />
= Node (base + midSize)<br />
(buildMemoTable' base (i-1))<br />
(buildMemoTable' (base + midSize) (i-1))<br />
where<br />
midSize = 2 ^ (i-1)<br />
<br />
searchMemoTable x ((x',tree):ms)<br />
| x < x' = searchMemoTree x tree<br />
| otherwise = searchMemoTable x ms<br />
<br />
searchMemoTree x (Leaf y) = y<br />
searchMemoTree x (Node mid l r)<br />
| x < mid = searchMemoTree x l<br />
| otherwise = searchMemoTree x r<br />
<br />
wonderous3' 1 = 0<br />
wonderous3' x<br />
| even x = 1 + wonderous3 (x `div` 2)<br />
| otherwise = 1 + wonderous3 (3*x+1)<br />
</haskell><br />
<br />
Naturally, these techniques can be combined, say, by using a fast CAF data structure for the most common part of the domain and an infinite CAF data structure for the rest.<br />
<br />
-- [[AndrewBromage]]<br />
<br />
== Memoizing polymorphic functions ==<br />
<br />
What about memoizing polymorphic functions defined with polymorphic recursion?<br />
How can such functions be memoized?<br />
The caching data structures used in memoization typically handle only one type of argument at a time.<br />
For instance, one can have finite maps of differing types, but each concrete finite map holds just one type of key and one type of value.<br />
<br />
See the discussion on *Memoizing polymorphic functions*, [http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/ part one] and [http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/ part two].<br />
<br />
== See also ==<br />
<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2007-February/022590.html Haskell-Cafe "speeding up fibonacci with memoizing"]<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2007-May/025991.html Haskell-Cafe about memoization utility function]<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2007-February/022865.html Haskell-Cafe "memoisation"]<br />
* [http://www.haskell.org/pipermail/haskell-cafe/2005-October/011589.html Haskell-Cafe about Memoization and Data.Map]<br />
* http://programming.reddit.com/info/16ofr/comments<br />
* [http://www.cs.utexas.edu/~wcook/Drafts/2006/MemoMixins.pdf Monadic Memoization Mixins] by Daniel Brown and William R. Cook<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/data-memocombinators data-memocombinators: Combinators for building memo tables.]<br />
* [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MemoTrie MemoTrie: Trie-based memo functions]<br />
* [http://hackage.haskell.org/package/monad-memo monad-memo: memoization monad transformer]<br />
* [http://hackage.haskell.org/package/memoize memoize: uses Template Haskell to derive memoization code]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Constant_applicative_form&diff=55632Constant applicative form2013-04-01T22:40:28Z<p>HowardBGolden: Add link to Memoization#Memoising_CAFS</p>
<hr />
<div>Also referred to as CAF.<br />
<br />
Any [[super combinator]] which is not a [[lambda abstraction]]. This includes truly constant expressions such as <hask>12, ((+) 1 2), [1,2,3]</hask> as well as partially applied functions such as <hask>((+) 4)</hask>. Note that this last example is equivalent under eta abstraction to <hask>\ x -> (+) 4 x</hask> which is not a CAF.<br />
<br />
==Examples and discussions==<br />
Since a CAF is a [[super combinator]], it contains no [[free variable]]s. Moreover, since it is not a [[lambda abstraction]] it contains no variables at all. It may however contain identifiers which refer to other CAFs, e.g.<br />
<br />
<haskell><br />
c 3 where c = (*) 2<br />
</haskell><br />
<br />
A CAF can always be lifted to the top level of the program. It can either be compiled to a piece of graph which will be shared by all uses or to some shared code which will overwrite itself with some graph the first time it is evaluated. A CAF such as<br />
<br />
<haskell><br />
ints = from 1 where from n = n : from (n+1)<br />
</haskell><br />
<br />
can grow without bound but may only be accessible from within the code of one or more functions. In order for the [[garbage collector]] to be able to reclaim such structures, we associate with each function a list of the CAFs to which it refers. When garbage collecting a reference to the function we collect the CAFs on its list.<br />
<br />
<br />
<br />
===Q&A discussion from HaWiki===<br />
:''What is the difference between ''<hask>((+) 4)</hask>'' and ''<hask>\x -> (+) 4 x</hask>'', apart from the obvious difference in notation? (I have braced the + to make the expressions compliant with Haskell syntax.)''<br />
::One is an application that returns a function and may imply some work in general, the other is a syntactic value (a lambda abstraction).<br />
<br />
:''If notation really happens to matter so much, then what about ''<hask>(4 +)</hask>'' and ''<hask>(+ 4)</hask>''? Are '''both''' of these CAFs? If we take away the nifty syntax, how do we express ''<hask>(+ 4)</hask>'' then? Or is it no longer a CAF? ;)''<br />
<br />
::It depends on how they desugar. `(4 +)` presumably desugars to `((+) 4)` and so is a CAF. If (+ 4) desugars to `\x -> x + 4` it isn't, if it desugars to `flip (+) 4` it is. -- DerekElkins<br />
<br />
:::''--- Rambler'' ''I'm afraid I still don't get it (or maybe I do, but I secretly wish it didn't mean '''that'''...) To the best of my understanding of the matter, `flip (+) 4` should return something that should behave exactly as `\x -> x + 4` would. Moreover, even if I take it for granted that `flip (+) 4` differs dramatically from `\x -> x + 4`, what happens when we expand the former?<br />
:::'''''There is no difference in ''behavior'' as far as meaning is concerned. They are just treated differently. -- DerekElkins'''''<br />
:::Suppose `flip` is defined as `\f x y -> f y x` (which it probably is, anyway,) then `flip (+) 4 where flip = \f x y -> f y x` is obviously not a CAF, according to the definition.<br />
:::What about `flip (+) 4 where flip f x y = f y x`???''<br />
::::''I believe that FOLDOC is incorrect here. A better way of thinking about CAFs is that a CAF is anything that can be let floated (see [[lifting pattern]]) to the top level. So a CAF can not only call other CAFs, but also other [[super combinator]]s.''<br />
:::::I believe that's already granted, according to the definition of a [[super combinator]]. A CAF may reference any [[super combinator]] simply by virtue of being one.<br />
::::''The difference between <hask>flip (+) 4</hask> and <hask>\x -> x + 4</hask> is that in a pure lambda calculus implementation, the former can be reduced but the latter cannot. Remember that <hask>\f x y -> f y x</hask> is a shorthand for <hask>\f -> (\x -> (\y -> f y x)))</hask>, which means if given two arguments, it can be reduced. --AndrewBromage''<br />
:::::Fine, is it then irreducibility that makes CAFs special? If so, then the current formulation of the definition clearly misses the point. If not, then why is this distinction relevant in the context of the definition?<br />
:::::In any case, I am left wondering 1) why irreducible expressions might be of such interest (apart from the trivially imaginable,) and 2) whatever happened to the proverbial [[referential transparency]]. It just struck me lately that my difficulty may be due to the fact that I am trying to make sense of CAFs in a broad theoretical context, whereas they may be simply an implementation instrument -- is this the case? --Rambler<br />
<br />
:'''You've inverted it slightly (or it reads that way): it's ''reducibility'' that makes CAFs special. Since they are reducible they may imply work; work that could be saved. Nevertheless, yes, one typically doesn't care whether something's a CAF or not as far as meaning goes. Read the relevant parts of the book I linked to below, if you haven't already. As for ReferentialTransparency, whether or not something is viewed as a CAF doesn't change it's meaning, i.e. it is just a different ''implementation'' of the ''same'' function. -- DerekElkins'''<br />
<br />
::''OK, it definitely makes sense now, thanks to everyone for the explanations and references. --Rambler''<br />
<br />
==See also==<br />
* Simon Peyton Jones' [http://research.microsoft.com/%7Esimonpj/papers/slpj-book-1987/index.htm Implementation of Functional Programming Languages] for more about this and related terms.<br />
* [[Memoization#Memoising_CAFS|Memoising constant applicative forms]]<br />
[[Category:Glossary]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Kind&diff=50264Kind2012-08-26T19:44:00Z<p>HowardBGolden: Include Wikipedia introduction, which is clearer (to me) and link to TaPL</p>
<hr />
<div>[http://en.wikipedia.org/wiki/Kind_%28type_theory%29 Wikipedia] says, "In type theory, a '''kind''' is the type of a type constructor or, less commonly, the type of a higher-order type operator. A kind system is essentially a simply typed lambda calculus 'one level up,' endowed with a primitive type, denoted * and called 'type,' which is the kind of any (monomorphic) data type."<br />
<br />
Ordinary types have kind <TT>*</TT>. Type constructors have kind <TT>P -> Q</TT>, where <TT>P</TT> and <TT>Q</TT> are kinds. For instance:<br />
<br />
Int :: *<br />
Maybe :: * -> *<br />
Maybe Bool :: *<br />
a -> a :: *<br />
[] :: * -> *<br />
(->) :: * -> * -> *<br />
<br />
In Haskell 98, <TT>*</TT> is the only '''inhabited kind''', that is, all values have types of kind <TT>*</TT>. GHC introduces another inhabited kind, <TT>#</TT>, for [[unboxed type]]s.<br />
<br />
= See also =<br />
<br />
* [[GHC/Kinds]]<br />
* [http://hackage.haskell.org/trac/ghc/wiki/IntermediateTypes#KindsareTypes Kinds ?, ??, # and (#)]<br />
* [[Books#Foundations|Pierce, Benjamin. ''Types and Programming Languages'']].<br />
<br />
[[Category:Language]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=$&diff=45275$2012-04-16T02:36:40Z<p>HowardBGolden: A new page for the $ operator explaining its usefulness</p>
<hr />
<div>'''$''' is an infix operator often seen in Haskell code. It applies the function on its left to the value on its right. At first glance this operator appears redundant, since ordinary application <hask>(f x)</hask> means the same as <hask>(f $ x)</hask>. However, <hask>$</hask> has the lowest, right-associative binding precedence (infixr 0), so it sometimes allows parentheses to be omitted; for example:<br />
<br />
f $ g $ h x = f (g (h x))<br />
<br />
If <hask>$</hask> were omitted, the parse would be different:<br />
<br />
f g h x = ((f g) h) x<br />
<br />
It is also useful in higher-order situations, such as <hask>map ($ 0) xs</hask>, or <hask>zipWith ($) fs xs</hask>.<br />
<br />
==Definition==<br />
$ comes from the [[Prelude]], where it is defined as:<br />
<br />
infixr 0 $<br />
($) :: (a -> b) -> a -> b<br />
f $ x = f x<br />
<br />
==See also==<br />
*[[$!]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Generic_programming&diff=43554Applications and libraries/Generic programming2011-12-10T03:58:17Z<p>HowardBGolden: Undo revision 43548 by HowardBGolden (Talk)</p>
<hr />
<div>{{unknown copyright}}<br />
<br />
== Common library for generic programming ==<br />
<br />
Johan Jeuring and Andres Loeh [http://article.gmane.org/gmane.comp.lang.haskell.general/14304/ announced] an initiative to design a common library for generic programming, which should work together with most of the Haskell compilers, and for which they hope to guarantee support for generics in Haskell into the future. If you want to get involved (or just want to see the discussion), you can subscribe to [http://www.haskell.org/mailman/listinfo/generics the generics mailing list]. Check the [http://haskell.org/haskellwiki/Research_papers/Generics Haskell research wiki] for some background on generics.<br />
<br />
=== Work Plan ===<br />
<br />
We have identified a number of approaches that are potential candidates to a generic programming library:<br />
<br />
<ul><br />
<li><p>[[/Lightweight|A Lightweight Implementation Generics and Dynamics]]</p></li><br />
<li><p>[[/SyB| SYB (and variants)]]</p></li><br />
<li><p>[[/Strafunski| Strafunski]]</p></li><br />
<li><p>Generics for the Masses</p></li><br />
<li><p>Generics as a library</p></li><br />
<li><p>[[/Smash|Smash your Boilerplate]]</p></li><br />
<li><p>RepLib</p></li><br />
<li><p>Extensible superclasses</p></li><br />
<li><p>Almost compositional functions</p></li><br />
</ul><br />
<br />
At the moment we are discussing the advantages and disadvantages of the different approaches. Each approach is roughly two weeks under discussion and the results will be published in this Wiki Page. There is also a darcs repository where you can find some code that we are collecting. For retriving this code do:<br />
<br />
> darcs get http://darcs.haskell.org/generics<br />
<br />
The template that we are using to summarise the different approaches can be found [[/Template|here]].<br />
<br />
==Alternatives==<br />
*[[Uniplate]], recently released by Neil Mitchell.<br />
<br />
==Benchmark suite==<br />
We have developed a benchmark suite that tests the expressiveness of different generic programming libraries. For more information go to: [[GPBench]].</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Generic_programming/Strafunski&diff=43551Applications and libraries/Generic programming/Strafunski2011-12-10T03:51:22Z<p>HowardBGolden: Update Strafunski website URL</p>
<hr />
<div>== Approach: Strafunski ==<br />
<br />
Reference: [http://code.google.com/p/strafunski/ Strafunski home page].<br />
<br />
Strafunski is a Haskell-centered software bundle for generic programming and language processing. On this page, we focus on the generic programming capabilities as offered by Strafunski's subpackage StrategyLib; for the language processing support of Strafunski, see the subsection on <b>Language processing support</b>.<br />
<br />
The generic programming capabilities of Strafunski are less ambitious than some other generic functional programming approaches; it limits itself to enabling type-safe strategic programming as useful for the construction of generic traversals (transformations and queries) over large sets of first-order, non-parameterized algebraic datatypes, such as abstract syntax representations.<br />
<br />
Strafunski is compatible with the scrap-your-boilerplate (SyB) approach to generic functional programming, in the sense that one of the available implementations of Strafunski's strategy combinator API relies on the Data.Generics module of SyB1.<br />
<br />
== Required features/Portability ==<br />
<br />
Strafunski can be used with at least GHC and Hugs (others?). It relies on compiler extensions for overlapping and undecidable instances.<br />
<br />
Strafunski is usually used in combination with DrIFT, though instances can of course be provided by hand.<br />
<br />
If the Data.Generics implementation of Strafunski's strategy combinator API is activated, the requirements and portability are the same as those of SyB1. Also, instances can then be provided alternatively with DrIFT, by hand, or via the deriving clause.<br />
<br />
== Expressibility ==<br />
<br />
Strafunski is based on the notion of a functional strategy. These are generic functions that can traverse into terms of any type while mixing type-specific and uniform behaviour. Strafunski's suite of basic strategy combinators can be found here:<br />
<br />
[http://code.google.com/p/strafunski/source/browse/trunk/misc/syb42/src/Strafunski/StrategyLib/StrategyPrimitives.hs StrategyPrimitives definitions source]<br />
<br />
Two kinds of functional strategies are supported: monadic type-preserving transformations (of type TP m, which corresponds to forall a . a -> m a), and monadic type-unifying queries (of type TU u m, which corresponds to forall a . a -> m u).<br />
<br />
Among the strategy combinators are combinators for one-layer generic traversal into terms. These enable the construction of generic traversals of various kinds (partial or complete, fix-point or one-pass, bottum-up or topdown, etc.).<br />
<br />
Type-specific and generic behaviour can be mixed on the basis of the so-called adhoc combinators. These specialize a generic function for a specific input type.<br />
<br />
== Subset of data types covered ==<br />
<br />
Strafunski is primarily targeted at algebraic datatypes that represent language syntaxes. It supports non-parameterized algebraic datatypes without function components.<br />
<br />
== Usage ==<br />
<br />
To enable Strafunski for new user-defined datatypes, one must run DrIFT on those datatypes.<br />
<br />
To write new generic functions, one must import the StrategyLib module, or one or more of the submodules of the library, and use the available strategy combinators to compose new functions.<br />
<br />
Generic functions can be called by normal functions without exposing this fact in their types. This is called the "Keyhole Operation" design pattern in "Design Patterns for Functional Strategic Programming" (Ralf Lämmel & Joost Visser, 2002). This enables the use of generic functions without knowing it.<br />
<br />
End users (those that use generic functions, but do not define them) must make sure that they import the appropriate class instances for the datatypes to which they apply generic functions. Normal functions defined using generic functions can be used without such precautions.<br />
<br />
Strafunski is suitable for generic programming over very large sets of algebraic datatypes, typically representations of language syntaxes. The size of these sets of datatypes makes it desirable to automatically create instances for these datatypes, not with the deriving mechanism, but with DrIFT. DrIFT allows instances to reside in a different file than the datatypes and to be compiled separately. The need for separate compilation explains why Strafunski is usually used in combination with DrIFT, even when the SyB implementation of its strategy combinator API is activated.<br />
<br />
== Error Messages ==<br />
<br />
There do not seem to be strong usability problems with respect to error reporting.<br />
<br />
== Amount of work per data type (Boilerplate) ==<br />
<br />
When new datatypes are added, DrIFT can be invoked to supply the necessary instances.<br />
<br />
== Extensibility == <br />
<br />
Strafunski enjoys good extensibility properties. New datatypes can be added without changing existing generic functions. New generic functions can be added without changing existing datatypes or their instances.<br />
<br />
== Reasoning ==<br />
<br />
The set of generic function combinators of Strafunski has a well-understood semantics that does not rely on very advanced typing features. As a result, reasoning is quite straightforward. In fact, reasoning can be automated, as demonstrated in "Transformation of Structure-Shy Programs, Applied to XPath and Strategic Functions" (Alcino Cunha & Joost Visser, draft October 2006).<br />
<br />
== Performance considerations ==<br />
<br />
Time and space behaviour of generic functions created with Strafunski seem to pose no problems in practice, given its successful application to non-trivial analysis and transformation of large language syntaxes (see <b>Applications</b>).<br />
<br />
== Helpful extra features ==<br />
<br />
The current feature set of Haskell + overlapping and undecidable instances is sufficient.<br />
<br />
== Language processing support ==<br />
<br />
Apart from the strategy combinator library StrategyLib, the Strafunski bundle provides generative tool support based on DrIFT and Sdf2Haskell, and parsing/unparsing support based on the Haskell ATerm Library and the scannerless, generalized LR parser SGLR.<br />
<br />
== Applications ==<br />
<br />
Documented applications of Strafunski include the Haskell Refactorer HaRe (processing Haskell abstract syntax trees), the XsdMetz tool (processing XML Schema), the VooDooM tool (processing VDM-SL and producing SQL), and Sdf2Haskell (ingredient of the Strafunski bundle that generates Haskell datatypes from SDF grammars).<br />
<br />
See also "A Strafunski Application Letter" (Ralf Lämmel & Joost Visser, 2003).<br />
<br />
== Discussion ==<br />
<br />
Though limited in its generic functional programming capabilities with respect to other approaches to generic functional programming, Strafunski has proven quite effective in its primary application domain of language processing. Strafunski avoids boilerplate code for such applications, but relies on very few non-standard Haskell extensions.</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Applications_and_libraries&diff=43549Applications and libraries2011-12-10T03:45:16Z<p>HowardBGolden: Add link to generic programming subpage</p>
<hr />
<div>[[Category:Libraries]] [[Category:Tools]]<br />
<br />
The number of Haskell packages is growing rapidly. The section 'Haskell library collections' gives an ordering of all these packages by relative importance. In the section 'Haskell applications and libraries' an ordering by category is given. Finally some guidelines for developers of new packages are presented.<br />
<br />
== Haskell library collections ==<br />
<br />
=== Haskell Prelude ===<br />
The most important Haskell library is called the [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html Prelude]. It is implicitly imported by default, and includes the most commonly used functions. Make sure you know what they do and how to use them effectively.<br />
<br />
=== The Haskell 2010 libraries ===<br />
The Haskell 2010 [[Language and library specification]] defines a set of [http://www.haskell.org/onlinereport/haskell2010/haskellpa2.html libraries] with basic functionality which all Haskell implementations should support, including the Prelude. Changes to these libraries are handled by the [http://hackage.haskell.org/trac/haskell-prime/ Haskell'] process.<br />
<br />
Haskell modules that almost everybody uses are in this group, for example:<br />
[http://www.haskell.org/onlinereport/haskell2010/haskellch13.html Control.Monad], [http://www.haskell.org/onlinereport/haskell2010/haskellch20.html Data.List] <br />
and [http://www.haskell.org/onlinereport/haskell2010/haskellch41.html System.IO]. In GHC these are all grouped into the 'base' package. <br />
<br />
=== The GHC standard libraries ===<br />
GHC comes with an expanded version of the Haskell 2010 libraries. Together these are called the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html GHC standard libraries]. Changes to these libraries are handled by the package maintainer if one exists, or the [[Library submissions]] process if not. [http://haskell.org/hoogle Hoogle] - the Haskell API Search Engine - indexes the [http://www.haskell.org/ghc/docs/latest/html/libraries/index.html GHC standard libraries].<br />
<br />
Examples of libraries, or packages, that belong to this group are: <br />
[http://hackage.haskell.org/package/bytestring bytestring], <br />
[http://hackage.haskell.org/package/containers containers] and [http://hackage.haskell.org/package/Win32 Win32].<br />
<br />
=== Haskell Platform libraries ===<br />
On top of the GHC standard libraries, the [http://hackage.haskell.org/platform Haskell Platform] comes preinstalled with some additional packages that together form the [http://hackage.haskell.org/platform/contents.html#packages-and-documentation Haskell Platform libraries]. These libraries have been thoroughly tested before being included. The addition of these libraries with the [http://hackage.haskell.org/platform/ Haskell Platform] is what makes it 'batteries included'.<br />
<br />
Examples of included packages are: [http://hackage.haskell.org/package/mtl Monad transformer library], [http://hackage.haskell.org/package/parallel parallel] and [http://hackage.haskell.org/package/QuickCheck QuickCheck].<br />
<br />
=== The Hackage database ===<br />
[http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] is the final layer of the Haskell library collections. [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] aims to provide a comprehensive collection of released Haskell packages, similar to Perl's CPAN or Python's PyPI. <br />
<br />
Start on [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] if you are looking for some functionality that did not come preinstalled with the [http://hackage.haskell.org/platform/ Haskell Platform]. <br />
<br />
See also the [[Hackage|Hackage wiki page]] and [[Cabal/How to install a Cabal package | how to install a Cabal package]].<br />
<br />
== Haskell applications and libraries ==<br />
<br />
Applications, libraries and tools for Haskell or written in Haskell have been classified below, but you should check [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage] for the latest list.<br />
<br />
* [[/Music and sound/|Audio, music and sound]]<br />
* [[/Bioinformatics/]]<br />
* [[/Concurrency and parallelism/]]<br />
* [[/Compilers and interpreters/]]<br />
* [[/Compiler tools|Compiler construction, lexing, parsing, pretty printing]]<br />
* [[/Cryptography|Cryptography and hashing]]<br />
* [[/Data structures | Data Structures and IO Libraries]]<br />
* [[/Database interfaces/]]<br />
* [[/Editors|Editors written in Haskell]] and [[Editors|editors for Haskell]].<br />
* [[/Extended Haskell/]]<br />
* [[/Games/]]<br />
* [[/Generic programming/]]<br />
* [[/Genetic programming/]]<br />
* [[/GUI libraries|Graphical User Interface (GUI) Libraries]]<br />
* [[/Graphics/]]<br />
* [[/Hardware verification/]]<br />
* [[/Linguistics|Linguistics and natural language processing]]<br />
* [[/Mathematics/|Mathematics and physics]]<br />
* [[/Network/]]<br />
* [[/Operating system/|Operating systems and systems programming]] (also emulators)<br />
* [[/Program development/]]<br />
* [[/Robotics/]]<br />
* [[/Theorem provers/]]<br />
* [[/Interfacing other languages|Tools for interfacing with other languages]]<br />
* [[Web|Web, HTML, XML]]<br />
<br />
Other places to look include:<br />
* The [[Library]] hierarchy page on this wiki.<br />
* The Haskell [[Haskell Communities and Activities Report|community reports]].<br />
* The [http://www.haskell.org/mailman/listinfo/libraries mailing list] for discussion of issues related to libraries.<br />
<br />
You can also [http://www.reddit.com/r/haskell_proposals/top/?t=month propose and vote on new libraries] that you'd like on [http://www.reddit.com/r/haskell reddit], and look at our past [http://hackage.haskell.org/trac/summer-of-code/ Summer of Code proposals].<br />
<br />
== Guidelines for developers ==<br />
<br />
[[Image:Cabal-With-Text-small.png|frame|Built with Cabal]]<br />
<br />
Developer guides:<br />
<br />
* [[How to write a Haskell program|How to write a new Haskell library]]<br />
* [[Library submissions|How to propose changes to the standard libraries]]<br />
* [http://web.archive.org/web/20071011215053/http://pupeno.com/2006/12/12/the-lambda-revolution-v/ Creating a .deb from a Haskell Cabal package] (in the Web Archive)<br />
* [http://cgi.cse.unsw.edu.au/~dons/blog/2006/12/11 Creating a Haskell library by example]<br />
* Guide to making standard [[Library submissions|library submissions]]<br />
* If you notice the library documentation is lacking, or could be improved, [http://haskell.org/haskellwiki/Improving_library_documentation please report it here]<br />
* [http://www.google.com/codesearch Google Code Search] can help identify common idioms, improving your API.<br />
* [[Future projects]], more projects people would like.<br />
* Project activity for some of the larger Haskell projects is graphed [http://www.cse.unsw.edu.au/~dons/images/commits/community/ here].<br />
* [[Cabal]], The Common Architecture for Building Applications and Libraries, is a framework for packaging, building, and installing any tool developed in the Haskell language.<br />
* [[Hack-Nix]], a set of tools based on the [http://nixos.org Nix] package manager to manage multiple setups to build a project<br />
<br />
Proposals for the module name space layout that can be used to guide the construction of new libraries. <br />
<br />
* [[Hierarchical module names|Almost current guide]]<br />
* [http://www.cs.york.ac.uk/fp/libraries/layout.html Proposal 1]<br />
* [http://www.cs.york.ac.uk/fp/libraries/layoutSM.html Proposal 2]<br />
<br />
=== Libraries for other languages ===<br />
<br />
If you are thinking about designing a new library for Haskell, you ought to look what has been done in other languages. Here are standard library definitions for <br />
<br />
* [http://wiki.clean.cs.ru.nl/Libraries Clean]<br />
* [http://www.standardml.org/Basis/ Standard ML]<br />
* [http://caml.inria.fr/pub/docs/manual-ocaml/manual034.html Objective Caml]<br />
* [http://srfi.schemers.org/ Scheme]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Generic_programming&diff=43548Applications and libraries/Generic programming2011-12-10T03:19:38Z<p>HowardBGolden: /* Work Plan */ Refer to main Strafunski page instead of duplicate</p>
<hr />
<div>{{unknown copyright}}<br />
<br />
== Common library for generic programming ==<br />
<br />
Johan Jeuring and Andres Loeh [http://article.gmane.org/gmane.comp.lang.haskell.general/14304/ announced] an initiative to design a common library for generic programming, which should work together with most of the Haskell compilers, and for which they hope to guarantee support for generics in Haskell into the future. If you want to get involved (or just want to see the discussion), you can subscribe to [http://www.haskell.org/mailman/listinfo/generics the generics mailing list]. Check the [http://haskell.org/haskellwiki/Research_papers/Generics Haskell research wiki] for some background on generics.<br />
<br />
=== Work Plan ===<br />
<br />
We have identified a number of approaches that are potential candidates to a generic programming library:<br />
<br />
<ul><br />
<li><p>[[/Lightweight|A Lightweight Implementation Generics and Dynamics]]</p></li><br />
<li><p>[[/SyB| SYB (and variants)]]</p></li><br />
<li><p>[[Libraries_and_tools/Strafunski| Strafunski]]</p></li><br />
<li><p>Generics for the Masses</p></li><br />
<li><p>Generics as a library</p></li><br />
<li><p>[[/Smash|Smash your Boilerplate]]</p></li><br />
<li><p>RepLib</p></li><br />
<li><p>Extensible superclasses</p></li><br />
<li><p>Almost compositional functions</p></li><br />
</ul><br />
<br />
At the moment we are discussing the advantages and disadvantages of the different approaches. Each approach is roughly two weeks under discussion and the results will be published in this Wiki Page. There is also a darcs repository where you can find some code that we are collecting. For retriving this code do:<br />
<br />
> darcs get http://darcs.haskell.org/generics<br />
<br />
The template that we are using to summarise the different approaches can be found [[/Template|here]].<br />
<br />
==Alternatives==<br />
*[[Uniplate]], recently released by Neil Mitchell.<br />
<br />
==Benchmark suite==<br />
We have developed a benchmark suite that tests the expressiveness of different generic programming libraries. For more information go to: [[GPBench]].</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Upgrading_packages&diff=38997Upgrading packages2011-03-13T18:05:41Z<p>HowardBGolden: Stub for upgrading packages to GHC-7.0.</p>
<hr />
<div>A list of things that need updating when porting packages to newer library/cabal versions.<br />
<br />
If you maintain a Haskell package this is for you.<br />
For older versions of this document:<br />
<br />
* [[/Updating to GHC 6.10]]<br />
* [[/Updating to GHC 6.8]]<br />
<br />
<br />
'''Updating to GHC 7.0'''<br />
<br />
When upgrading to GHC 7.0, any of your packages that worked against<br />
the base-3 library will need to be updated to the base-4.<br />
<br />
(This is a stub, since the previous version was so out-of-date. Please help by adding useful content.)</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Upgrading_packages/Updating_to_GHC_6.10&diff=38995Upgrading packages/Updating to GHC 6.102011-03-13T18:00:37Z<p>HowardBGolden: Upgrading packages moved to Upgrading packages/Updating to GHC 6.10: This version applies to the older GHC 6.10. It is out-of-date for GHC-7.0</p>
<hr />
<div>A list of things that need updating when porting packages to newer library/cabal versions.<br />
<br />
If you maintain a Haskell package this is for you.<br />
For older versions of this document:<br />
<br />
* [[/Updating to GHC 6.8]]<br />
<br />
'''Updating to GHC 6.10 and Cabal 1.6'''<br />
<br />
When upgrading to GHC 6.10, any of your packages that worked against<br />
the base-3 library will continue to work (unless you define instances of the <code>Arrow</code> class: see below). GHC 6.10 provides both the old<br />
base-3 library and the new base-4.<br />
<br />
To ensure your old code continues to work, you can have the code compile<br />
and link against base-3, and then, over time, migrate code to the base-4<br />
series.<br />
<br />
== Adding base-3 constraints ==<br />
<br />
How to do this depends on how you build your Haskell code. We'll start<br />
with the most simplistic build mechanisms. cabal-install, the most<br />
sophisticated tool, will sort this all out for you anyway, so things<br />
should change.<br />
<br />
=== ghc --make ===<br />
<br />
Force use of package base-3 when using --make,<br />
<br />
ghc --make -package base-3.0.3.0<br />
<br />
===runhaskell ===<br />
<br />
If you build your packages with the 'runhaskell Setup.hs configure'<br />
method, then you can force the use of base-3,<br />
<br />
--constraint="base<4"<br />
<br />
=== cabal-install===<br />
<br />
It is worth upgrading cabal-install immediately (maybe before installing<br />
GHC). This way you can use the smart dependency solver to work out what<br />
to install for you.<br />
<br />
* install [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HTTP HTTP] from hackage<br />
* install [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/zlib zlib] from hackage<br />
<br />
Then build cabal-install.<br />
<br />
You can also override the dependencies when using the 'cabal' binary, with<br />
<br />
--constraint="base<4"<br />
<br />
== Typical breakages with GHC 6.10 ==<br />
<br />
[http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/15430 48 new packages] break with the current GHC 6.10 release candidate.<br />
<br />
The primary reasons are:<br />
<br />
* Changes to the Arrow class definition break Arrow instances<br />
* Changes to the return types of Map and Set functions<br />
* Cabal changes<br />
* Changes to ghc-api<br />
* Changes to when 'forall' is parsed<br />
* GHC.Prim was moved,<br />
* Changes to -fvia-C and headers<br />
* GADT changes,<br />
* pragma warnings tightened<br />
* Integer constructors have moved<br />
* New warnings and used -Werror<br />
<br />
Each of these has a standard way to solve the problem. Techniques should be attached here.<br />
<br />
=== Arrow instances ===<br />
<br />
The relevant change is essentially that Arrow became a subclass of Category. To be exact:<br />
<br />
* <code>(.)</code> is a new function, in Category. <code>(>>>)</code> was removed from Arrow and made a function.<br />
* <code>id</code> is a new function, in Category<br />
<br />
The base-3 compatibility package contains the same classes as base-4, so it will not save you if you define instances of the Arrow class: you'll need to change your code.<br />
Whenever you define an instance of Arrow you must also define an instance of Category, as follows:<br />
<br />
* Add the following imports:<br />
<haskell><br />
import Control.Category<br />
import Prelude hiding (id,(.)) -- conflicts with Category otherwise<br />
</haskell><br />
* Add <code>instance Category [your type] where</code> for any Arrow instances you define.<br />
* Move your <code>(>>>)</code> definition into Category, and change <code>f >>> g = ...</code> into <code>g . f = ...</code><br />
* Define <code>id</code> in Category to something equivalent to<br />
<haskell><br />
id = arr id<br />
</haskell><br />
: Unfortunately this exact definition does not work in GHC 6.10.1 with optimization turned on (this is bug [http://hackage.haskell.org/trac/ghc/ticket/2722 #2722]), but anything equivalent to it is OK.<br />
<br />
And you're done.<br />
<br />
Following the recipe above will make your library work with ghc 6.9 and 6.10 and ''not work'' with 6.8.<br />
With a little more work and the help of CPP, you can manage the differences between 6.8, 6.9, and 6.10 and make your library work on all of them.<br />
<br />
The following directions are an alternative to the ones above.<br />
<br />
First, include <code>CPP</code> to your <code>LANGUAGE</code> pragma.<br />
<br />
Then add the following lines in place of your <hask>import Control.Arrow</hask>:<br />
<haskell><br />
#if __GLASGOW_HASKELL__ >= 609<br />
import Control.Category<br />
import Prelude hiding ((.), id)<br />
#endif<br />
<br />
import Control.Arrow<br />
#if __GLASGOW_HASKELL__ < 610<br />
hiding (pure)<br />
#endif<br />
</haskell><br />
This <hask>hiding (pure)</hask> is to accommodate the removal of <hask>pure</hask> from the <hask>Arrow</hask> interface, and you'll want it if you work with the <hask>pure</hask> method of <hask>Applicative</hask>.<br />
Before ghc 6.10, the <hask>hiding</hask> part is necessary, while afterward it's illegal.<br />
<br />
Finally, doctor your <hask>Arrow</hask> instances.<br />
The following example is taken from [http://hackage.haskell.org/packages/archive/TypeCompose/latest/doc/html/src/Control-Compose.html Control.Compose] in the TypeCompose package.<br />
<br />
<haskell><br />
#if __GLASGOW_HASKELL__ >= 609<br />
instance FunAble h => Category (FunA h) where<br />
id = FunA (arrFun id)<br />
(.) = inFunA2 (.)<br />
#endif<br />
<br />
instance FunAble h => Arrow (FunA h) where<br />
arr p = FunA (arrFun p)<br />
#if __GLASGOW_HASKELL__ < 609<br />
(>>>) = inFunA2 (>>>)<br />
#endif<br />
first = inFunA firstFun<br />
second = inFunA secondFun<br />
(***) = inFunA2 (***%)<br />
(&&&) = inFunA2 (&&&%)<br />
</haskell><br />
<br />
===Return types of Map and Set functions ===<br />
<br />
Functions with signatures like<br />
<haskell><br />
lookup :: (Monad m, Ord k) => k -> Map k a -> m a<br />
</haskell><br />
have been specialized to<br />
<haskell><br />
lookup :: (Ord k) => k -> Map k a -> Maybe a<br />
</haskell><br />
If you assume the more specific type, your code will work with both old and new versions of the <code>containers</code> package.<br />
The brute force approach is to change each <code>lookup k m</code> to<br />
<haskell><br />
fromMaybe (fail "lookup: key not found") $<br />
lookup k m<br />
</haskell><br />
but you could also consider how you want to handle possible failures, or at least give a more informative error message. <br />
<br />
=== Exception handling changes ===<br />
<br />
The exception system was generalised in GHC 6.10, but GHC 6.10 still provides base-3, so all your applications can continue to work. <br />
<br />
Follow the steps for compiling against base-3 at the top of the page, based on your build system.<br />
<br />
Note that if you use cabal-install, it is smart enough to work this out for you.<br />
<br />
=== Changes to -fvia-C and headers ===<br />
<br />
GHC 6.10 no longer includes extra header files when compiling with -fvia-C. This makes compilation with -fvia-C consistent with the native code generator.<br />
<br />
As a consequence, defining inline functions in header files and relying on -fvia-C to pick them up no longer works. Similarly calling C 'functions' that are actually defined via CPP macros also does not work.<br />
<br />
* If you use a library that provides inline functions that you want to use, you will have to create wrapper functions to use them via FFI.<br />
* If you use the <code>#def</code> feature of hsc2hs, you can no longer define inline functions. That is, replace <code>#def inline void foobar() { ... } </code> by just <code>#def void foobar() { ... }</code><br />
<br />
The problem typically manifests itself as link errors (for example "ghc26356_0.hc:(.text+0x20282): undefined reference to `hs_curses_color_pair'"). <br />
<br />
Beware: In some cases, a library using inline functions will be built successfully, but programs using the library will fail to build.<br />
<br />
=== Changes to RULES parsing ===<br />
<br />
RULES are now always parsed and checked. No ghc flags or language extensions are required. (Note: the first 6.10 RC had a bug in this area)<br />
<br />
RULES are only exported if the defining module is built with -O. This is the same as for other cross-module optimisations like exporting the bodies of inlinable functions.<br />
<br />
=== Changes to GADT matching ===<br />
<br />
GHC now enforces the rule that in a GADT pattern match:<br />
<br />
* the type of the scrutinee must be rigid<br />
* the result type must be rigid<br />
* the type of any variable free in the case branch must be rigid<br />
<br />
Here "rigid" means "fully known to the compiler, usually by way of a type signature". This rule is to make type inference simple and predictable.<br />
<br />
Observe that this means that GHC must know the result type of the match ''at the match point''. There is no workaround other than finding a way to provide enough annotations in order to make GHC happy. Nevertheless, this heuristic was suggested:<br />
<br />
<blockquote>My general method for solving these problems was to find an expression<br />
or statement that enclosed both the left and right hand sides, and add<br />
<code>:: Int</code> to it. I then recompiled and got an error message saying it<br />
couldn't match <code>Int</code> with "something". I then replaced <code>Int</code> with<br />
"something" and it worked.</blockquote><br />
<br />
For example, if GHC is complaining about a case-expression you might try rewriting it like this:<br />
(case ... of { ...}) :: type<br />
<br />
<br />
In any case, [http://thread.gmane.org/gmane.comp.lang.haskell.glasgow.user/15153 this thread] is probably a must-read if you are running into this.<br />
<br />
Here's an example from [http://www.haskell.org/haskellwiki/QuickCheck_/_GADT the wiki entry on using QuickCheck with GADTs]. This failed with 6.10.1 with:<br />
<br />
<code><br />
GADT.hs:153:12:<br />
GADT pattern match with non-rigid result type `t'<br />
Solution: add a type signature<br />
In a case alternative: RInt -> text "RInt"<br />
In the expression:<br />
case s of {<br />
RInt -> text "RInt"<br />
RChar -> text "RChar"<br />
RList y -> text "RList" <> space <> parens (prettyRep (Rep y))<br />
RPair y1 y2<br />
-> text "RPair" <> space <> parens (prettyRep (Rep y1)) <> space<br />
<><br />
parens (prettyRep (Rep y2))<br />
RDyn -> text "RDyn" }<br />
</code><br />
<br />
Adding the type signature to the function (not the case alternative as you might infer from the error message): <haskell>prettyRep :: Rep -> Doc</haskell> solves the problem.<br />
<br />
A related issue is this. GHC 6.10 insists on <code>-XGADTs</code> when you ''define'' a GADT, but does not insist on the flag when you ''match'' on a GADT. However, when supplying a type signature for a recursive or mutually-recursive function which does GADT matching, you should use <code>-XRelaxedPolyRec</code> (or <code>-XGADTs</code>, which implies the former) to ensure that the type signature is completely rigid. (Why? It's to do with the way that the Hindley-Milner algorithm typechecks mutually recursive definitions. See this [http://www.haskell.org/pipermail/glasgow-haskell-users/2008-December/016370.html mail thread].)<br />
<br />
=== No more GHC.Prim ===<br />
<br />
It is no longer possible to import GHC.Prim, instead, GHC.Exts should be used to get at the compiler's primops.<br />
<br />
== Backwards compatibility ==<br />
<br />
The new, suggested Cabal version range syntax,<br />
<br />
build-depends: base-3.*<br />
<br />
is not backwards compatible with older versions of Cabal. Users will need to upgrade to the newer Cabal to build packages that start using this syntax.<br />
<br />
== GHC API changes ==<br />
<br />
For converting a package that uses GHC-API, see [[http://hackage.haskell.org/trac/ghc/wiki/GhcApiStatus GhcApiStatus]] for notes on the changes to the API and its use in 6.10. There are four main changes:<br />
<br />
* add imports '<code>MonadUtils</code>' and '<code>SrcLoc</code>'<br />
* use of '<code>runGhc</code>' instead of newSession<br />
* code using getSession and related, converts to become monadic within <code>Ghc</code>monad<br />
* String type becomes Located String type. To convert basic strings, use "L noSrcSpan <string>"<br />
<br />
[[Category:Libraries]]<br />
[[Category:GHC]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Upgrading_packages&diff=38996Upgrading packages2011-03-13T18:00:37Z<p>HowardBGolden: Upgrading packages moved to Upgrading packages/Updating to GHC 6.10: This version applies to the older GHC 6.10. It is out-of-date for GHC-7.0</p>
<hr />
<div>#REDIRECT [[Upgrading packages/Updating to GHC 6.10]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Upgrading_from_MTL_1_to_MTL_2&diff=38009Upgrading from MTL 1 to MTL 22010-12-25T06:14:10Z<p>HowardBGolden: Spelling correction</p>
<hr />
<div>Version 2 of the [[Monad Transformer Library]] introduced some<br />
[[Incompatibilities between MTL 1 and MTL 2|incompatibilities]]<br />
relative to version 1.<br />
This page provides instructions for upgrading code written for<br />
MTL 1 to work with MTL 2.<br />
<br />
Many packages written for earlier versions of MTL build unchanged with version 2. Most of the remainder require only small changes to upgrade to it, though that will usually render them incompatible with version 1 without some CPP directives. Here are the fixes for common messages:<br />
<br />
''Illegal instance declaration for Applicative (State a)''<br />
:This usually means that the instance you're defining is now defined in the [http://hackage.haskell.org/package/transformers transformers] package. You may wish to check it's the same, so you can just delete it.<br />
<br />
''Could not deduce (Functor m) from the context (Monad m)<br/>arising from a use of fmap''<br />
:This will be a situation where you're using a monad constructed with a transformer as a Functor. You can replace <hask>fmap</hask> with <hask>liftM</hask> and the code will build with old and new versions of mtl.<br />
<br />
''Could not deduce (Functor m) from the context (Monad m)<br/>arising from the superclasses of an instance declaration''<br />
:This will be another situation where you're using a monad constructed with a transformer as a Functor. You can replace the <hask>Monad m</hask> with <hask>Functor m</hask> to make it work with mtl-2, or add a <hask>Functor m</hask> constraint to make it work with old and new versions of mtl.<br />
<br />
''Not in scope: data constructor State''<br />
:The <hask>State</hask> type is now a type synonym. You could replace the <hask>State</hask> data constructor with the <hask>state</hask> function.<br />
<br />
''Not in scope: runState''<br />
:You probably imported <hask>State(..)</hask>, which won't work now that <hask>State</hask> is a type synonym. You need to import <hask>State</hask> and <hask>runState</hask>. (That will work with old versions of mtl too.)<br />
<br />
''Illegal instance declaration for Myclass (State Foo)''<br />
:If you have a matching instance for <hask>StateT</hask>, you can delete the instance for <hask>State</hask>. Otherwise you need to generalize your instance to <hask>StateT</hask>. If that's not possible, you may need to introduce a <hask>newtype</hask>.<br />
<br />
[[Category: Monad]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Package_versioning_policy&diff=34608Package versioning policy2010-04-26T01:31:46Z<p>HowardBGolden: change link d.h.o -> c.h.o</p>
<hr />
<div>== Rationale ==<br />
<br />
The goal of a versioning system is to inform clients of a package of changes to that package that might affect them, and to provide a way for clients to specify a particular version or range of versions of a dependency that they are compatible with.<br />
<br />
[http://haskell.org/cabal Cabal] provides the raw materials for versioning: it allows packages to specify their own version, and it allows dependencies that specify which versions of the dependent package are acceptable. Cabal will select dependencies based on the constraints.<br />
<br />
What is missing from this picture is a ''policy'' that tells the library developer how to set their version numbers, and tells a client how to write a dependency that means their package will not try to compile against an incompatible dependency. For some time there has been an informal policy in use in the Haskell community, but it became clear that we were running into trouble with incorrectly-specified dependencies and unbuildable packages, so this page is an attempt to formalize the policy.<br />
<br />
== Version numbers ==<br />
<br />
A package version number should have the form ''A.B.C'', and may optionally have any number of additional components, for example 2.1.0.4 (in this case, ''A''=2, ''B''=1, ''C=0''). This policy defines the meaning of the first three components ''A-C'', the other components can be used in any way the package maintainer sees fit.<br />
<br />
Version number ordering is already defined by Cabal as the lexicographic ordering of the components. For example, 2.1 > 1.3, and 2.1.1 > 2.1. (The <tt>Data.Version.Version</tt> type and its <tt>Ord</tt> instance embody this ordering).<br />
<br />
''A.B'' is known as the ''major'' version number, and ''C'' the ''minor'' version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:<br />
<br />
# If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or instances were added or removed, then the new ''A.B'' must be greater than the previous ''A.B''. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.<br />
# Otherwise, if only new bindings, types, classes or modules (but see below) were added to the interface, then ''A.B'' may remain the same but the new ''C'' must be greater than the old ''C''.<br />
# Otherwise, ''A.B.C'' may remain the same (other version components may change).<br />
<br />
Hence ''A.B.C'' uniquely identifies the API. A client that wants to specify that they depend on a particular version of the API can specify a particular ''A.B.C'' and be sure of getting that API only. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
Often a package maintainer wants to add to an API without breaking backwards compatibility, and in that case they can follow the rules of point 2, and increase only ''C''. A client can specify that they are [[Import modules properly|insensitive to additions to the API]] by allowing a range of ''C'' values, e.g. <tt>build-depends: base >= 2.1.1 && < 2.2</tt>.<br />
<br />
=== Adding new modules ===<br />
<br />
Strictly speaking, adding new modules might cause an unavoidable name collision in dependent code. However, the likelihood is so low that only an increase of the minor version number is required. Generic module names (e.g. Data.Set) are more likely to collide. In this case increasing the major version number likely makes sense. <br />
<br />
== Dependencies in Cabal ==<br />
<br />
When publishing a Cabal package, you should ensure that your dependencies in the <tt>build-depends</tt> field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency. <br />
<br />
At some point in the future, Hackage may refuse to accept packages that do not follow this convention. The aim is that before this happens, we will put in place tool support that makes it easier to follow the convention and less painful when dependencies are updated.<br />
<br />
To minimize breakage when new package versions are released, you can use dependencies that are insensitive to minor version changes (e.g. <tt>foo >= 1.2.1 && < 1.3</tt>). However, note that this approach is slightly risky: when a package exports more things than before, there is a chance that your code will fail to compile due to new name-clash errors. The risk from new name clashes tends to be small, and you can always eliminate it by using explicit import lists if you want.<br />
<br />
== Cabal extensions ==<br />
<br />
To make specifying dependencies easier, we probably want the extensions to the dependency syntax suggested by Thomas Schilling:<br />
<br />
* http://www.haskell.org/pipermail/cabal-devel/2007-September/001111.html<br />
<br />
== Tools ==<br />
<br />
* script to check for API changes in gtk2hs: http://code.haskell.org/gtk2hs/tools/apidiff/<br />
<br />
== Related ==<br />
<br />
* [[Sven Moritz Hallberg]], "[[The_Monad.Reader/Issue2/EternalCompatibilityInTheory|Eternal compatibility in theory]]," [[The Monad.Reader]], [[The Monad.Reader/Issue2|Issue 2]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=GHC/FAQ&diff=32662GHC/FAQ2009-12-20T07:43:31Z<p>HowardBGolden: Update link to Building Guide</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 />
==== Ctrl-C doesn't work on Windows ====<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>[http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#forcing-options-through -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 />
== .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 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 />
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 />
== 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 [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ FFI Addendum]).<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 />
== Propogating 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 />
== 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>HowardBGoldenhttps://wiki.haskell.org/index.php?title=User_groups&diff=31660User groups2009-11-19T09:30:13Z<p>HowardBGolden: Correct hyphenation</p>
<hr />
<div>[[Category:Community]]<br />
<br />
A range of Haskell User Groups are springing up all over. Also see a [http://www.frappr.com/haskellers Map of Haskellers].<br />
<br />
== User groups ==<br />
<br />
Regular meetings in a particular geographical area. Great if you want to see and meet other Haskellers.<br />
<br />
===North America===<br />
<br />
====West Coast ====<br />
<br />
;[http://socalfp.blogspot.com/ SoCal FP Group]<br />
<br />
;[http://bayfp.org/ The Bay Area Functional Programmers group]<br />
:Meeting monthly in the San Francisco Bay area. See [http://bayfp.org/blog their blog] for more details and news of upcoming meetings.<br />
<br />
;[http://groups.google.com/group/pdxfunc PDXfunc: Portland FP Group]<br />
:Monthly meetings of the Portland, Oregon functional programming group. Meetings occur on the second Monday of each month at 7 pm. They are held at [http://www.cubespacepdx.com CubeSpace] on 6th & Grant ([http://www.cubespacepdx.com/directions directions]), which generously provides the space free of charge. <br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2008-February/038991.html Seattle: Northwest Functional Programming Interest Group]<br />
:a Northwest Functional Programming Interest Group in Seattle.<br />
<br />
;[http://groups.google.com/group/hugvan Vancouver, Canada: Haskell Programmers Group]<br />
:Regular informal meetings for local Haskell programmers/devotees.<br />
<br />
====East Coast====<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.cafe/21856 New York Functional Programmers Network]<br />
:Come and meet like-minded functional programmers in the New York area. The next meeting is at 6:30pm on February 26th, at Credit Suisse's offices. Paul Hudak from Yale will be giving a talk on real-time sound synthesis using Haskell. Please RSVP at the [http://lisp.meetup.com/59/ NYFPN Meetup Page].<br />
<br />
;[http://www.lisperati.com/fringedc.html FringeDC Washington]<br />
:Meetings about functional programming languages in Washington DC.<br />
<br />
====Central====<br />
<br />
;[http://leibnizdream.wordpress.com/2007/12/22/new-austin-functional-programmers-group-in-2008/ Austin Functional Programmers Group]<br />
:See the [http://groups.google.com/group/austin-fp discussion group] for more.<br />
<br />
;[http://groups.google.com/group/real-world-haskell-book-club/browse_thread/thread/3e8e59768c8c50a9 Colorado Area Haskell Study Group]<br />
<br />
;[http://www.facebook.com/pages/Chicago-IL/Chicago-Haskell-User-Group/115989593098 Chicago Haskell User Group] — brand new (August 2009) and still organizing.<br />
<br />
===Australia===<br />
<br />
;[http://groups.google.com/group/fp-syd FP-SYD, the Sydney (Australia) Functional Programming group]<br />
:FP hackers in Sydney.<br />
<br />
;[http://sites.google.com/site/fpunion/ (FPU) Melbourne Functional Programming Union]<br />
:The FPU is a collective of functional programming language enthusiasts, which has been in operation since 1998. We are based at the University of Melbourne, in the Department of Computer Science and Software Engineering, but we are open to all members of the community. We meet on a regular basis for lively discussions on topics broadly associated with the declarative programming paradigm.<br />
<br />
;[http://www.meetup.com/Brisbane-Functional-Programming-Group-BFG/ Brisbane Functional Programming Group]<br />
; A group for Functional Programming with Haskell, Scala and other languages.<br />
<br />
===Europe===<br />
<br />
;[http://www.londonhug.net/ London Haskell User Group]<br />
:The first meeting of the London Haskell User Group took place on 23rd May 2007, at City University in central London<br />
<br />
;Haskell in Leipzig<br />
:Hal, they have videos [http://iba-cg.de/haskell.html online].<br />
<br />
;[http://users.ecs.soton.ac.uk/pocm06r/fpsig/ Southampton University FPSIG]<br />
:The Functional Programming Special Interest Group of the University of Southampton is a meeting for people interested in FP and Haskell and meet weekly on Tuesdays at 11.30, on the Access Grid Room of Blg. 32<br />
<br />
;[http://oasis.yi.org/oasis/HUGZ Haskell User Group Zurich]<br />
:A user group for the haskell users residing in Zurich and surroundings. It's new and still being formed.<br />
<br />
;[[IsraelHaskell]] User Group<br />
:[http://article.gmane.org/gmane.comp.lang.haskell.cafe/28877 Are getting organised].<br />
<br />
;[http://spbhug.folding-maps.org Saint-Petersburg Haskell User Group]<br />
:The next meeting will be held in April, 2008.<br />
<br />
;[[ItaloHaskell]]<br />
:We had a first meeting in August 2008 and we are planning a second one sometime during the 2008/2009 Autumn/Winter season.<br />
<br />
;[[Reykjavik Haskell User Group]] Iceland<br />
;[http://groups.google.com/group/haskell-is Currently recruiting members]<br />
<br />
;[http://groups.google.com/group/core-haskell?lnk=srg Turkey Haskell Programmer's Group]<br />
:Formed by Turkish Functional Programmers, the group began to communicate via an e-mail list opened by core.gen.tr. The first contribution is hlibev project by Aycan iRiCAN.<br />
<br />
;[http://bilfp.wikidot.com/ BILFP (Bilkent University Comp. Eng. Dept. Functional Programming Society)] Turkey <br />
:Project aims to improve people's knowledge and encourage the use of functional programming languages &mdash; especially in Turkey. Group is open to functional-programming-related discussions and establishes related presentations at Bilkent University that are open to anybody.<br />
<br />
;[[Dutch HUG]]<br />
:The Dutch HUG meets monthly in an informal setting.<br />
<br />
;[http://groups.google.com/group/fp-southwales fp-southwales], the South Wales Functional Programming User Group<br />
:Starting up in late 2009, based out of Swansea University.<br />
<br />
===South America===<br />
<br />
;[http://groups.google.com/group/hug-br HUG-BR]<br />
:Haskell Users' Group for Brasil<br />
<br />
===Asia===<br />
<br />
;[http://lisp.org.cn/en/ China Lisp User Group]<br />
:China Lisp User Group (CLUG) is the earliest founded Lisp user group in China. <br />
<br />
;[http://www.starling-software.com/en/tsac.html Tokyo Society for the Application of Currying]<br />
<br />
== Workshops/meet ups ==<br />
<br />
Less regular, and move around. Usually have a few talks from invited speakers.<br />
<br />
;[[AngloHaskell]]<br />
:AngloHaskell is a Haskell meeting held in England once a year.<br />
<br />
;[[OzHaskell]]<br />
:Australian Haskell Programmer's Group<br />
<br />
;[[AmeroHaskell]]<br />
:USAsian Haskell Programmer's Group<br />
<br />
;[http://taichi.ddns.comp.nus.edu.sg/taichiwiki/SingHaskell2007 SingHaskell]<br />
:Sing(apore)Haskell is a Haskell (and related languages) meeting in Singapore<br />
* [http://www.comp.nus.edu.sg/~sulzmann/singhaskell07/index.html slides]<br />
<br />
;[http://www.comp.mq.edu.au/~asloane/pmwiki.php/SAPLING/HomePage Sydney Area Programming Languages Interest Group]<br />
:10am-4pm, June 12, 2007. Room T5, Building E7B, Macquarie University<br />
<br />
;[http://www.cs.uu.nl/~johanj/FPDag2008/ Utrecht Functioneel Programmeren dag 2008]<br />
:11 januari 2008<br />
<br />
== Hackathons ==<br />
<br />
Getting together to squash bugs and write new stuff. For a more complete list, see [[Hackathon]].<br />
<br />
;[http://haskell.org/haskellwiki/Hac_2007 Hackathons]<br />
:Hac 07 was held January 10-12, 2007, Oxford University Computing Laboratory<br />
<br />
;[http://haskell.org/haskellwiki/HaL3 HaL3 Hackathon]<br />
:HaL3 was held Apr 19-20, 2008, Leipzig<br />
<br />
;[[Hac5]]<br />
:Hac5 was held 17-19 April 2009 in Utrecht.<br />
<br />
== Conferences ==<br />
<br />
See the [[Conferences]] page for academic workshops and conferences<br />
focusing on Haskell and related technology</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=User_groups&diff=31659User groups2009-11-19T09:28:16Z<p>HowardBGolden: More information about BILFP</p>
<hr />
<div>[[Category:Community]]<br />
<br />
A range of Haskell User Groups are springing up all over. Also see a [http://www.frappr.com/haskellers Map of Haskellers].<br />
<br />
== User groups ==<br />
<br />
Regular meetings in a particular geographical area. Great if you want to see and meet other Haskellers.<br />
<br />
===North America===<br />
<br />
====West Coast ====<br />
<br />
;[http://socalfp.blogspot.com/ SoCal FP Group]<br />
<br />
;[http://bayfp.org/ The Bay Area Functional Programmers group]<br />
:Meeting monthly in the San Francisco Bay area. See [http://bayfp.org/blog their blog] for more details and news of upcoming meetings.<br />
<br />
;[http://groups.google.com/group/pdxfunc PDXfunc: Portland FP Group]<br />
:Monthly meetings of the Portland, Oregon functional programming group. Meetings occur on the second Monday of each month at 7 pm. They are held at [http://www.cubespacepdx.com CubeSpace] on 6th & Grant ([http://www.cubespacepdx.com/directions directions]), which generously provides the space free of charge. <br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2008-February/038991.html Seattle: Northwest Functional Programming Interest Group]<br />
:a Northwest Functional Programming Interest Group in Seattle.<br />
<br />
;[http://groups.google.com/group/hugvan Vancouver, Canada: Haskell Programmers Group]<br />
:Regular informal meetings for local Haskell programmers/devotees.<br />
<br />
====East Coast====<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.cafe/21856 New York Functional Programmers Network]<br />
:Come and meet like-minded functional programmers in the New York area. The next meeting is at 6:30pm on February 26th, at Credit Suisse's offices. Paul Hudak from Yale will be giving a talk on real-time sound synthesis using Haskell. Please RSVP at the [http://lisp.meetup.com/59/ NYFPN Meetup Page].<br />
<br />
;[http://www.lisperati.com/fringedc.html FringeDC Washington]<br />
:Meetings about functional programming languages in Washington DC.<br />
<br />
====Central====<br />
<br />
;[http://leibnizdream.wordpress.com/2007/12/22/new-austin-functional-programmers-group-in-2008/ Austin Functional Programmers Group]<br />
:See the [http://groups.google.com/group/austin-fp discussion group] for more.<br />
<br />
;[http://groups.google.com/group/real-world-haskell-book-club/browse_thread/thread/3e8e59768c8c50a9 Colorado Area Haskell Study Group]<br />
<br />
;[http://www.facebook.com/pages/Chicago-IL/Chicago-Haskell-User-Group/115989593098 Chicago Haskell User Group] — brand new (August 2009) and still organizing.<br />
<br />
===Australia===<br />
<br />
;[http://groups.google.com/group/fp-syd FP-SYD, the Sydney (Australia) Functional Programming group]<br />
:FP hackers in Sydney.<br />
<br />
;[http://sites.google.com/site/fpunion/ (FPU) Melbourne Functional Programming Union]<br />
:The FPU is a collective of functional programming language enthusiasts, which has been in operation since 1998. We are based at the University of Melbourne, in the Department of Computer Science and Software Engineering, but we are open to all members of the community. We meet on a regular basis for lively discussions on topics broadly associated with the declarative programming paradigm.<br />
<br />
;[http://www.meetup.com/Brisbane-Functional-Programming-Group-BFG/ Brisbane Functional Programming Group]<br />
; A group for Functional Programming with Haskell, Scala and other languages.<br />
<br />
===Europe===<br />
<br />
;[http://www.londonhug.net/ London Haskell User Group]<br />
:The first meeting of the London Haskell User Group took place on 23rd May 2007, at City University in central London<br />
<br />
;Haskell in Leipzig<br />
:Hal, they have videos [http://iba-cg.de/haskell.html online].<br />
<br />
;[http://users.ecs.soton.ac.uk/pocm06r/fpsig/ Southampton University FPSIG]<br />
:The Functional Programming Special Interest Group of the University of Southampton is a meeting for people interested in FP and Haskell and meet weekly on Tuesdays at 11.30, on the Access Grid Room of Blg. 32<br />
<br />
;[http://oasis.yi.org/oasis/HUGZ Haskell User Group Zurich]<br />
:A user group for the haskell users residing in Zurich and surroundings. It's new and still being formed.<br />
<br />
;[[IsraelHaskell]] User Group<br />
:[http://article.gmane.org/gmane.comp.lang.haskell.cafe/28877 Are getting organised].<br />
<br />
;[http://spbhug.folding-maps.org Saint-Petersburg Haskell User Group]<br />
:The next meeting will be held in April, 2008.<br />
<br />
;[[ItaloHaskell]]<br />
:We had a first meeting in August 2008 and we are planning a second one sometime during the 2008/2009 Autumn/Winter season.<br />
<br />
;[[Reykjavik Haskell User Group]] Iceland<br />
;[http://groups.google.com/group/haskell-is Currently recruiting members]<br />
<br />
;[http://groups.google.com/group/core-haskell?lnk=srg Turkey Haskell Programmer's Group]<br />
:Formed by Turkish Functional Programmers, the group began to communicate via an e-mail list opened by core.gen.tr. The first contribution is hlibev project by Aycan iRiCAN.<br />
<br />
;[http://bilfp.wikidot.com/ BILFP (Bilkent University Comp. Eng. Dept. Functional Programming Society)] Turkey <br />
:Project aims to improve people's knowledge and encourage the use of functional programming languages &mdash; especially in Turkey. Group is open to functional programming related discussions and establishes related presentations at Bilkent University that are open to anybody.<br />
<br />
;[[Dutch HUG]]<br />
:The Dutch HUG meets monthly in an informal setting.<br />
<br />
;[http://groups.google.com/group/fp-southwales fp-southwales], the South Wales Functional Programming User Group<br />
:Starting up in late 2009, based out of Swansea University.<br />
<br />
===South America===<br />
<br />
;[http://groups.google.com/group/hug-br HUG-BR]<br />
:Haskell Users' Group for Brasil<br />
<br />
===Asia===<br />
<br />
;[http://lisp.org.cn/en/ China Lisp User Group]<br />
:China Lisp User Group (CLUG) is the earliest founded Lisp user group in China. <br />
<br />
;[http://www.starling-software.com/en/tsac.html Tokyo Society for the Application of Currying]<br />
<br />
== Workshops/meet ups ==<br />
<br />
Less regular, and move around. Usually have a few talks from invited speakers.<br />
<br />
;[[AngloHaskell]]<br />
:AngloHaskell is a Haskell meeting held in England once a year.<br />
<br />
;[[OzHaskell]]<br />
:Australian Haskell Programmer's Group<br />
<br />
;[[AmeroHaskell]]<br />
:USAsian Haskell Programmer's Group<br />
<br />
;[http://taichi.ddns.comp.nus.edu.sg/taichiwiki/SingHaskell2007 SingHaskell]<br />
:Sing(apore)Haskell is a Haskell (and related languages) meeting in Singapore<br />
* [http://www.comp.nus.edu.sg/~sulzmann/singhaskell07/index.html slides]<br />
<br />
;[http://www.comp.mq.edu.au/~asloane/pmwiki.php/SAPLING/HomePage Sydney Area Programming Languages Interest Group]<br />
:10am-4pm, June 12, 2007. Room T5, Building E7B, Macquarie University<br />
<br />
;[http://www.cs.uu.nl/~johanj/FPDag2008/ Utrecht Functioneel Programmeren dag 2008]<br />
:11 januari 2008<br />
<br />
== Hackathons ==<br />
<br />
Getting together to squash bugs and write new stuff. For a more complete list, see [[Hackathon]].<br />
<br />
;[http://haskell.org/haskellwiki/Hac_2007 Hackathons]<br />
:Hac 07 was held January 10-12, 2007, Oxford University Computing Laboratory<br />
<br />
;[http://haskell.org/haskellwiki/HaL3 HaL3 Hackathon]<br />
:HaL3 was held Apr 19-20, 2008, Leipzig<br />
<br />
;[[Hac5]]<br />
:Hac5 was held 17-19 April 2009 in Utrecht.<br />
<br />
== Conferences ==<br />
<br />
See the [[Conferences]] page for academic workshops and conferences<br />
focusing on Haskell and related technology</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=User_groups&diff=31658User groups2009-11-19T09:09:15Z<p>HowardBGolden: Add BILFP to Europe/Turkey</p>
<hr />
<div>[[Category:Community]]<br />
<br />
A range of Haskell User Groups are springing up all over. Also see a [http://www.frappr.com/haskellers Map of Haskellers].<br />
<br />
== User groups ==<br />
<br />
Regular meetings in a particular geographical area. Great if you want to see and meet other Haskellers.<br />
<br />
===North America===<br />
<br />
====West Coast ====<br />
<br />
;[http://socalfp.blogspot.com/ SoCal FP Group]<br />
<br />
;[http://bayfp.org/ The Bay Area Functional Programmers group]<br />
:Meeting monthly in the San Francisco Bay area. See [http://bayfp.org/blog their blog] for more details and news of upcoming meetings.<br />
<br />
;[http://groups.google.com/group/pdxfunc PDXfunc: Portland FP Group]<br />
:Monthly meetings of the Portland, Oregon functional programming group. Meetings occur on the second Monday of each month at 7 pm. They are held at [http://www.cubespacepdx.com CubeSpace] on 6th & Grant ([http://www.cubespacepdx.com/directions directions]), which generously provides the space free of charge. <br />
<br />
;[http://www.haskell.org/pipermail/haskell-cafe/2008-February/038991.html Seattle: Northwest Functional Programming Interest Group]<br />
:a Northwest Functional Programming Interest Group in Seattle.<br />
<br />
;[http://groups.google.com/group/hugvan Vancouver, Canada: Haskell Programmers Group]<br />
:Regular informal meetings for local Haskell programmers/devotees.<br />
<br />
====East Coast====<br />
<br />
;[http://article.gmane.org/gmane.comp.lang.haskell.cafe/21856 New York Functional Programmers Network]<br />
:Come and meet like-minded functional programmers in the New York area. The next meeting is at 6:30pm on February 26th, at Credit Suisse's offices. Paul Hudak from Yale will be giving a talk on real-time sound synthesis using Haskell. Please RSVP at the [http://lisp.meetup.com/59/ NYFPN Meetup Page].<br />
<br />
;[http://www.lisperati.com/fringedc.html FringeDC Washington]<br />
:Meetings about functional programming languages in Washington DC.<br />
<br />
====Central====<br />
<br />
;[http://leibnizdream.wordpress.com/2007/12/22/new-austin-functional-programmers-group-in-2008/ Austin Functional Programmers Group]<br />
:See the [http://groups.google.com/group/austin-fp discussion group] for more.<br />
<br />
;[http://groups.google.com/group/real-world-haskell-book-club/browse_thread/thread/3e8e59768c8c50a9 Colorado Area Haskell Study Group]<br />
<br />
;[http://www.facebook.com/pages/Chicago-IL/Chicago-Haskell-User-Group/115989593098 Chicago Haskell User Group] — brand new (August 2009) and still organizing.<br />
<br />
===Australia===<br />
<br />
;[http://groups.google.com/group/fp-syd FP-SYD, the Sydney (Australia) Functional Programming group]<br />
:FP hackers in Sydney.<br />
<br />
;[http://sites.google.com/site/fpunion/ (FPU) Melbourne Functional Programming Union]<br />
:The FPU is a collective of functional programming language enthusiasts, which has been in operation since 1998. We are based at the University of Melbourne, in the Department of Computer Science and Software Engineering, but we are open to all members of the community. We meet on a regular basis for lively discussions on topics broadly associated with the declarative programming paradigm.<br />
<br />
;[http://www.meetup.com/Brisbane-Functional-Programming-Group-BFG/ Brisbane Functional Programming Group]<br />
; A group for Functional Programming with Haskell, Scala and other languages.<br />
<br />
===Europe===<br />
<br />
;[http://www.londonhug.net/ London Haskell User Group]<br />
:The first meeting of the London Haskell User Group took place on 23rd May 2007, at City University in central London<br />
<br />
;Haskell in Leipzig<br />
:Hal, they have videos [http://iba-cg.de/haskell.html online].<br />
<br />
;[http://users.ecs.soton.ac.uk/pocm06r/fpsig/ Southampton University FPSIG]<br />
:The Functional Programming Special Interest Group of the University of Southampton is a meeting for people interested in FP and Haskell and meet weekly on Tuesdays at 11.30, on the Access Grid Room of Blg. 32<br />
<br />
;[http://oasis.yi.org/oasis/HUGZ Haskell User Group Zurich]<br />
:A user group for the haskell users residing in Zurich and surroundings. It's new and still being formed.<br />
<br />
;[[IsraelHaskell]] User Group<br />
:[http://article.gmane.org/gmane.comp.lang.haskell.cafe/28877 Are getting organised].<br />
<br />
;[http://spbhug.folding-maps.org Saint-Petersburg Haskell User Group]<br />
:The next meeting will be held in April, 2008.<br />
<br />
;[[ItaloHaskell]]<br />
:We had a first meeting in August 2008 and we are planning a second one sometime during the 2008/2009 Autumn/Winter season.<br />
<br />
;[[Reykjavik Haskell User Group]] Iceland<br />
;[http://groups.google.com/group/haskell-is Currently recruiting members]<br />
<br />
;[http://groups.google.com/group/core-haskell?lnk=srg Turkey Haskell Programmer's Group]<br />
:Formed by Turkish Functional Programmers, the group began to communicate via an e-mail list opened by core.gen.tr. The first contribution is hlibev project by Aycan iRiCAN.<br />
<br />
;[http://bilfp.wikidot.com/ BILFP (Bilkent University Comp. Eng. Dept. Functional Programming Society)] Turkey <br />
<br />
;[[Dutch HUG]]<br />
:The Dutch HUG meets monthly in an informal setting.<br />
<br />
;[http://groups.google.com/group/fp-southwales fp-southwales], the South Wales Functional Programming User Group<br />
:Starting up in late 2009, based out of Swansea University.<br />
<br />
===South America===<br />
<br />
;[http://groups.google.com/group/hug-br HUG-BR]<br />
:Haskell Users' Group for Brasil<br />
<br />
===Asia===<br />
<br />
;[http://lisp.org.cn/en/ China Lisp User Group]<br />
:China Lisp User Group (CLUG) is the earliest founded Lisp user group in China. <br />
<br />
;[http://www.starling-software.com/en/tsac.html Tokyo Society for the Application of Currying]<br />
<br />
== Workshops/meet ups ==<br />
<br />
Less regular, and move around. Usually have a few talks from invited speakers.<br />
<br />
;[[AngloHaskell]]<br />
:AngloHaskell is a Haskell meeting held in England once a year.<br />
<br />
;[[OzHaskell]]<br />
:Australian Haskell Programmer's Group<br />
<br />
;[[AmeroHaskell]]<br />
:USAsian Haskell Programmer's Group<br />
<br />
;[http://taichi.ddns.comp.nus.edu.sg/taichiwiki/SingHaskell2007 SingHaskell]<br />
:Sing(apore)Haskell is a Haskell (and related languages) meeting in Singapore<br />
* [http://www.comp.nus.edu.sg/~sulzmann/singhaskell07/index.html slides]<br />
<br />
;[http://www.comp.mq.edu.au/~asloane/pmwiki.php/SAPLING/HomePage Sydney Area Programming Languages Interest Group]<br />
:10am-4pm, June 12, 2007. Room T5, Building E7B, Macquarie University<br />
<br />
;[http://www.cs.uu.nl/~johanj/FPDag2008/ Utrecht Functioneel Programmeren dag 2008]<br />
:11 januari 2008<br />
<br />
== Hackathons ==<br />
<br />
Getting together to squash bugs and write new stuff. For a more complete list, see [[Hackathon]].<br />
<br />
;[http://haskell.org/haskellwiki/Hac_2007 Hackathons]<br />
:Hac 07 was held January 10-12, 2007, Oxford University Computing Laboratory<br />
<br />
;[http://haskell.org/haskellwiki/HaL3 HaL3 Hackathon]<br />
:HaL3 was held Apr 19-20, 2008, Leipzig<br />
<br />
;[[Hac5]]<br />
:Hac5 was held 17-19 April 2009 in Utrecht.<br />
<br />
== Conferences ==<br />
<br />
See the [[Conferences]] page for academic workshops and conferences<br />
focusing on Haskell and related technology</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Gentoo/HaskellPlatform&diff=29469Gentoo/HaskellPlatform2009-08-07T21:16:15Z<p>HowardBGolden: Add haskell-updater to p.unmask file</p>
<hr />
<div>Gentoo supports the Haskell Platform!<br />
<br />
==Unmasking GHC 6.10.4 and the Haskell Platform==<br />
<br />
Currently (2009-08-02) GHC 6.10.4 and a few libraries are hard masked, meaning you will have to p.unmask yourself before installing. This is because we're still updating the portage packages to get full GHC 6.10.4 support.<br />
<br />
<code><br />
echo dev-lang/ghc >> /etc/portage/package.unmask<br />
echo dev-haskell/parallel >> /etc/portage/package.unmask<br />
echo dev-haskell/haddock >> /etc/portage/package.unmask<br />
echo app-admin/haskell-updater >> /etc/portage/package.unmask<br />
</code><br />
<br />
As the haskell-platform depends on this recent GHC version, you'll need to unmask it too;<br />
<br />
<code><br />
echo dev-haskell/haskell-platform >> /etc/portage/package.unmask<br />
</code><br />
<br />
Don't forget that these packages are also ~keyworded.<br />
<br />
==Install==<br />
<br />
Now, to install, run:<br />
<br />
<code><br />
emerge haskell-platform<br />
</code><br />
<br />
This will pull the GHC compiler, and all the libraries included in HP. If you want haddock documentation, set your <code>USE="doc"</code>. If you also want profiling libraries, set <code>USE="profile"</code>.<br />
<br />
==Feedback==<br />
<br />
Got any feedback for the packages above? Let us know!<br />
<br />
You'll find us in <code>#gentoo-haskell @ freenode</code>, or send your comments to [mailto:haskell@gentoo.org haskell@gentoo.org].</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Cookbook/Compilers_and_interpreters&diff=29198Cookbook/Compilers and interpreters2009-07-22T23:24:34Z<p>HowardBGolden: Change more Prelude links to HaskellWiki page</p>
<hr />
<div>= Prelude =<br />
<br />
A lot of functions are defined in the [[Prelude]]. The Prelude is a standard module imported by default into all Haskell module.<br />
<br />
Also, if you ever want to search for a function, based on the name, type or module, take a look at the excellent [[Hoogle]]. This is for a lot of people a must-have while debugging and writing Haskell programs.<br />
<br />
= GHCi/Hugs =<br />
== GHCi interaction ==<br />
To start GHCi from a command prompt, simply type `ghci'<br />
<br />
$ ghci<br />
___ ___ _<br />
/ _ \ /\ /\/ __(_)<br />
/ /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98.<br />
/ /_\\/ __ / /___| | http://www.haskell.org/ghc/<br />
\____/\/ /_/\____/|_| Type :? for help.<br />
<br />
Loading package base ... linking ... done.<br />
Prelude><br />
<br />
[[Prelude]] is the "base" library of Haskell.<br />
<br />
To create variables at the GHCi prompt, use `let'<br />
<haskell><br />
Prelude> let x = 5<br />
Prelude> x<br />
5<br />
Prelude> let y = 3<br />
Prelude> y<br />
3<br />
Prelude> x + y<br />
8<br />
</haskell><br />
<br />
`let' is also the way to create simple functions at the GHCi prompt<br />
<haskell><br />
Prelude> let fact n = product [1..n]<br />
Prelude> fact 5<br />
120<br />
</haskell><br />
<br />
<br />
== Checking Types ==<br />
To check the type of an expression or function, use the command `:t'<br />
<haskell><br />
Prelude> :t x<br />
x :: Integer<br />
Prelude> :t "Hello"<br />
"Hello" :: [Char]<br />
</haskell><br />
Haskell has the following types defined in the [[Prelude]].<br />
<haskell><br />
Int -- bounded, word-sized integers<br />
Integer -- unbounded integers<br />
Double -- floating point values<br />
Char -- characters<br />
String -- equivalent to [Char], strings are lists of characters<br />
() -- the unit type<br />
Bool -- booleans<br />
[a] -- lists<br />
(a,b) -- tuples / product types<br />
Either a b -- sum types<br />
Maybe a -- optional values <br />
</haskell></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Cookbook/Compilers_and_interpreters&diff=29197Cookbook/Compilers and interpreters2009-07-22T23:05:48Z<p>HowardBGolden: Change Prelude and Hoogle links to HaskellWiki pages</p>
<hr />
<div>= Prelude =<br />
<br />
A lot of functions are defined in the [[Prelude]]. The Prelude is a standard module imported by default into all Haskell module.<br />
<br />
Also, if you ever want to search for a function, based on the name, type or module, take a look at the excellent [[Hoogle]]. This is for a lot of people a must-have while debugging and writing Haskell programs.<br />
<br />
= GHCi/Hugs =<br />
== GHCi interaction ==<br />
To start GHCi from a command prompt, simply type `ghci'<br />
<br />
$ ghci<br />
___ ___ _<br />
/ _ \ /\ /\/ __(_)<br />
/ /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98.<br />
/ /_\\/ __ / /___| | http://www.haskell.org/ghc/<br />
\____/\/ /_/\____/|_| Type :? for help.<br />
<br />
Loading package base ... linking ... done.<br />
Prelude><br />
<br />
[http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html Prelude] is the "base" library of Haskell.<br />
<br />
To create variables at the GHCi prompt, use `let'<br />
<haskell><br />
Prelude> let x = 5<br />
Prelude> x<br />
5<br />
Prelude> let y = 3<br />
Prelude> y<br />
3<br />
Prelude> x + y<br />
8<br />
</haskell><br />
<br />
`let' is also the way to create simple functions at the GHCi prompt<br />
<haskell><br />
Prelude> let fact n = product [1..n]<br />
Prelude> fact 5<br />
120<br />
</haskell><br />
<br />
<br />
== Checking Types ==<br />
To check the type of an expression or function, use the command `:t'<br />
<haskell><br />
Prelude> :t x<br />
x :: Integer<br />
Prelude> :t "Hello"<br />
"Hello" :: [Char]<br />
</haskell><br />
Haskell has the following types defined in the [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html Standard Prelude].<br />
<haskell><br />
Int -- bounded, word-sized integers<br />
Integer -- unbounded integers<br />
Double -- floating point values<br />
Char -- characters<br />
String -- equivalent to [Char], strings are lists of characters<br />
() -- the unit type<br />
Bool -- booleans<br />
[a] -- lists<br />
(a,b) -- tuples / product types<br />
Either a b -- sum types<br />
Maybe a -- optional values <br />
</haskell></div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Package_versioning_policy&diff=28091Package versioning policy2009-05-03T00:53:19Z<p>HowardBGolden: Update link to Eternal compatibility in theory</p>
<hr />
<div>== Rationale ==<br />
<br />
The goal of a versioning system is to inform clients of a package of changes to that package that might affect them, and to provide a way for clients to specify a particular version or range of versions of a dependency that they are compatible with.<br />
<br />
[http://haskell.org/cabal Cabal] provides the raw materials for versioning: it allows packages to specify their own version, and it allows dependencies that specify which versions of the dependent package are acceptable. Cabal will select dependencies based on the constraints.<br />
<br />
What is missing from this picture is a ''policy'' that tells the library developer how to set their version numbers, and tells a client how to write a dependency that means their package will not try to compile against an incompatible dependency. For some time there has been an informal policy in use in the Haskell community, but it became clear that we were running into trouble with incorrectly-specified dependencies and unbuildable packages, so this page is an attempt to formalize the policy.<br />
<br />
== Version numbers ==<br />
<br />
A package version number should have the form ''A.B.C'', and may optionally have any number of additional components, for example 2.1.0.4 (in this case, ''A''=2, ''B''=1, ''C=0''). This policy defines the meaning of the first three components ''A-C'', the other components can be used in any way the package maintainer sees fit.<br />
<br />
Version number ordering is already defined by Cabal as the lexicographic ordering of the components. For example, 2.1 > 1.3, and 2.1.1 > 2.1. (The <tt>Data.Version.Version</tt> type and its <tt>Ord</tt> instance embody this ordering).<br />
<br />
''A.B'' is known as the ''major'' version number, and ''C'' the ''minor'' version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:<br />
<br />
# If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or instances were added or removed, then the new ''A.B'' must be greater than the previous ''A.B''. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.<br />
# Otherwise, if only new bindings, types, classes or modules (but see below) were added to the interface, then ''A.B'' may remain the same but the new ''C'' must be greater than the old ''C''.<br />
# Otherwise, ''A.B.C'' may remain the same (other version components may change).<br />
<br />
Hence ''A.B.C'' uniquely identifies the API. A client that wants to specify that they depend on a particular version of the API can specify a particular ''A.B.C'' and be sure of getting that API only. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
Often a package maintainer wants to add to an API without breaking backwards compatibility, and in that case they can follow the rules of point 2, and increase only ''C''. A client can specify that they are insensitive to additions to the API by allowing a range of ''C'' values, e.g. <tt>build-depends: base >= 2.1.1 && < 2.2</tt>.<br />
<br />
=== Adding new modules ===<br />
<br />
Strictly speaking, adding new modules might cause an unavoidable name collision in dependent code. However, the likelihood is so low that only an increase of the minor version number is required. Generic module names (e.g. Data.Set) are more likely to collide. In this case increasing the major version number likely makes sense. <br />
<br />
== Dependencies in Cabal ==<br />
<br />
When publishing a Cabal package, you should ensure that your dependencies in the <tt>build-depends</tt> field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency. <br />
<br />
At some point in the future, Hackage may refuse to accept packages that do not follow this convention. The aim is that before this happens, we will put in place tool support that makes it easier to follow the convention and less painful when dependencies are updated.<br />
<br />
To minimize breakage when new package versions are released, you can use dependencies that are insensitive to minor version changes (e.g. <tt>foo >= 1.2.1 && < 1.3</tt>). However, note that this approach is slightly risky: when a package exports more things than before, there is a chance that your code will fail to compile due to new name-clash errors. The risk from new name clashes tends to be small, and you can always eliminate it by using explicit import lists if you want.<br />
<br />
== Cabal extensions ==<br />
<br />
To make specifying dependencies easier, we probably want the extensions to the dependency syntax suggested by Thomas Schilling:<br />
<br />
* http://www.haskell.org/pipermail/cabal-devel/2007-September/001111.html<br />
<br />
== Tools ==<br />
<br />
* script to check for API changes in gtk2hs: http://darcs.haskell.org/gtk2hs/tools/apidiff/<br />
<br />
== Related ==<br />
<br />
* [[Sven Moritz Hallberg]], "[[The_Monad.Reader/Issue2/EternalCompatibilityInTheory|Eternal compatibility in theory]]," [[The Monad.Reader]], [[The Monad.Reader/Issue2|Issue 2]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=User_talk:Ashley_Y&diff=23249User talk:Ashley Y2008-10-04T08:17:27Z<p>HowardBGolden: Request for MediaWiki upgrade</p>
<hr />
<div>== Math Content ==<br />
<br />
Hi Ashley. I notice you are a sysop for haskellwiki. I'm not sure if this is a good place to ask this, but do you know if there is a reason why math support is not enabled for this wiki? I was planning to add some simple math background for some things and would have liked it to show appropriately. (If it is just because no one was sure on how to configure it, I'd be happy to tell what I had to do for my personal home wiki (same software)). [[User:BrettGiles|BrettGiles]] 22:16, 25 February 2006 (UTC)<br />
<br />
:Now switched on. If it's not showing up on a page, purge the page by adding <tt>&amp;action=purge</tt> to the end of the URL. &mdash;[[User:Ashley Y|Ashley Y]] 00:20, 27 February 2006 (UTC)<br />
<br />
:: Thank you - works perfectly. [[User:BrettGiles|BrettGiles]] 18:15, 27 February 2006 (UTC)<br />
<br />
== haskell.org skin? ==<br />
<br />
Hi Ashley. I hope you're the right person to ask about this. I'm currently setting up a wiki, and I was wondering how you got haskellwiki looking like it does? I really hate the wikipedia look, and I'd like something nice and simple I could tweak. I understand that you can get skins for mediawiki - is the haskell.org look available in this form? - [[User:MikeDodds|MikeDodds]] 12:33, 1 March 2006 (UTC)<br />
<br />
:I suppose I should publish the skin file somehow. I'm not sure the best way. &mdash;[[User:Ashley Y|Ashley Y]] 09:44, 25 March 2006 (UTC)<br />
<br />
:OK, see [[HaskellWiki:Site software]]. &mdash;[[User:Ashley Y|Ashley Y]] 01:15, 20 September 2006 (UTC)<br />
<br />
== [[Libraries and tools]] copyright status ==<br />
<br />
Dear Ashley Y,<br />
<br />
I saw that the page [[Libraries and tools/Genetic programming]] got a <nowiki>{{unknown copyright}}</nowiki> mark in the recent days during the moving to its own separate page. This mark asks me to resolve the copyright status.<br />
<br />
It was me who wrote the content of this page ([http://www.haskell.org/haskellwiki/?title=Libraries_and_tools&diff=2265&oldid=2252 here is the diff page showing this]) in February, so I thought it need not be licenced explicitly, it is automatically licenced under [[HaskellWiki:Licensing]].<br />
<br />
Have I to do something?<br />
<br />
Tank You very much in advance<br />
<br />
Best wishes<br />
<br />
[[User:EndreyMark|EndreyMark]] 12:32, 24 March 2006 (UTC)<br />
<br />
:Great, go ahead and remove the "unknown copyright" label. &mdash;[[User:Ashley Y|Ashley Y]] 09:42, 25 March 2006 (UTC)<br />
<br />
:Thank You, I have done it. [[User:EndreyMark|EndreyMark]] 18:05, 25 March 2006 (UTC)<br />
<br />
== Deletion of [[Continuation passing style]] ==<br />
<br />
Dear Ashley,<br />
<br />
Acidentally, I have created a [[Continuation passing style]] page superfluously.<br />
Because a [[Continuation]] article exists already, I suppose the superfluous empty page should be deleted, because its existence can be confusing (e.g. editors linking word "[[Continuation passing style]]" will not get a warning red link any more, but a misleading empty page). I cannot delete the page (only empty it, but it is not enough).<br />
<br />
Thank You in advance<br />
<br />
[[User:EndreyMark|EndreyMark]] 08:14, 27 October 2006 (UTC)<br />
<br />
:I made it a redirect instead. &mdash;[[User:Ashley Y|Ashley Y]] 18:44, 31 October 2006 (UTC)<br />
<br />
== Interwiki map ==<br />
<br />
Hi: could you add some stuff to the interwiki map? In [[Haste]], I was trying to interwiki to the English Wikipedia using the usual <nowiki>[[wikipedia:Scintilla]]</nowiki> interwiki link, but it didn't work (nor did en:, or wiki: - which just took one to c2.com). [[User:Gwern|Gwern]]<br />
<br />
== Same logo, less bytes ==<br />
<br />
If you're interested in using it, I shaved 407 bytes off the logo in the upper-left-hand corner of the wiki. It's [[:Image:Haskellwiki_logo_small.png|uploaded here]]. [[User:Olathe|Olathe]] 00:33, 12 August 2008 (UTC)<br />
<br />
== Latex upgrade ==<br />
While testing Pandoc's conversion of LaTeX to MediaWiki markup, I noticed some bugs. Compare [[User:Gwern/kenn]] to [https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn https://secure.wikimedia.org/wikipedia/en/wiki/User:Gwern/kenn]. The haskell.org version features many ugly red sections like '<nowiki>Failed to parse (unknown function\begin): \begin{array}{rclcl} \phi & ::= & P(t_1, \cdots, t_n) \\ & \mid & \neg\phi \\ & \mid & \phi_1 \Rightarrow \phi_2 \\ & \mid & TT & \mid & FF \\ & \mid & \phi_1 \wedge \phi_2 & \mid & \phi_1 \vee \phi_2 \\ & \mid & \forall x.\, \phi & \mid & \exists x.\, \phi \end{array}</nowiki>'.<br />
<br />
John MacFarlane, Pandoc's author, thinks this is because of outdated addons to MediaWiki or MediaWiki itself; this is consistent with the same source text not producing those errors on the English Wikipedia. Could you fix this? --[[User:Gwern|Gwern]] 10:46, 6 September 2008 (UTC)<br />
<br />
== Request for MediaWiki Upgrade ==<br />
I request that you update the MediaWiki software to a more recent version. Thanks in advance. &mdash;[[User:HowardBGolden|HowardBGolden]] 08:17, 4 October 2008 (UTC)</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Haskell_programming_tips&diff=22573Haskell programming tips2008-08-23T01:03:12Z<p>HowardBGolden: Things to avoid moved to Haskell programming tips</p>
<hr />
<div>==Preface==<br />
<br />
This page shows several examples of how code can be improved. We try to derive general rules from them, though they cannot be applied deterministicly and are a matter of taste. We all know this, please don't add "this is disputable" to each item!<br />
<br />
Instead, you can now add "this is disputable" on [[/Discussion]] and change this page only when some sort of consensus is reached.<br />
<br />
==Be concise==<br />
<br />
===Don't reinvent the wheel===<br />
<br />
The standard libraries are full of useful functions, possibly too full. If you rewrite an existing function, the reader wonders what the difference to the standard function is. But if you use a standard function, the reader may learn something new and useful.<br />
If you have problems finding an appropriate list function, try this guide:<br />
http://www.cs.chalmers.se/Cs/Grundutb/Kurser/d1pt/d1pta/ListDoc/<br />
<br />
===Avoid explicit recursion===<br />
<br />
Explicit recursion is not generally bad, but you should spend some time trying to find a more declarative implementation using higher order functions.<br />
<br />
Don't define<br />
<haskell><br />
raise :: Num a => a -> [a] -> [a]<br />
raise _ [] = []<br />
raise x (y:ys) = x+y : raise x ys<br />
</haskell><br />
because it is hard for the reader to find out<br />
how much of the list is processed and<br />
on which values the elements of the output list depend.<br />
Just write<br />
<haskell><br />
raise x ys = map (x+) ys<br />
</haskell><br />
or even<br />
<haskell><br />
raise x = map (x+)<br />
</haskell><br />
and the reader knows that the complete list is processed and that each output element depends only on the corresponding input element.<br />
<br />
If you don't find appropriate functions in the standard library, extract a general function. This helps you and others understand the program. Haskell is '''very''' good at factoring out parts of the code.<br />
If you find it very general, put it in a separate module and re-use it. It may appear in the standard libraries later, or you may later find that it is already there.<br />
<br />
Decomposing a problem this way also has the advantage that you can debug more easily. If the last implementation of <hask>raise</hask> does not show the expected behaviour, you can inspect <hask>map</hask> (I hope it is correct :-) ) and the invoked instance of <hask>(+)</hask> separately.<br />
<br />
<br />
''Could this be stated more generally? It seems to me this is a special case of the general principle of separating concerns: iteration over a collection vs operating on elements of a collection should apply. If you can write the loop over a data structure (list, tree, whatever) once and debug it, then you don't need to duplicate that code over and over (at least in haskell), so your code can follow the principle of Wiki:OnceAndOnlyOnce ; Wiki:OnceAndOnlyOnce is a lot harder in languages that don't provide a certain level of functional programming support (i.e. Java requires copy and paste programming, the delegate C# syntax is clumsy but workable - using it is almost Wiki:GoldPlating).''<br />
<br />
<br />
Another example:<br />
The function <hask>count</hask> counts the number of elements<br />
which fulfill a certain property,<br />
i.e. the elements for which the predicate <hask>p</hask> is <hask>True</hask>.<br />
<br />
I found the following code (but convoluted in a more specific function) in a Haskell program<br />
<haskell><br />
count :: (a -> Bool) -> [a] -> Int<br />
count _ [] = 0<br />
count p (x:xs)<br />
| p x = 1 + count p xs<br />
| otherwise = count p xs<br />
</haskell><br />
which you won't like after you become aware of<br />
<haskell><br />
count p = length . filter p<br />
</haskell><br />
.<br />
<br />
<br />
===Only introduce identifiers you need===<br />
<br />
Here is some advice that is useful for every language, including scientific prose<br />
(http://www.cs.utexas.edu/users/EWD/transcriptions/EWD09xx/EWD993.html):<br />
Introduce only identifiers you use.<br />
The compiler will check this for you if you pass an option like <code>-Wall</code> to GHC.<br />
<br />
In an expression like<br />
<haskell><br />
[a | i <- [1..m]]<br />
</haskell><br />
where <hask>a</hask> might be a horrible complex expression it is not easy to see,<br />
that <hask>a</hask> really does not depend on <hask>i</hask>.<br />
<haskell><br />
replicate m a<br />
</haskell><br />
is certainly better here.<br />
<br />
<br />
===Remember the zero===<br />
<br />
Don't forget that zero is a natural number. Recursive definitions become more complicated if the recursion anchor is not chosen properly. For example the function <hask>tupel</hask> presented in ''DMV-Mitteilungen 2004/12-3, Jürgen Bokowski: Haskell, ein gutes Werkzeug der Diskreten Mathematik'' (Haskell, a good tool for discrete mathematics). This is also a good example of how to avoid guards.<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples r l<br />
| r == 1 = [[el] | el <- l]<br />
| length l == r = [l]<br />
| otherwise = (map ([head l] ++) (tuples (r-1) (tail l)))<br />
++ tuples r (tail l)<br />
</haskell><br />
Do you have an idea what it does?<br />
<br />
Let's strip the guards and forget about list comprehension.<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 1 l = map (:[]) l<br />
tuples r l =<br />
if r == length l<br />
then [l]<br />
else<br />
let t = tail l<br />
in map (head l :) (tuples (r-1) t)<br />
++ tuples r t<br />
</haskell><br />
<br />
What about tuples with zero elements? We can add the pattern<br />
<haskell><br />
tuples 0 _ = [[]]<br />
</haskell><br />
but then we can also omit the pattern for 1-tuples.<br />
<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 0 _ = [[]]<br />
tuples r l =<br />
if r == length l<br />
then [l]<br />
else<br />
let t = tail l<br />
in map (head l :) (tuples (r-1) t)<br />
++ tuples r t<br />
</haskell><br />
What about the case <hask>r > length l</hask>? Sure, no reason to let <hask>head</hask> fail - in that case there is no tuple, thus we return an empty list. Again, this saves us one special case.<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 0 _ = [[]]<br />
tuples r l =<br />
if r > length l<br />
then []<br />
else<br />
let t = tail l<br />
in map (head l :) (tuples (r-1) t)<br />
++ tuples r t<br />
</haskell><br />
<br />
We have learnt above that <hask>length</hask> is evil! What about<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 0 _ = [[]]<br />
tuples _ [] = []<br />
tuples r (x:xs) =<br />
map (x :) (tuples (r-1) xs)<br />
++ tuples r xs<br />
</haskell><br />
? It is no longer necessary to compute the length of <hask>l</hask> again and again. The code is easier to read and it covers all special cases, including <hask>tuples (-1) [1,2,3]</hask>!<br />
<br />
''Eliminating the <hask>length</hask> test can worsen performance dramatically in some cases, like <hask>tuples 24 [1..25]</hask>. We could also use <hask>null (drop (r-1) l)</hask> instead of <hask>length l < r</hask>, which works for infinite lists. See also [[Things to avoid#Don't ask for the length of a list, if you don't need it|below]].''<br />
<br />
You can even save one direction of recursion<br />
by explicit computation of the list of all suffixes provided by <hask>tails</hask>.<br />
You can do this with do notation<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 0 _ = [[]]<br />
tuples r xs = do<br />
y:ys <- tails xs<br />
map (y:) (tuples (r-1) ys)<br />
</haskell><br />
<br />
Since <hask>(=<<)</hask> in the list monad is <hask>concatMap</hask>, we can also write this as follows.<br />
Where in the previous version the pattern <hask>y:ys</hask> filtered out the last empty suffix<br />
we have to do this manually now with <hask>init</hask>.<br />
<haskell><br />
tuples :: Int -> [a] -> [[a]]<br />
tuples 0 _ = [[]]<br />
tuples r xs =<br />
concatMap (\(y:ys) -> map (y:) (tuples (r-1) ys))<br />
(init (tails xs))<br />
</haskell><br />
The list of all suffixes could be generated with <hask>iterate tail</hask><br />
but this ends with a "Prelude.tail: empty list".<br />
<hask>tails</hask> generates the suffixes in the same order but aborts properly.<br />
<br />
<br />
''More generally, [[Base cases and identities]]''<br />
<br />
===Don't overuse lambdas===<br />
<br />
Like explicit recursion, using explicit lambdas isn't a universally bad idea, but a better solution often exists.<br />
For example, Haskell is quite good at currying. Don't write<br />
<haskell><br />
zipWith (\x y -> f x y)<br />
<br />
map (\x -> x + 42)<br />
</haskell><br />
<br />
instead, write<br />
<haskell><br />
zipWith f<br />
<br />
map (+42)<br />
</haskell><br />
<br />
also, instead of writing<br />
<haskell><br />
-- sort a list of strings case insensitively<br />
sortBy (\x y -> compare (map toLower x) (map toLower y))<br />
</haskell><br />
<br />
write<br />
<haskell><br />
comparing p x y = compare (p x) (p y)<br />
<br />
sortBy (comparing (map toLower))<br />
</haskell><br />
which is both clearer and re-usable.<br />
Actually, starting with GHC-6.6 you do not need to define <hask>comparing</hask>, since it is already in module <hask>Data.Ord</hask>.<br />
http://www.haskell.org/ghc/dist/current/docs/libraries/base/Data-Ord.html<br />
<br />
(Just a remark for this special example:<br />
We can avoid multiple evaluations of the conversions.<br />
<haskell><br />
sortKey :: (Ord b) => (a -> b) -> [a] -> [a]<br />
sortKey f x = map snd (sortBy (comparing fst) (zip (map f x) x))<br />
</haskell><br />
)<br />
<br />
As a rule of thumb, once your expression becomes too long to easily be point-freed, it probably deserves a name anyway.<br />
Lambdas are occasionally appropriate however, e.g. for control structures in monadic code (in this example, a control-structure "foreach2" which most languages don't even support.):<br />
<haskell><br />
foreach2 xs ys f = zipWithM_ f xs ys<br />
<br />
linify :: [String] -> IO ()<br />
linify lines<br />
= foreach2 [1..] lines $ \lineNr line -> do<br />
unless (null line) $<br />
putStrLn $ shows lineNr $ showString ": " $ show line<br />
</haskell><br />
<br />
<br />
===<hask>Bool</hask> is a regular type===<br />
<br />
Logic expressions are not restricted to guards and <hask>if</hask> statements.<br />
Avoid verbosity like in<br />
<haskell><br />
isEven n<br />
| mod n 2 == 0 = True<br />
| otherwise = False<br />
</haskell><br />
since it is the same as<br />
<haskell><br />
isEven n = mod n 2 == 0<br />
</haskell><br />
.<br />
<br />
<br />
<br />
<br />
==Use syntactic sugar wisely==<br />
<br />
People who employ [[syntactic sugar]] extensively<br />
argue that it makes their code more readable.<br />
The following sections show several examples<br />
where less syntactic sugar is more readable.<br />
<br />
It is argued that a special notation is often<br />
more intuitive than a purely functional expression.<br />
But the term "intuitive notation" is always a matter of habit.<br />
You can also develop an intuition for analytic expressions<br />
that don't match your habits at the first glance.<br />
So why not making a habit of less sugar sometimes?<br />
<br />
<br />
===List comprehension===<br />
<br />
List comprehension lets you remain in imperative thinking, that is it lets you think in variables rather than transformations. Open your mind, discover the flavour of the [[pointfree]] style!<br />
<br />
Instead of<br />
<haskell><br />
[toUpper c | c <- s]<br />
</haskell><br />
write<br />
<haskell><br />
map toUpper s<br />
</haskell><br />
.<br />
<br />
<br />
Consider<br />
<haskell><br />
[toUpper c | s <- strings, c <- s]<br />
</haskell><br />
where it takes some time for the reader<br />
to discover which value depends on what other value<br />
and it is not so clear how many times<br />
the interim values <hask>s</hask> and <hask>c</hask> are used.<br />
In contrast to that<br />
<haskell><br />
map toUpper (concat strings)<br />
</haskell><br />
can't be clearer.<br />
<br />
<br />
<br />
When using higher order functions you can switch more easily from <hask>List</hask> to other data structures.<br />
<br />
Compare<br />
<haskell><br />
map (1+) list<br />
</haskell><br />
and<br />
<haskell><br />
mapSet (1+) set<br />
</haskell><br />
.<br />
If there were a standard instance for the <hask>Functor</hask> class<br />
you could use the code<br />
<haskell><br />
fmap (1+) pool<br />
</haskell><br />
for both choices.<br />
<br />
If you are not used to higher order functions for list processing<br />
you may feel you need parallel list comprehension.<br />
This is unfortunately supported by GHC now,<br />
but it is arguably superfluous since various flavours of <hask>zip</hask> already do a great job.<br />
<br />
<br />
<br />
<br />
===<hask>do</hask> notation===<br />
<br />
[[Do notation considered harmful|do notation]] is useful to express the imperative nature (e.g. a hidden state or an order of execution) of a piece of code.<br />
Nevertheless it's sometimes useful to remember that the <hask>do</hask> notation is explained in terms of functions.<br />
<br />
Instead of<br />
<haskell><br />
do<br />
text <- readFile "foo"<br />
writeFile "bar" text<br />
</haskell><br />
one can write<br />
<haskell><br />
readFile "foo" >>= writeFile "bar"<br />
</haskell><br />
.<br />
<br />
<br />
The code<br />
<haskell><br />
do<br />
text <- readFile "foo"<br />
return text<br />
</haskell><br />
can be simplified to<br />
<haskell><br />
readFile "foo"<br />
</haskell><br />
by a law that each Monad must fulfill.<br />
<br />
<br />
You certainly also agree that<br />
<haskell><br />
do<br />
text <- readFile "foobar"<br />
return (lines text)<br />
</haskell><br />
is more complicated than<br />
<haskell><br />
liftM lines (readFile "foobar")<br />
</haskell><br />
.<br />
By the way, the <hask>Functor</hask> class method <hask>fmap</hask> and the <hask>Monad</hask> based function <hask>liftM</hask> are the same (as long as both are defined, as they should be).<br />
<br />
''Be aware that "more complicated" does not imply "worse". If your do-expression was longer than this, then mixing do-notation and <hask>fmap</hask> might be precisely the wrong thing to do, because it adds one more thing to think about. Be natural. Only change it if you gain something by changing it. -- AndrewBromage''<br />
<br />
===Guards===<br />
<br />
''Disclaimer: This section is NOT advising you to avoid guards. It is advising you to prefer pattern matching to guards when both are appropriate. -- AndrewBromage''<br />
<br />
Guards look like<br />
<haskell><br />
-- Bad implementation:<br />
fac :: Integer -> Integer<br />
fac n | n == 0 = 1<br />
| n /= 0 = n * fac (n-1)<br />
</haskell><br />
which implements a factorial function. This example, like a lot of uses of guards, has a number of problems.<br />
<br />
The first problem is that it's nearly impossible for the compiler to check if guards like this are exhaustive, as the guard conditions may be arbitrarily complex (GHC will warn you if you use the <code>-Wall</code> option). To avoid this problem and potential bugs through non exhaustive patterns you should use an <hask>otherwise</hask> guard, that will match for all remaining cases:<br />
<br />
<haskell><br />
-- Slightly improved implementation:<br />
fac :: Integer -> Integer<br />
fac n | n == 0 = 1<br />
| otherwise = n * fac (n-1)<br />
</haskell><br />
<br />
Another reason to prefer this one is its greater readability for humans and optimizability for compilers. Though it may not matter much in a simple case like this, when seeing an <hask>otherwise</hask> it's immediately clear that it's used whenever the previous guard fails, which isn't true if the "negation of the previous test" is spelled out. The same applies to the compiler: It probably will be able to optimize an <hask>otherwise</hask> (which is a synonym for <hask>True</hask>) away but cannot do that for most expressions.<br />
<br />
This can be done with even less sugar using <hask>if</hask>,<br />
<haskell><br />
-- Less sugar (though the verbosity of if-then-else can also be considered as sugar :-)<br />
fac :: Integer -> Integer<br />
fac n = if n == 0<br />
then 1<br />
else n * fac (n-1)<br />
</haskell><br />
Note that <hask>if</hask> has its own set of problems, for example in connection with the layout rule or that nested <hask>if</hask>s are difficult to read. See ["Case"] how to avoid nested <hask>if</hask>s.<br />
<br />
But in this special case, the same can be done even more easily with pattern matching:<br />
<haskell><br />
-- Good implementation:<br />
fac :: Integer -> Integer<br />
fac 0 = 1<br />
fac n = n * fac (n-1)<br />
</haskell><br />
<br />
Actually, in this case there is an even more easier to read version, which (see above) doesn't use Explicit Recursion:<br />
<haskell><br />
-- Excellent implementation:<br />
fac :: Integer -> Integer<br />
fac n = product [1..n]<br />
</haskell><br />
This may also be more efficient as <hask>product</hask> might be optimized by the library-writer... In GHC, when compiling with optimizations turned on, this version runs in O(1) stack-space, whereas the previous versions run in O(n) stack-space.<br />
<br />
Note however, that there is a difference between this version and the previous ones: When given a negative number, the previous versions do not terminate (until StackOverflow-time), while the last implemenation returns 1.<br />
<br />
<br />
Guards don't always make code clearer.<br />
Compare<br />
<haskell><br />
foo xs | not (null xs) = bar (head xs)<br />
</haskell><br />
and<br />
<haskell><br />
foo (x:_) = bar x<br />
</haskell><br />
<br />
or compare the following example using the advanced [[pattern guard]]s<br />
(http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#PATTERN-GUARDS)<br />
<haskell><br />
parseCmd ln<br />
| Left err <- parse cmd "Commands" ln<br />
= BadCmd $ unwords $ lines $ show err<br />
| Right x <- parse cmd "Commands" ln<br />
= x<br />
</haskell><br />
with this one with [[no pattern guard]]s:<br />
<haskell><br />
parseCmd ln = case parse cmd "Commands" ln of<br />
Left err -> BadCmd $ unwords $ lines $ show err<br />
Right x -> x<br />
</haskell><br />
or, if you expect your readers to be familiar with the <hask>either</hask> function:<br />
<haskell><br />
parseCmd :: -- add an explicit type signature, as this is now a pattern binding<br />
parseCmd = either (BadCmd . unwords . lines . show) id . parse cmd "Commands"<br />
</haskell><br />
<br />
<br />
Incidentally, compilers often also have problems with numerical patterns. For example, the pattern <hask>0</hask> in fact means <hask>fromInteger 0</hask>; thus it involves a computation, which is uncommon for function parameter patterns. To illustrate this, consider the following example:<br />
<haskell><br />
data Foo = Foo deriving (Eq, Show)<br />
<br />
instance Num Foo where<br />
fromInteger = error "forget it"<br />
<br />
f :: Foo -> Bool<br />
f 42 = True<br />
f _ = False<br />
</haskell><br />
<br />
<haskell><br />
*Main> f 42<br />
*** Exception: forget it<br />
</haskell><br />
<br />
Only use guards when you need to. In general, you should stick to pattern matching whenever possible.<br />
<br />
===<hask>n+k</hask> patterns===<br />
In order to allow pattern matching against numerical types, Haskell 98 provides so-called n+k patterns, as in<br />
<haskell><br />
take :: Int -> [a] -> [a]<br />
take (n+1) (x:xs) = x: take n xs<br />
take _ _ = []<br />
</haskell><br />
However, they are often criticised for hiding computational complexity and producing ambiguities, see [[/Discussion]] for details. They are subsumed by the more general [[Views]] proposal, which has unfortunately never been implemented despite being around for quite some time now.<br />
<br />
<br />
==Efficiency and infinity==<br />
<br />
A rule of thumb is:<br />
If a function makes sense for an infinite data structure but the implementation at hand fails for an infinite amount of data, then the implementation is probably also inefficient for finite data.<br />
<br />
===Don't ask for the length of a list when you don't need it===<br />
<br />
Don't write<br />
<haskell><br />
length x == 0<br />
</haskell><br />
to find out if the list <hask>x</hask> is empty.<br />
If you write it, you force Haskell to create all list nodes. It fails on an infinite list although the expression should be evaluated to <hask>False</hask> in this case. (Nevertheless the content of the list elements may not be evaluated.)<br />
<br />
In contrast<br />
<haskell><br />
x == []<br />
</haskell><br />
is faster but it requires the list <hask>x</hask> to be of type <hask>[a]</hask> where <hask>a</hask> is a type of class <hask>Eq</hask>.<br />
<br />
The best thing to do is<br />
<haskell><br />
null x<br />
</haskell><br />
<br />
Additionally, many uses of the length function are overspecifying the problem: one may only need to check that a list is ''at least'' a certain length, and not a specific length. Thus use of <haskell>length</haskell> could be replaced with an <hask>atLeast</hask> function that only checks to see that a list is greater than the required minimum length.<br />
<haskell><br />
atLeast :: Int -> [a] -> Bool<br />
atLeast 0 _ = True<br />
atLeast _ [] = False<br />
atLeast n (_:ys) = atLeast (n-1) ys<br />
</haskell><br />
or non-recursive, but less efficient because both <hask>length</hask> and <hask>take</hask> must count<br />
<haskell><br />
atLeast :: Int -> [a] -> Bool<br />
atLeast n x = n == length (take n x)<br />
</haskell><br />
or non-recursive but fairly efficient<br />
<haskell><br />
atLeast :: Int -> [a] -> Bool<br />
atLeast n =<br />
if n>0<br />
then not . null . drop (n-1)<br />
else const True<br />
</haskell><br />
or<br />
<haskell><br />
atLeast :: Int -> [a] -> Bool<br />
atLeast 0 = const True<br />
atLeast n = not . null . drop (n-1)<br />
</haskell><br />
<br />
The same problem arises if you want to shorten a list to the length of another one by<br />
<haskell><br />
take (length x) y<br />
</haskell><br />
since this is inefficient for large lists <hask>x</hask> and fails for infinite ones. But this can be useful to extract a finite prefix from an infinite list.<br />
So, instead<br />
<haskell><br />
zipWith const y x<br />
</haskell><br />
works well.<br />
<br />
It should be noted that <hask>length</hask>, <hask>take</hask><br />
can be replaced by <hask>genericLength</hask>, <hask>genericTake</hask> et.al.,<br />
which allow the usage of [[Peano numbers]].<br />
<br />
===Don't ask for the minimum when you don't need it===<br />
<br />
The function <hask>isLowerLimit</hask> checks if a number is a lower limit to a sequence.<br />
<haskell><br />
isLowerLimit :: Ord a => a -> [a] -> Bool<br />
isLowerLimit x ys = x <= minimum ys<br />
</haskell><br />
It certainly fails if <hask>ys</hask> is infinite. Is this a problem? <br />
<br />
Compare it with<br />
<haskell><br />
isLowerLimit x = all (x<=)<br />
</haskell><br />
This definition terminates for infinite lists, if <hask>x</hask> is not a lower limit. It aborts immediately if an element is found which is below <hask>x</hask>. Thus it is also faster for finite lists. Even more: It also works for empty lists.<br />
<br />
<br />
===Use sharing===<br />
<br />
If you want a list of lists with increasing length and constant content, don't write<br />
<haskell><br />
map (flip replicate x) [0..]<br />
</haskell><br />
because this needs quadratic space and run-time. If you code<br />
<haskell><br />
iterate (x:) []<br />
</haskell><br />
then the lists will share their suffixes and thus need only linear space and run-time for creation.<br />
<br />
<br />
===Choose the right fold===<br />
<br />
See [[Stack overflow]] for advice on which fold is appropriate for your situation.<br />
<br />
<br />
==Choose types properly==<br />
<br />
===Lists are not good for everything===<br />
<br />
====Lists are not arrays====<br />
<br />
Lists are not arrays, so don't treat them as such.<br />
Frequent use of <hask>(!!)</hask> should alarm you.<br />
Accessing the <hask>n</hask>th list element<br />
involves traversing through the first <hask>n</hask> nodes of the list.<br />
This is very inefficient.<br />
<br />
If you access the elements progressively, as in<br />
<haskell><br />
[x !! i - i | i <- [0..n]]<br />
</haskell><br />
you should try to get rid of indexing, as in<br />
<haskell><br />
zipWith (-) x [0..n]<br />
</haskell><br />
.<br />
<br />
If you really need random access, as in the Fourier Transform,<br />
you should switch to [http://haskell.org/haskellwiki/Arrays Arrays].<br />
<br />
<br />
====Lists are not sets====<br />
<br />
If you manage data sets where each object can occur only once<br />
and the order is irrelevant,<br />
if you use list functions like<br />
<hask>sort</hask>, <hask>nub</hask>, <hask>union</hask>, <hask>elem</hask>, <hask>delete</hask>, <hask>(\\)</hask><br />
frequently,<br />
you should think about switching to sets.<br />
If you need multi-sets,<br />
i.e. data sets with irrelevant order but multiple occurrences of objects,<br />
you can use a <hask>Data.Map.Map a Int</hask>.<br />
<br />
<br />
====Lists are not finite maps====<br />
<br />
Similarly, lists are not finite maps, as mentioned in [[efficiency hints]].<br />
<br />
<br />
===Reduce type class constraints===<br />
<br />
====Eq type class====<br />
<br />
When using functions like <hask>delete</hask>, <hask>(\\)</hask>, <hask>nub</hask>, and so on you should be aware that they need types of the <hask>Eq</hask> class. There are two problems: The routines might not work as expected if a processed list contains multiple equal elements and the element type of the list may not be comparable, like functions.<br />
<br />
Example:<br />
The following function takes the input list <hask>xs</hask> and removes each element of <hask>xs</hask> once from <hask>xs</hask>.<br />
Clear what it does? No? The code is probably more understandable<br />
<haskell><br />
removeEach :: (Eq a) => [a] -> [[a]]<br />
removeEach xs = map (flip List.delete xs) xs<br />
</haskell><br />
but it should be replaced by<br />
<haskell><br />
removeEach :: [a] -> [[a]]<br />
removeEach xs =<br />
zipWith (++) (List.inits xs) (tail (List.tails xs))<br />
</haskell><br />
since this works perfectly for function types <hask>a</hask> and for equal elements in <hask>xs</hask>.<br />
<br />
<br />
===Don't use <hask>Int</hask> when you don't consider integers===<br />
<br />
Before using integers for each and everything (C style)<br />
think of more specialised types.<br />
If only the values <hask>0</hask> and <hask>1</hask> are of interest,<br />
try the type <hask>Bool</hask> instead.<br />
If there are more but predefined choices and numeric operations aren't needed try an enumeration.<br />
<br />
Instead of<br />
<haskell><br />
type Weekday = Int<br />
</haskell><br />
write<br />
<haskell><br />
data Weekday = Monday<br />
| Tuesday<br />
| Wednesday<br />
| Thursday<br />
| Friday<br />
| Saturday<br />
| Sunday<br />
deriving (Eq, Ord, Enum)<br />
</haskell><br />
<br />
It allows all sensible operations like <hask>==</hask>, <hask> < </hask>, <hask>succ</hask> and<br />
forbids all nonsensical ones like <hask>+</hask>, <hask>*</hask>.<br />
You cannot accidentally mix up weekdays with numbers and<br />
the signature of a function with weekday parameter clearly states what kind of data is expected.<br />
<br />
If an enumeration is not appropriate<br />
you can define a <hask>newtype</hask> carrying the type that is closest to what you need.<br />
E.g. if you want to associate objects with a unique identifier,<br />
you may want to choose the type <hask>Int</hask>.<br />
But you don't need arithmetic and you can make this type distinct from real <hask>Int</hask>s by defining<br />
<haskell><br />
newtype Identifier = Identifier Int deriving Eq<br />
</haskell><br />
<br />
<br />
<br />
==Miscellaneous==<br />
<br />
===Separate IO and data processing===<br />
<br />
It's not good to use the IO Monad everywhere,<br />
much of the data processing can be done without IO interaction.<br />
You should separate data processing and IO<br />
because pure data processing can be done purely functionally,<br />
that is you don't have to specify an order of execution<br />
and you don't have to worry about what computations are actually necessary.<br />
You can easily benefit from lazy evaluation<br />
if you process data purely functionally<br />
and output it by a short IO interaction.<br />
<br />
<haskell><br />
-- import Control.Monad (replicateM_)<br />
replicateM_ 10 (putStr "foo")<br />
</haskell><br />
is certainly worse than<br />
<haskell><br />
putStr (concat $ replicate 10 "foo")<br />
</haskell><br />
<br />
Similarly,<br />
<haskell><br />
do<br />
h <- openFile "foo" WriteMode<br />
replicateM_ 10 (hPutStr h "bar")<br />
hClose h<br />
</haskell><br />
can be shortened to<br />
<haskell><br />
writeFile "foo" (concat $ replicate 10 "bar")<br />
</haskell><br />
which also ensures proper closing of the handle <hask>h</hask><br />
in case of failure.<br />
<br />
A function which computes a random value<br />
with respect to a custom distribution<br />
(<hask>distInv</hask> is the inverse of the distribution function)<br />
can be defined via IO<br />
<haskell><br />
randomDist :: (Random a, Num a) => (a -> a) -> IO a<br />
randomDist distInv = liftM distInv (randomRIO (0,1))<br />
</haskell><br />
but [[Humor/Erlkönig|there is no need to do so]].<br />
You don't need the state of the whole world<br />
just for remembering the state of a random number generator.<br />
What about<br />
<haskell><br />
randomDist :: (RandomGen g, Random a, Num a) => (a -> a) -> State g a<br />
randomDist distInv = liftM distInv (State (randomR (0,1)))<br />
</haskell><br />
?<br />
<br />
===Forget about quot and rem===<br />
<br />
They complicate handling of negative dividends.<br />
<hask>div</hask> and <hask>mod</hask> are almost always the better choice.<br />
If <hask>b > 0</hask> then it always holds<br />
<haskell><br />
a == b * div a b + mod a b<br />
mod a b < b<br />
mod a b >= 0<br />
</haskell><br />
The first equation is true also for <hask>quot</hask> and <hask>rem</hask>,<br />
but the two others are true only for <hask>mod</hask>, but not for <hask>rem</hask>.<br />
That is, <hask>mod a b</hask> always wraps <hask>a</hask> to an element from <hask>[0..(b-1)]</hask>,<br />
whereas the sign of <hask>rem a b</hask> depends on the sign of <hask>a</hask>.<br />
<br />
This seems to be more an issue of experience rather than one of a superior reason.<br />
You might argue, that the sign of the dividend is more important for you, than that of the divisor.<br />
However, I have never seen such an application,<br />
but many uses of <hask>quot</hask> and <hask>rem</hask> where <hask>div</hask> and <hask>mod</hask> were clearly superior.<br />
<br />
Examples:<br />
<br />
* Conversion from a continuously counted tone pitch to the pitch class, like C, D, E etc.: <hask>mod p 12</hask><br />
<br />
* Pad a list <hask>xs</hask> to a multiple of <hask>m</hask> number of elements: <hask>xs ++ replicate (mod (- length xs) m) pad</hask><br />
<br />
* Conversion from a day counter to a week day: <hask>mod n 7</hask><br />
<br />
* Pacman runs out of the screen and re-appears at the opposite border: <hask>mod x screenWidth</hask><br />
<br />
See<br />
* Daan Leijen: [http://www.cs.uu.nl/~daan/download/papers/divmodnote-letter.pdf Division and Modulus for Computer Scientists]<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2007-August/030394.html default for quotRem in terms of divMod?]<br />
<br />
<br />
===Partial functions like <hask>fromJust</hask> and <hask>head</hask>===<br />
<br />
Avoid functions that fail for certain input values like <hask>fromJust</hask> and <hask>head</hask>.<br />
They raise errors that can only be detected at runtime.<br />
Think about how they can be avoided by different program organization<br />
or by choosing more specific types.<br />
<br />
Instead of<br />
<haskell><br />
if i == Nothing then deflt else fromJust i<br />
</haskell><br />
write<br />
<haskell><br />
fromMaybe deflt i<br />
</haskell><br />
Please note, that <hask>(==)</hask> also requires an <hask>Eq</hask> class instance for the type of <hask>i</hask>,<br />
which <hask>fromMaybe</hask> does not require because it employs [[pattern matching]].<br />
See also [[#Reduce type class constraints]].<br />
<br />
If it is not possible to avoid <hask>fromJust</hask> this way,<br />
then use <hask>fromMaybe</hask> anyway<br />
and document with an <hask>error</hask> why you think that the value must be always <hask>Just</hask> in your situation.<br />
<haskell><br />
fromMaybe (error "Function bla: The list does always contains the searched value")<br />
(lookup key dict)<br />
</haskell><br />
<br />
The function <hask>head</hask> can be avoided by [[Non-empty list|checking with types]], that it is never empty.<br />
There is also a function which returns an existing first list element in terms of <hask>Maybe</hask>:<br />
<hask>maybeToList</hask><br />
(See [http://www.haskell.org/pipermail/haskell-cafe/2007-March/023391.html remark].)<br />
<br />
== Related Links ==<br />
<br />
=== Common Mistakes and Incorrect Beliefs By Haskell Beginners ===<br />
<br />
* [[Common Misunderstandings]]<br />
<br />
=== Some Common (and not so common!) Hugs Errors ===<br />
<br />
* [http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/errors/allErrors.html Some common Hugs error messages]<br />
<br />
<br />
[[Category:Style]]</div>HowardBGoldenhttps://wiki.haskell.org/index.php?title=Things_to_avoid&diff=22574Things to avoid2008-08-23T01:03:12Z<p>HowardBGolden: Things to avoid moved to Haskell programming tips: This isn't just things to avoid. It's dos and don'ts.</p>
<hr />
<div>#redirect [[Haskell programming tips]]</div>HowardBGolden