https://wiki.haskell.org/api.php?action=feedcontributions&user=Lambda+Fairy&feedformat=atomHaskellWiki - User contributions [en]2024-03-19T04:49:06ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Xmonad/Screenshots&diff=59017Xmonad/Screenshots2014-10-20T02:28:24Z<p>Lambda Fairy: /* Layouts */ Change broken link to use web.archive.org</p>
<hr />
<div>{{xmonad}}<br />
<br />
'''xmonad screenshot gallery'''; images contributed by users.<br />
<br />
See the [[Xmonad/Config archive]] for the configuration files that produced some of these screenshots.<br />
<br />
===Misc screenshots===<br />
<br />
====Desktop Environments====<br />
<gallery><br />
Image:Screen-atomb-apple.png|Apple OSX<br />
Image:Screen-nomeata-ewhm.png|Gnome support<br />
Image:Screen-sjanssen-kde-kicker.png|KDE support<br />
Image:xmonad-xfce-panel.png|XFCE Panel<br />
<br />
Image:Loupgaroublond-config.png|More Gnome<br />
Image:2011.03-srvn_2560x960.png|Gnome monitors + dzen xmonad info<br />
</gallery><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Desktop.html Config.Desktop],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Gnome.html Config.Gnome],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Kde.html Config.Kde],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Xfce.html Config.Xfce]<br />
<br />
====Potpourri====<br />
<gallery><br />
Image:Xmonad-on-the-macbook.jpg|Xmonad on the macbook<br />
Image:Photo-cjb-olpc.jpg|The OLPC laptop<br />
Image:xmonad_on_tv.jpg|xmonad on TV (used as web and video station)<br />
Image:Screen-triplehead-galois.jpg|Xinerama<br />
Image:Quad-monitor.jpg|Quad monitor setup with Xinerama/Nvidia<br />
<br />
Image:Xmonad-screen-modprobe.jpg|Tall, xinerama, and dzen<br />
Image:Xmonad-screen-ta.png|Dual head, Layout.WindowNavigation<br />
Image:Screen-dons-floating.png|Floating layer<br />
Image:vvv-config.png|DynamicWorkspaces<br />
Image:NamingScheme.jpg|Mnemonics make workspace navigation a cinch!<br />
</gallery><br />
<br />
====Transparency====<br />
<gallery><br />
Image:Xmonad-screen-comp-xfce.jpg|xfce + xmonad + composite + eye-burning bg<br />
Image:Screen-ajhager-minimal-gnome-xcompmgr.png|Gnome + xcompmgr<br />
Image:Screen-xmonad-grid-thayer.png|Grid mode + transparency<br />
Image:Xmonad-mag-grid.jpg|Magnifier + compositing<br />
Image:Screenshot_-_07202011_-_01-35-48_AM.png|xfce panel + xmonad + gnome-terminal (terminal and vim)<br />
Image:Shot.jpg|Xmonad 0.11-2 + Urxvt(rxvt-unicode) + Xcompmgr for true transparency + Quad Monitor setup (2x 1920x1080 and 2x 1600x900)<br />
</gallery><br />
<br />
====Status bars and monitors====<br />
<gallery><br />
Image:Screen-rob-dzen-cpubar.png|Nice dzen<br />
Image:Screen-rob-dzen.png|More dzen examples<br />
Image:byorgey-config.png|Byorgey's dzen<br />
Image:Screen-dons-color-dzen.png|dzen example<br />
<br />
Image:Screen-emertens-gray.png|dzen with bitmaps<br />
Image:Screen-mauke-dzen.png|More dzen<br />
Image:Screen-lobzang-monitoring.jpg|dzen monitoring<br />
Image:rob-config.png|Shellprompt + dzen<br />
<br />
Image:Arossato-config.png|tabbed+xmobar<br />
Image:xmonad_shellprompt_newconf.png|Dual head, dzen and ShellPrompt<br />
Image:Xmonad-screen-emacs-dzen.png|nice emacs + dzen mode<br />
Image:xmonad-clock.png|XMonad with clock (using Monitor extension)<br />
</gallery><br />
(See also the [http://haskell.org/haskellwiki/Xmonad/Config_archive xmonad config archive] for more status bar examples and associated files.)<br />
<br />
===Layouts===<br />
'''Off-wiki xmonad layout galleries'''<br />
*[http://web.archive.org/web/20090425073140/http://www.webframp.com/2009/01/06/xmonad-layout-gallery/ webframp's xmonad layout gallery] (archived; original page [http://www.webframp.com/2009/01/06/xmonad-layout-gallery here])<br />
<br />
====Tiled layouts====<br />
xmonad-contrib-0.8*:<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad/XMonad-Layout.html (Defaults) Full Tall and Mirror Tall],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Accordion.html Accordion],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Dishes.html Dishes],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Grid.html Grid],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-MosaicAlt.html MosaicAlt],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ResizableTile.html ResizableTile],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Spiral.html Spiral],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-StackTile.html StackTile],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ThreeColumns.html ThreeColumns]<br />
</blockquote><br />
[[Xmonad/Notable_changes_since_0.8|> xmonad-contrib-0.8.1]] (darcs):<br />
<blockquote><br />
CenteredMaster, FixedColumn, GridVariants, Mosaic<br />
</blockquote><br />
<br />
<gallery><br />
Image:Xmonad-screen-dons-code.png|Default wide<br />
Image:dons-config.png|Default wide<br />
Image:Xmonad_screen3.png|Tall vim+multitail+htop<br />
Image:Screen-dons-4x4.png|Tall Inc master<br />
<br />
Image:Screen-rickard-resize.png|ResizableTile<br />
Image:ResizableEight.jpg|ResizableTile four masters<br />
Image:Screen-ejt-spiral-dzen.png|Spiral<br />
Image:SpiralGoldenRatio.jpg|Spiral Golden Ratio<br />
<br />
Image:Screen-dishes-nornagon.png|Dishes (static)<br />
Image:StackTile1.jpg|StackTile (resizable)<br />
Image:StackTile3.jpg|StackTile three masters<br />
Image:StackTile3_8_9ths.jpg|StackTile three at 8/9<br />
<br />
Image:Accordion.jpg|Accordion<br />
Image:Screen-xj2106-three-column.png|ThreeColumn<br />
Image:Screen-dons-grid.jpg|Grid.Grid (also see HintedGrid)<br />
Image:GridGrid.jpg|another Grid.Grid<br />
</gallery><br />
'''Off-wiki tiled layout shots'''<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/MosaicAlt-1920x1200.png webframp's MosaicAlt]<br />
<br />
====Hinted tile layouts====<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutHints.html layoutHints (modifier)],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-HintedGrid.html HintedGrid],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-HintedTile.html HintedTall and HintedWide]<br />
</blockquote><br />
<gallery><br />
Image:glguy-config.jpg|layoutHints + dualhead<br />
Image:LayoutHintsTall.jpg|layoutHints Tall<br />
Image:LayoutHintsThreeColumns.jpg|layoutHints ThreeColumn<br />
Image:MagnifierHintedGridFalse.jpg|HintedGrid False + [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Magnifier.html Magnifier]<br />
<br />
Image:HintedGridFalse.jpg|HintedGrid False<br />
Image:HintedGridTrue.jpg|HintedGrid True<br />
Image:HintedTileCenterTall.jpg|HintedTile Tall Center<br />
Image:HintedTileCenterWide.jpg|HintedTile Wide Center<br />
<br />
Image:HintedTileTopLeftTall.jpg|HintedTile Tall TopLeft<br />
Image:HintedTileBottomRightTall.jpg|HintedTile Tall BottomRight<br />
Image:HintedTileTopLeftWide.jpg|HintedTile Wide TopLeft<br />
Image:HintedTileBottomRightWide.jpg|HintedTile Wide BottomRight<br />
</gallery><br />
(*Silly bright purple background and font sizes set to emphasize differences in layouts.)<br />
<br />
====Layouts that hide some of the workspace's windows====<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-DragPane.html DragPane],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-TwoPane.html TwoPane],<br />
any layout with [http://code.haskell.org/XMonadContrib/XMonad/Layout/LimitWindows.hs LimitWindows layout modifier (darcs)]<br />
</blockquote><br />
<gallery><br />
Image:TwoPane5_9ths.jpg|TwoPane<br />
Image:MirrorTwoPane2_3rds.jpg|Mirror TwoPane<br />
Image:MasteredMirrorTwoPane.jpg|Master.mastered Mirror TwoPane<br />
</gallery><br />
<br />
====Layouts that leave the background visible====<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Circle.html Circle],<br />
[[Xmonad/Notable_changes_since_0.8|Cross (darcs)]],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Roledex.html Rolodex],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SimpleFloat.html SimpleFloat],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-WindowArranger.html WindowArranger (can be resized to show background)]<br />
</blockquote><br />
<gallery><br />
Image:Screen-peter-circle.png|Circle<br />
Image:Xmonad-circle-comp.jpg|Circle layout + compositing<br />
Image:MagnifierCircle.jpg|Circle + Magnifier<br />
Image:Rolodex.png|Rolodex<br />
<br />
Image:Xmonad-screen-ashren-full.jpg|floating + dzen<br />
</gallery><br />
'''Off-wiki visible background layout screenshots'''<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/simpleFLoat-1920x1200.png webframp's simple float]<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/Roledex-1920x1200.png webframp's rolodex]<br />
<br />
====Combo layouts====<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Combo.html Combo],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutCombinators.html LayoutCombinators],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Square.html Square],<br />
[[Xmonad/Notable_changes_since_0.8|ComboP, SubLayouts, LayoutBuilder (darcs)]]<br />
</blockquote><br />
(See also Master and LayoutScreens [[#Layout Modifiers and Utilities|modifiers]])<br />
<gallery><br />
Image:Screen-droundy-combo.png|Combined layouts<br />
Image:Screen-ohmega-tab-gnome-twopane.jpg|twopane+tabbing<br />
Image:AmphiGimpDragCombo.png|amphi's LayoutCombinators (tabbedLayout ****||* Full) Gimp<br />
</gallery><br />
<br />
====IM layouts====<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IM.html IM (modifier)], [http://haskell.org/haskellwiki/Xmonad/Notable_changes_since_0.8 ComboP (darcs)]<br />
</blockquote><br />
(See also [[#Tiled layouts]] and [[#Layout Modifiers and Utilities]])<br />
<gallery><br />
Image:Xmonad-layout-im.png|IM layout<br />
Image:kvirc-tall.jpeg|kvirc under Tall layout<br />
Image:Captura_da_tela.png|Marcot's withIM<br />
Image:Im_gimp.jpg|Gimp and withIM resizableTall (see [[Xmonad/General_xmonad.hs_config_tips|Config Tips]])<br />
Image:Xmonadgimp.jpg|Double withIM'd Gimp, dzens, and stalonetray<br />
Image:comboP.png|comboP layout (generalization of IM)<br />
</gallery><br />
<br />
====Decorated Layouts====<br />
Hey decoration users! Surely you exist! Please add your beautiful screenshots here, or have someone else do it for you from #xmonad.<br />
<blockquote><br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Decoration.html Decoration],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-DecorationMadness.html Decoration examples],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-DwmStyle.html DwmStyle],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ResizeScreen.html ResizeScreen (Utility helper for decorations)],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SimpleDecoration.html SimpleDecoration],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Simplest.html Simplest],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SimplestFloat.html Simplest],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-TabBarDecoration.html TabBarDecoration],<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Tabbed.html Tabbed]<br />
</blockquote><br />
(See also [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Prompt-Theme.html Prompt.Theme] and [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-Themes.html Util.Themes])<br />
<gallery><br />
Image:Screen-gattocarlo-tabbed.png|Ion-like tabbing<br />
Image:Xmonad-dwm-style.png|dwm-like decorations<br />
</gallery><br />
'''Off-wiki decorated layout screenshots'''<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/DwmStyle-Tall-1920x1200.png webframp's dwm-style]<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/TabBarMirrorTall-1920x1200.png webframp's tabbed]<br />
*[http://www.webframp.com/wp-content/gallery/xmonad-layouts/simpleDecorationTall-1920x1200.png webframp's simpleDeco narrow tabs]<br />
<br />
====Old Layouts====<br />
<gallery><br />
Image:Screen-droundy-mosaic2.png|Old Mosaic (0.6)<br />
Image:droundy-config.png|Combo mode<br />
</gallery><br />
<br />
====Layout Modifiers and Utilities====<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-BoringWindows.html BoringWindows] Mark windows boring to remove from focus/swap bindings<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Gaps.html Gaps] Manually set gaps not handled by ManageDocks avoidStruts<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutModifier.html Modifier (development utility)]<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutScreens.html LayoutScreens] Configure screen splits independent of xinerama with bindings<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-MagicFocus.html MagicFocus] swap focused into master pane<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Magnifier.html Magnifier] configurable zoom<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Master.html Master] add pane to any layout<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Maximize.html Maximize] Maximize is not full screen (use Magnifier or Full instead)<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-MultiToggle.html MultiToggle] toggle other modifiers<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-MultiToggle-Instances.html commonly toggled modifiers for MultiToggle]<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Named.html Named] Change layout name for show or logHook<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-NoBorders.html NoBorders] smart hiding of borders<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-PerWorkspace.html PerWorkspace] different layouts per workspace<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Reflect.html Reflect] across X or Y axis<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ShowWName.html ShowWName] flash workspace tag/name/Id when entering it<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ToggleLayouts.html ToggleLayouts] single version of MultiToggle<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-WindowNavigation.html WindowNavigation] navigate directionally<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-WindowNavigation.html Actions.WindowNavigation] navigate directionally even across screens no coloured borders<br />
*[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-WorkspaceDir.html WorkspaceDir] set working directory per workspace<br />
<br />
[[Category:XMonad]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=FAQ&diff=58537FAQ2014-07-06T08:01:18Z<p>Lambda Fairy: Change "C cast" to the more precise "reinterpret cast"</p>
<hr />
<div>This FAQ is based on actual frequently-asked questions from [[IRC channel|<tt>#haskell</tt> IRC]]. The goal is simply to collect and edit some common answers. Beginner questions are still welcome on IRC, as always.<br />
<br />
This is a wiki, so please edit the text with any improvements you have. And feel free to add new questions, if they are frequently asked.<br />
<br />
== See also ==<br />
<br />
* [[:Category:FAQ|Other FAQs]]<br />
* The [[Introduction|introduction to Haskell]], and the FAQ at the end of that document.<br />
<br />
__TOC__<br />
<br />
= The real world =<br />
<br />
== Should I learn Haskell? ==<br />
<br />
That depends on your goals. In general, Haskellers will tell you that you should learn Haskell. :)<br />
<br />
Learning Haskell is fun. It will expand your mind and make you a better programmer in other languages. These are the immediate benefits.<br />
<br />
Haskell is also a great tool for solving real-world problems, but it can take many months of study to get to that point.<br />
<br />
== Is Haskell hard to learn? ==<br />
<br />
Any competent programmer can learn Haskell, but it will take more time and motivation than you may expect.<br />
<br />
Haskell requires learning a new way to think, not just new syntax for old concepts. This can be incredibly frustrating, as simple tasks seem impossibly difficult.<br />
<br />
Those with no prior programming experience may actually have an easier time learning Haskell, because they have less to un-learn.<br />
<br />
== How can I get started with Haskell ''right now''? ==<br />
<br />
Check out [http://tryhaskell.org/ Try Haskell].<br />
<br />
== What should I read for learning Haskell? ==<br />
<br />
The most popular resources are [http://learnyouahaskell.com/ ''Learn You a Haskell''] and [http://book.realworldhaskell.org/ ''Real World Haskell'']. Each is available online for free, or can be purchased in hardcopy.<br />
<br />
Many other [[tutorials]], [[books]], and [[Learning Haskell|other resources]] are available.<br />
<br />
== How can I get help with learning Haskell? ==<br />
<br />
Your options include:<br />
<br />
* [[IRC channel|<tt>#haskell</tt> on Freenode IRC]]<br />
* [http://stackoverflow.com/questions/tagged/haskell Stack Overflow]<br />
* The [http://www.haskell.org/mailman/listinfo/haskell-cafe Haskell-Cafe] mailing list<br />
<br />
== Will Haskell get me a job? ==<br />
<br />
There are plenty of [[Haskell in industry|companies using Haskell]], but it's still a tiny number compared to the software industry as a whole.<br />
<br />
There are also many companies which do not use Haskell, but prefer to hire people who know Haskell. It indicates that you learned something hard and obscure just for fun, which employers take as a sign of intelligence.<br />
<br />
== Is Haskell similar to Language X? ==<br />
<br />
Probably not. It's best if you approach Haskell with a clean slate. Most analogies to another language will break down somewhere, often in a subtle and misleading way. If you first learn the Haskell concepts for what they are, you can then draw useful connections to other languages.<br />
<br />
== What's the relationship between Haskell and GHC? ==<br />
<br />
Haskell is not a piece of software; it is a specification for a standardized programming language. The [[Language and library specification|latest version of the spec]] is the Haskell 2010 Report.<br />
<br />
[http://www.haskell.org/ghc/ GHC] is the Glorious Glasgow Haskell Compiler. It is by far the most popular and &quot;production-ready&quot; implementation of the standard Haskell language. It also implements many [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghc-language-features.html extension] features that go above and beyond standard Haskell. Many programs use these features and so aren't &quot;written in Haskell&quot; in the strictest sense.<br />
<br />
You can use the term &quot;Haskell&quot; to refer to the standard language, and &quot;GHC Haskell&quot; when including GHC extensions.<br />
<br />
Besides GHC, several other [[implementations]] of Haskell are available. Each one provides its own extensions, some of which don't exist in GHC.<br />
<br />
== What is the Haskell Platform? ==<br />
<br />
The [http://hackage.haskell.org/platform/ Haskell Platform] is a copy of GHC bundled with a &quot;blessed&quot; set of useful libraries. It is the easiest way to get started with Haskell. It's not essential to start with the Platform, because you can install the same libraries as needed.<br />
<br />
== What is Haskell Prime (Haskell')? ==<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/ Haskell Prime] is a process which produces new versions of the Haskell language spec. It does not refer to a particular present or future version of Haskell.<br />
<br />
== My textbook uses Haskell 98. Is it very different from Haskell 2010? ==<br />
<br />
No. Haskell 2010 is a [http://www.haskell.org/pipermail/haskell/2009-November/021750.html very conservative change] to Haskell 98. It fixes small syntactic flaws, and standardizes several well-behaved extensions which GHC has supported for years.<br />
<br />
The standardization process is very slow because standardizing a flawed language can be a costly mistake. Extensions are accepted only once they are considered mature and well-understood.<br />
<br />
== How do I get libraries for Haskell? ==<br />
<br />
You can find libraries on [http://hackage.haskell.org/packages/archive/pkg-list.html Hackage], and install them with [[Cabal-Install|<tt>cabal-install</tt>]].<br />
<br />
== Is Haskell compiled? ==<br />
<br />
Usually. GHC, the most popular Haskell implementation, has an optimizing ahead-of-time native-code compiler, as well as a bytecode compiler and interpreter for interactive use.<br />
<br />
Haskell itself is not a &quot;compiled language&quot; because nothing in the Haskell spec requires implementations to be compilers.<br />
<br />
== Does Haskell have an interpreter? ==<br />
<br />
Yes, but maybe you instead mean &quot;Is there a program where I can type Haskell code and see it run immediately?&quot;. GHCi provides such a &quot;read-evaluate-print loop&quot;.<br />
<br />
= Paradigms =<br />
<br />
== Is learning Haskell the best way to learn functional programming? ==<br />
<br />
Not necessarily! Haskell is not a ''typical'' functional language. It can be overwhelming to learn the basic concepts of functional programming alongside static types, algebraic data, laziness, type classes, first-class IO, etc. For an introduction to FP by itself you might want to learn Scheme, or play with the FP features in your current favorite language.<br />
<br />
That said, many people choose Haskell as an introduction to FP and have success with that approach. Haskell has an extremely active community of people teaching, doing research, writing libraries, etc. Haskell is where interesting things happen in the FP space, so it's an exciting place to jump in.<br />
<br />
== I heard Haskell is pure functional. Does that mean I can't do imperative / OOP / aspect-oriented / logic programming in Haskell? ==<br />
<br />
No, &quot;pure functional&quot; has a specific technical meaning. It doesn't mean that functional is the only supported paradigm.<br />
<br />
Paradigms describe the techniques used in a particular program. For example, the Linux kernel is written in C, with pervasive use of functional, object-oriented, and aspect-oriented programming. The most we can say about a ''language'' is that it encourages or discourages a particular paradigm. Haskell is very flexible and can comfortably accommodate most paradigms, even when there is no built-in support.<br />
<br />
== I heard Haskell is pure functional. Does that mean it can't do IO? ==<br />
<br />
No; [[Introduction to IO|IO in Haskell]] is straightforward.<br />
<br />
== I heard Haskell is pure functional. Does that mean it doesn't have mutable state? ==<br />
<br />
No; see [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-IORef.html <tt>IORef</tt>] for a simple example. A more sophisticated example is [http://book.realworldhaskell.org/read/software-transactional-memory.html software transactional memory], which provides concurrent state more sophisticated than you'll find in most other imperative languages.<br />
<br />
== Wait, is Haskell imperative or is it functional? ==<br />
<br />
Both. In Haskell, functions are first class, and so are imperative actions.<br />
<br />
There is no reason to consider &quot;imperative language&quot; and &quot;functional language&quot; as mutually exclusive. It's only a historical accident that a few of the most popular imperative languages are unusually bad at functional programming. Functional imperative programming is extremely powerful and is supported by many languages.<br />
<br />
= Math =<br />
<br />
== Was Haskell designed by mathematicians? ==<br />
<br />
Haskell was designed by people studying programming language design. Perhaps programmers would consider them to be mathematicians, while mathematicians would consider them to be programmers.<br />
<br />
Designing a programming language is a hard thing to do. There are many non-obvious tradeoffs, and many lessons to be learned from past failures and successes. Yet many of today's most popular languages were designed by people who hadn't done their homework.<br />
<br />
Haskell was designed by people who knew what they were doing. It's not perfect, but the contrast to an amateur's design is striking.<br />
<br />
== Do I need to know advanced math in order to use Haskell? ==<br />
<br />
No. Certain concepts in Haskell are named after concepts in advanced math. But other languages also appropriate math terminology: consider &quot;[http://en.wikipedia.org/wiki/Singleton_pattern singleton]&quot;, not to mention &quot;function&quot; and &quot;variable&quot;. The way these programming concepts relate to actual mathematics is not necessarily important or relevant.<br />
<br />
In addition, some people write articles about advanced math, using Haskell syntax as their notation. These articles are interesting, but the connection to everyday programming work is usually remote.<br />
<br />
Knowing advanced math will enrich your experience using Haskell, but is by no means a prerequisite.<br />
<br />
= Types =<br />
<br />
== Doesn't a static type system just make it harder to write programs? ==<br />
<br />
Yes. In particular, it makes it ''much'' harder to write ''incorrect'' programs.<br />
<br />
The tradeoff is that correct programs also become somewhat harder to write. In Haskell, features like type inference mitigate this burden to a large extent.<br />
<br />
== How do I make a list with elements of different types? ==<br />
<br />
Are you sure that's what you want? Consider instead creating a single data type to encompass the alternatives:<br />
<br />
<haskell><br />
data Identifier<br />
= ByNumber Int<br />
| ByName String<br />
<br />
doStuff :: [Identifier] -> Whatever<br />
</haskell><br />
<br />
In many dynamically-typed languages you aren't allowed to create &quot;variant types&quot; like this. The type system itself is used as a single ad-hoc global variant type. Keep this in mind if you're translating designs from a dynamically-typed language to Haskell.<br />
<br />
== No really, how do I make a list of elements of different types? ==<br />
<br />
Well, you can't avoid putting all your values into one type. But sometimes the &quot;variant type&quot; approach above is too restrictive. Maybe you need to let other people add to the set of allowed types, the way [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html Control.Exception] allows users to define new exception types.<br />
<br />
You can use an [[existential type]], possibly with a type class. Or you can use [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Dynamic.html Data.Dynamic].<br />
<br />
== I'm making an RPG. Should I define a type for each kind of monster, and a type class for them? ==<br />
<br />
Probably not. Some languages require a new type for each new behavior. In Haskell, behaviors are functions or IO actions, which are first-class values. So you can store behaviors in an ordinary data type:<br />
<br />
<haskell><br />
data MonsterOps = MonsterOps<br />
{ new :: Monster<br />
, move :: Monster -> Monster<br />
, attack :: Monster -> Player -> Player }<br />
<br />
data Monster = Monster<br />
{ position :: (Int, Int)<br />
, hitpoints :: Double }<br />
<br />
beholder :: MonsterOps<br />
beholder = MonsterOps new move attack where<br />
new = Monster (0,0) 9000<br />
move self = ...<br />
attack self player = ...<br />
</haskell><br />
<br />
This approach is especially nice if you want to generate or transform behaviors on the fly. See the article [http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/ &quot;Haskell Antipattern: Existential Typeclass&quot;] for a longer discussion.<br />
<br />
== What's the difference between <hask>Integer</hask> and <hask>Int</hask>? ==<br />
<br />
<p><hask>Integer</hask> can represent arbitrarily large integers, up to using all of the storage on your machine.</p><br />
<br />
<p><hask>Int</hask> can only represent integers in a finite range. The [http://www.haskell.org/onlinereport/haskell2010/haskellch6.html#dx13-135009 language standard] only guarantees a range of -2<sup>29</sup> to (2<sup>29</sup> - 1). Most implementations will provide a full machine-size signed integer, i.e. 32 or 64 bits.</p><br />
<br />
Operations on <hask>Int</hask> can be much faster than operations on <hask>Integer</hask>, but overflow and underflow can cause weird bugs. Using <hask>Int</hask> in an initial design could be considered premature optimization. Unfortunately, many standard library functions (e.g. <hask>length</hask>, <hask>take</hask>) use <hask>Int</hask>.<br />
<br />
== How do I convert type <tt>A</tt> to type <tt>B</tt>? ==<br />
<br />
This is just another way of asking for a function of type <hask>A -> B</hask>. For example, you can convert <hask>Double</hask> to <hask>Int</hask> with <hask>round</hask>, <hask>ceiling</hask>, or <hask>floor</hask>. Haskell does not privilege one of these as ''the'' conversion.<br />
<br />
== Does Haskell have type casts? ==<br />
<br />
The word &quot;cast&quot; can mean a lot of different things.<br />
<br />
* You want to convert a value from one type to another, preserving some idea of what it means. For example, you might convert an <hask>Int</hask> to a <hask>Double</hask> which represents the same integer. In this case you'd just use a function of type <hask>Int -> Double</hask>, such as <hask>fromIntegral</hask>. Haskell doesn't provide special rules or syntax for these functions. See also the previous question.<br /><br /><br />
* You want to pass a value of more specific type to a function expecting a less specific type. There's no syntax for this in Haskell; you just do it. For example you can pass <hask>x :: Int</hask> to <hask>show :: (Show a) => a -> String</hask>, which automatically specializes the type of <hask>show</hask> to <hask>Int -> String</hask>. Note that Haskell does not have subtyping, so this only happens in the context of instantiating type variables.<br /><br /><br />
* You want to use a value of less specific type under the assumption of a more specific type, with a checkable runtime error if they do not match. This is rarely the right way to do things in Haskell, and probably indicates a conceptual / design problem instead. If you really do need such a cast, you can use [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Typeable.html#v:cast <tt>cast</tt>] from [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Typeable.html Data.Typeable]. In this case the &quot;checkable runtime error&quot; is <hask>cast</hask> returning <hask>Nothing</hask>. Note that Haskell does not have subtyping, so this only happens in the context of instantiating type variables.<br /><br /><br />
* You want to use a value of less specific type under the assumption of a more specific type, and if the assumption is incorrect, the program is allowed to segfault / silently corrupt data / give the attacker a root shell / send illicit photos to your boss. Also known as a "reinterpret cast". GHC Haskell has a way to do this, but I dare not speak its name. It's so dangerous and so unlikely to be what you want that it has no place in a general FAQ. You can ask on IRC or read the docs if you have the right kind of morbid curiosity.<br />
<br />
== How do I convert from one numeric type to another? ==<br />
<br />
Probably using one of these:<br />
<br />
<haskell><br />
fromIntegral :: (Integral a, Num b ) => a -> b<br />
realToFrac :: (Real a, Fractional b) => a -> b<br />
</haskell><br />
<br />
<p><hask>fromIntegral</hask> converts to a wider range of types, but <hask>realToFrac</hask> converts from types which aren't integers.</p><br />
<br />
== How do I convert <hask>Maybe Int</hask> to <hask>Int</hask>? ==<br />
<br />
Use pattern-matching. If <hask>mx :: Maybe Int</hask>:<br />
<br />
<haskell><br />
case mx of<br />
Just x -> ...<br />
Nothing -> ...<br />
</haskell><br />
<br />
This forces you to consider the <hask>Nothing</hask> case, and is the main advantage of <hask>Maybe</hask>, compared to adding a <tt>null</tt> value to every type.<br />
<br />
See also the functions [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html#v:maybe <tt>maybe</tt>] and [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html#v:fromMaybe <tt>fromMaybe</tt>] in the module [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html Data.Maybe].<br />
<br />
''Do not'' use <hask>fromJust</hask>, because passing <hask>Nothing</hask> will crash your program with a supremely unhelpful error message. Even when you want to assume the value is not <hask>Nothing</hask>, you can provide a better error message:<br />
<br />
<haskell><br />
let x = fromMaybe (error "custom error message") mx in ...<br />
</haskell><br />
<br />
If you pattern-match without a <hask>Nothing</hask> case:<br />
<br />
<haskell><br />
let Just x = mx in ...<br />
</haskell><br />
<br />
you'll at least get a line number in the error message:<br />
<br />
<pre><br />
*** Exception: foo.hs:2:9-24: Irrefutable pattern failed for pattern Data.Maybe.Just x<br />
</pre><br />
<br />
== How do I convert <hask>IO Int</hask> to <hask>Int</hask>? ==<br />
<br />
You can't; they represent totally different things. An <hask>Int</hask> is an integer. An <hask>IO Int</hask> is a description of how some IO could be performed, in the future, to produce an integer. The IO hasn't been performed yet, and might never happen or might happen more than once.<br />
<br />
See the [[Introduction to IO]].<br />
<br />
== How do I convert between <hask>String</hask> (or <hask>Text</hask>) and <hask>ByteString</hask>? ==<br />
<br />
<p><hask>String</hask> represents a sequence of Unicode characters. <hask>ByteString</hask> represents a sequence of bytes. There are many different, incompatible ways to represent Unicode characters as bytes. See [http://www.joelonsoftware.com/articles/Unicode.html this article] if you're fuzzy on the character / byte distinction.</p><br />
<br />
The module [http://hackage.haskell.org/packages/archive/text/0.11.1.5/doc/html/Data-Text-Encoding.html Data.Text.Encoding] from the <tt>text</tt> package provides functions for common Unicode encodings. For more obscure / legacy encodings, see the [http://hackage.haskell.org/package/text-icu <tt>text-icu</tt>] package.<br />
<br />
== How do I catch the error thrown by <hask>read</hask> on a parse failure? ==<br />
<br />
Don't. Instead use<br />
<br />
<haskell><br />
reads :: (Read a) => String -> [(a, String)]<br />
</haskell><br />
<br />
which returns a list of parses, each with a value and a remaining string. An example:<br />
<br />
<haskell><br />
safeRead :: (Read a) => String -> Maybe a<br />
safeRead x = case reads x of<br />
[(v,"")] -> Just v<br />
_ -> Nothing<br />
</haskell><br />
<br />
== What's the difference between <hask>type</hask>, <hask>data</hask>, and <hask>newtype</hask>? ==<br />
<br />
<p><hask>type</hask> introduces a synonym, which is fully interchangeable with the original type:</p><br />
<br />
<haskell><br />
type Foo = Int<br />
<br />
main = print ((2 :: Int) + (3 :: Foo))<br />
</haskell><br />
<br />
So it provides convenience and documentation, but no additional type checking.<br />
<br />
<p><hask>data</hask> is used to define new data types, distinct from any existing type.</p><br />
<br />
<p><hask>newtype</hask> can mostly be understood as a restricted form of <hask>data</hask>. You can use <hask>newtype</hask> when you have exactly one constructor with exactly one field. In those cases, <hask>newtype</hask> can give better performance than <hask>data</hask>.</p><br />
<br />
There is, however, a [[Newtype|subtle difference]] between <hask>data</hask> and <hask>newtype</hask> semantics, which is why the <hask>newtype</hask> optimization is not applied automatically.<br />
<br />
= Making it work =<br />
<br />
== How can I find type errors? ==<br />
<br />
There's no silver bullet, but here are a few useful techniques:<br />
<br />
* Comment out type signatures and see what GHC infers, using <tt>:t</tt> in GHCi.<br />
* Add more type signatures, for example inside <hask>let</hask>. This makes your assumptions clearer, so GHC's error message may better explain how your assumptions are inconsistent.<br />
* Replace some subexpressions with <hask>undefined</hask>, which can assume any type.<br />
<br />
== How can I find bugs that occur at runtime? ==<br />
<br />
With pure functions, correctness is a matter of getting the right output for a given input. If one function gives incorrect results, you test the functions it calls, and so on until the bad code is located. You can perform these tests directly in GHCi, or with the help of a tool like QuickCheck.<br />
<br />
You can trace evaluation using [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Debug-Trace.html Debug.Trace]. You'll get a printout when the expression is evaluated. Due to lazy evaluation, this might be at an unexpected time. But this property is useful when debugging problems related to excessive laziness.<br />
<br />
GHCi also implements a [http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html &quot;simple imperative-style debugger&quot;].<br />
<br />
Haskell is a natural fit for novel [http://ww2.cs.mu.oz.au/~bjpop/buddha/ &quot;declarative debugging&quot; tools] but to our knowledge, no such tool is production-ready.<br />
<br />
== Why do I get an &quot;undefined symbol&quot; linker error when compiling? ==<br />
<br />
If you're using GHC 6, you should pass <tt>--make</tt> so that GHC will automatically link the appropriate Haskell libraries.<br />
<br />
== How can I get a stack backtrace when my program throws an exception? ==<br />
<br />
The standard stack in GHC Haskell doesn't represent nested function calls. The more informative stack is the profiling cost-center stack, which only exists if your code is built for profiling.<br />
<br />
With GHC 7 you can do something like this:<br />
<br />
<pre>$ ghc -fforce-recomp -prof -auto-all -rtsopts foo.hs</pre><br />
For GHC 6 you should leave off <tt>-rtsopts</tt>, and you'll probably want <tt>--make</tt>.<br />
<br />
You can then run your program with the [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-options-debugging <tt>-xc</tt> RTS option`]:<br />
<br />
<pre>$ ./foo +RTS -xc</pre><br />
== How can I do automated unit testing? ==<br />
<br />
See the [http://book.realworldhaskell.org/read/testing-and-quality-assurance.html testing chapter] in ''Real World Haskell''.<br />
<br />
== How can I find and fix performance problems? ==<br />
<br />
See the [http://book.realworldhaskell.org/read/profiling-and-optimization.html profiling and optimization chapter] in ''Real World Haskell''.<br />
<br />
= Modules =<br />
<br />
== How do I deal with name clashes between modules? ==<br />
<br />
You can disambiguate by prefixing a module name:<br />
<br />
<haskell><br />
import Data.List<br />
import Data.Map<br />
<br />
f = Data.List.lookup 7<br />
g = Data.Map.lookup 7<br />
</haskell><br />
<br />
The import syntax gives you additional control:<br />
<br />
* With <hask>import qualified Foo</hask> the names from <hask>Foo</hask> can ''only'' be used qualified, and won't clash with unqualified names.<br />
<br />
* With <hask>import Foo as M</hask> you'd write <hask>M.x</hask> instead of <hask>Foo.x</hask>.<br />
<br />
You can combine these two features. A more common way to write the above example is:<br />
<br />
<haskell><br />
import qualified Data.Map as M<br />
<br />
f = lookup 7 -- unqualified, from Prelude<br />
g = M.lookup 7<br />
</haskell><br />
<br />
In general, most combinations of <hask>import</hask> features are allowed. You<br />
can combine <hask>as</hask> and <hask>qualified</hask> with import and<br />
<hask>hiding</hask> lists. You can import two modules <hask>as</hask> the same<br />
name, or one module <hask>as</hask> two names, with different import and<br />
<hask>hiding</hask> lists, <hask>qualified</hask> or unqualified, etc.<br />
<br />
== How do I control the <hask>Prelude</hask> import? ==<br />
<br />
Haskell modules implicitly import <hask>Prelude</hask>, unless an explicit import is given. So you can write<br />
<br />
<haskell><br />
import Prelude as P hiding (length, head)<br />
</haskell><br />
<br />
== How do I qualify the name of an infix operator? ==<br />
<br />
You prefix the module name, as usual:<br />
<br />
<haskell><br />
x = 2 + 3<br />
y = 2 Prelude.+ 3<br />
<br />
f = (+) 7<br />
g = (Prelude.+) 7<br />
</haskell><br />
<br />
This looks weird but works fine. The syntax does clash a bit:<br />
<br />
<haskell><br />
xs = [False..True] -- wrong, parses as qualified name<br />
xs = [False .. True] -- ok<br />
</haskell><br />
<br />
== How do I mention an infix operator in an export / import / <hask>hiding</hask> list? ==<br />
<br />
The same way as elsewhere: enclose it in parentheses.<br />
<br />
<haskell><br />
import Prelude ( succ, (+), length, (*) )<br />
</haskell><br />
<br />
== I listed a data type in my import list but its data constructors aren't in scope. How do I fix it? ==<br />
<br />
You have to import data constructors explicitly:<br />
<br />
<haskell><br />
import Prelude ( Maybe ) -- the type only<br />
import Prelude ( Maybe(Nothing) ) -- type and specific constructor(s)<br />
import Prelude ( Maybe(..) ) -- type and all its constructors<br />
</haskell><br />
<br />
== How can I import and re-export a whole module? ==<br />
<br />
<haskell><br />
module Bar ( module Foo ) where<br />
import Foo<br />
</haskell><br />
<br />
== How can I export another module ''and'' everything defined in this module? ==<br />
<br />
<haskell><br />
module Bar ( module Bar, module Foo ) where<br />
import Foo<br />
</haskell><br />
<br />
= The M-word =<br />
<br />
See also &quot;[[What a Monad is not]]&quot;.<br />
<br />
== I heard Haskell is about monads. I heard that the core feature of Haskell is monads. Is that true? ==<br />
<br />
Absolutely not.<br />
<br />
== Do I need to understand monads in order to do IO? ==<br />
<br />
Not really. &quot;<tt>Monad</tt>&quot; is the name of a generic API that applies to many different types, including the <hask>IO</hask> type. If you're only thinking about IO, you don't need to worry about how this API generalizes.<br />
<br />
See the [[Introduction to IO]].<br />
<br />
== What should I know before trying to understand monads? ==<br />
<br />
Let's look at part of the definition of <hask>Monad</hask>:<br /><br /><br />
<br />
<haskell><br />
class Monad m where<br />
(>>=) :: m a -> (a -> m b) -> m b<br />
</haskell><br />
<br />
This uses a lot of features:<br />
<br />
* first-class functions: the second argument to <hask>(>>=)</hask> is a function<br />
<br />
* type constructors (here <hask>m</hask>)<br />
<br />
* type class polymorphism<br />
<br />
* type class polymorphism ''over'' type constructors (which few other languages have)<br />
<br />
* parametric (not type class) polymorphism, over <hask>a</hask> and <hask>b</hask><br />
<br />
Each of these features is more fundamental than the specific idea of monads. If you understand each feature, then <hask>Monad</hask> is a small example of how they fit together. <hask>Functor</hask> is a slightly simpler example, and you can start there instead (see [[Typeclassopedia]]).<br />
<br />
== Aren't monads just a hack for handling impure things in a pure language? ==<br />
<br />
No. This is wrong in several ways.<br />
<br />
First, '''<hask>Monad</hask> isn't special.''' <hask>Monad</hask> is an ordinary Haskell type class. You can define it yourself in a few lines of pure Haskell code, so it's definitely not adding magical new capabilities to the language. Besides that, <hask>Monad</hask> is an API, not an implementation.<br /><br /><br />
<br />
(The <hask>do</hask> syntax ''is'' special, but it's only [[syntactic sugar]]. There's a straightforward translation to ordinary function calls, lambdas, etc.)<br /><br /><br />
<br />
Second, '''most monads have nothing to do with effects or "impurity".''' The <hask>Monad</hask> API is implemented by many different type constructors, including <hask>Maybe</hask> and <hask>[]</hask>. Lists and <hask>Maybe</hask> values are straightforward, familiar data values. There's nothing "impure" about them.<br /><br /><br />
<br />
Third, '''<hask>IO</hask> is not an exception to purity.''' IO actions are pure, first-class values like any other. You can create, store, and evaluate them without causing side effects. IO actions are just ''descriptions'' of IO which ''could'' be performed.<br /><br />
<br />
In short, Haskell programs are pure-functional programs which compute imperative programs.<br />
<br />
It's true that <hask>IO</hask> implements the <hask>Monad</hask> API, but that's not fundamental. You could instead use non-overloaded functions like<br /><br /><br />
<br />
<haskell><br />
returnIO :: a -> IO a<br />
bindIO :: IO a -> (a -> IO b) -> IO b<br />
</haskell><br />
<br />
<br />to glue together IO actions, and it would all work out basically the same. We use the generic <hask>Monad</hask> API for <hask>IO</hask> not because we have to, but because it lets us reuse convenient syntax and [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html libraries]. Indeed, you can [[Introduction to IO|introduce <tt>IO</tt>]] without mentioning <hask>Monad</hask> at all.<br />
<br />
== I heard monads are like burritos or space suits full of nuclear waste. Is that true? ==<br />
<br />
These analogies are not helpful. See [http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ &quot;Abstraction, intuition, and the 'monad tutorial fallacy&quot;'].<br />
<br />
== I can use monads but I feel like I still don't &quot;get&quot; them. What am I missing? ==<br />
<br />
You're not necessarily missing anything. &quot;<tt>Monad</tt>&quot; is just the name of a generic API that applies to many different types. The types implementing the <tt>Monad</tt> API don't have a lot in common.<br />
<br />
You might want to read &quot;[[Typeclassopedia]]&quot; to see how <tt>Monad</tt> fits in with other similar APIs.<br />
<br />
== What's the difference between <hask>State s</hask> and <hask>ST s</hask> monads? ==<br />
<br />
<tt>State s a</tt> is just a wrapper for the function type <hask>s -> (a, s)</hask>: a function that takes an &quot;old state&quot; and returns a &quot;new state&quot; along with its result. You can implement <hask>State</hask> in a few lines of standard Haskell, without any special help from the compiler.<br />
<br />
<hask>ST</hask> gives you true mutable variables with in-place update. You can't implement it yourself in standard Haskell. In GHC, <hask>STRef</hask> and <hask>IORef</hask> will behave the same way at runtime. The difference is the extra compile-time safety checking associated with <hask>runST</hask>.<br />
<br />
= Concurrency and parallelism =<br />
<br />
See also notes on [[parallel]] and [[Concurrency|concurrent]] programming.<br />
<br />
== How can I do X without resorting to threads? ==<br />
<br />
That's usually the wrong attitude. Threads are useful for solving problems. The attitude comes from other languages where some combination of the following holds:<br />
<br />
* Per-thread overhead consumes a lot of memory or CPU<br />
<br />
* Thread APIs are cumbersome, sometimes due to lacking first-class functions or IO actions<br />
<br />
* The thread implementation is fundamentally broken, e.g. a global interpreter lock<br />
<br />
* Threads break easily because programs constantly mutate implicitly-shared state<br />
<br />
None of these is true in GHC Haskell. Threads have disadvantages and are not always the right tool. But avoiding them at all costs is counterproductive.<br />
<br />
== What's the difference between concurrency and parallelism? ==<br />
<br />
Briefly: concurrency describes semantics; parallelism describes an implementation property.<br />
<br />
Concurrent programs are written with explicit threads of control. Concurrent semantics fit naturally with certain real-world problems, like a network server talking to many simultaneous clients. This is still a nice model for writing a network server, even if you only intend to run it on one CPU core — concurrency without parallelism.<br />
<br />
Parallel programs are those which run on multiple CPU cores simultaneously, regardless of how they were implemented.<br />
<br />
Concurrency is a popular way to obtain parallel performance, but converting a pure computation to use concurrent semantics is difficult and error-prone. GHC Haskell provides "[http://hackage.haskell.org/packages/archive/parallel/latest/doc/html/Control-Parallel-Strategies.html semi-implicit parallelism]" as an alternative. Adding these "annotations" to a program cannot change its behavior.<br />
<br />
There's a longer discussion on the [http://ghcmutterings.wordpress.com/2009/10/06/parallelism-concurrency/ GHC blog].<br />
<br />
== How do <hask>par</hask>, <hask>pseq</hask>, and <hask>seq</hask> relate? ==<br />
<br />
The expression <hask>par x y</hask> is semantically equivalent to <hask>y</hask>, but suggests to the runtime system that evaluating <hask>x</hask> in parallel might be a good idea. Usually <hask>x</hask> would be a variable referring to a thunk (unevaluated expression) that will later be needed.<br /><br /><br />
<br />
Now consider <hask>par x (x+y)</hask>. Evaluating this expression suggests evaluating <hask>x</hask> in parallel. But before the runtime system can act on that suggestion, we evaluate <hask>(x+y)</hask>, which will evaluate both <hask>x</hask> and <hask>y</hask> in sequence. It would be better to work on <hask>y</hask> for a while, and only demand <hask>x</hask> later, after perhaps some parallel work has occurred. We can use <hask>pseq</hask> to force this evaluation order, as in <hask>par x (pseq y (x+y))</hask>.<br /><br /><br />
<br />
The [http://hackage.haskell.org/packages/archive/parallel/latest/doc/html/Control-Parallel-Strategies.html Strategies] module provides a nicer interface to these <hask>par</hask> / <hask>pseq</hask> tricks.<br />
<br />
<p><hask>seq</hask> is similar to <hask>pseq</hask> but provides a weaker guarantee. [http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg10973.html The details] are subtle; suffice to say that if you're controlling evaluation order, you want <hask>pseq</hask>.</p><br />
<br />
== How do I do event-based IO in GHC Haskell? Should I call <tt>select</tt>, <tt>epoll</tt>, etc? ==<br />
<br />
No; just do blocking IO from multiple threads, and GHC's runtime system will make these calls for you. GHC Haskell gives you the performance benefits of event-based IO without making you turn your code inside-out.<br />
<br />
Threads in GHC are lightweight — both in performance and in the mental effort of using them. You can handle [http://blog.johantibell.com/2010/09/final-version-of-our-ghc-io-manager.html ten thousand concurrent requests] at high throughput with a naive "one thread per client" model.<br />
<br />
== What's the difference between <hask>forkIO</hask> and <hask>forkOS</hask>? ==<br />
<br />
It only matters if you're calling into a C library that cares about thread-local state. In that case, <hask>forkOS</hask> guarantees that the C library will see the same OS thread each time. Any difference beyond that is an implementation detail and subject to change.<br />
<br />
== How can I wait for a thread to finish and produce a result? ==<br />
<br />
There's a few libraries for this on Hackage, like [http://hackage.haskell.org/package/async <tt>async</tt>], [http://hackage.haskell.org/package/spawn <tt>spawn</tt>], and [http://hackage.haskell.org/package/threads <tt>threads</tt>].<br />
<br />
It's not hard to implement this yourself using [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html <tt>MVar</tt>], though it's harder to get the exception handling right.<br />
<br />
= IRC =<br />
<br />
== What does lambdabot's "info" command do? ==<br />
<br />
At first, it seems like it just echos whatever you type:<br />
<br />
<user> ?info foo bar baz<br />
<lambdabot> foo bar baz<br />
<br />
What is actually happening is that it autocorrects to the "undo" command, which desugars do blocks according to the Report's rules. So, a more interesting example might look like this:<br />
<br />
<user> ?info do { foo; x <- bar; baz }<br />
<lambdabot> foo >> bar >>= \ x -> baz<br />
<br />
[[Category:FAQ]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Roll_your_own_IRC_bot&diff=58334Roll your own IRC bot2014-06-15T08:31:22Z<p>Lambda Fairy: Update code to modern standards</p>
<hr />
<div><br />
This tutorial is designed as a practical guide to writing real world<br />
code in [http://haskell.org Haskell] and hopes to intuitively motivate<br />
and introduce some of the advanced features of Haskell to the novice<br />
programmer. Our goal is to write a concise, robust and elegant<br />
[http://haskell.org/haskellwiki/IRC_channel IRC] bot in Haskell.<br />
<br />
== Getting started ==<br />
<br />
You'll need a reasonably recent version of [http://haskell.org/ghc GHC]<br />
or [http://haskell.org/hugs Hugs]. Our first step is to get on the<br />
network. So let's start by importing the Network package, and the<br />
standard IO library and defining a server to connect to.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
t <- hGetContents h<br />
print t<br />
</haskell><br />
<br />
The key here is the <code>main</code> function. This is the entry point to a Haskell program. We first connect to the server, then set the buffering on the socket off. Once we've got a socket, we can then just read and print any data we receive.<br />
<br />
Put this code in the module <code>1.hs</code> and we can then run it. Use whichever system you like:<br />
<br />
Using runhaskell:<br />
<br />
$ runhaskell 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or we can just compile it to an executable with GHC:<br />
<br />
$ ghc --make 1.hs -o tutbot<br />
Chasing modules from: 1.hs<br />
Compiling Main ( 1.hs, 1.o )<br />
Linking ...<br />
$ ./tutbot<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or using GHCi:<br />
<br />
$ ghci 1.hs<br />
*Main> main<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or in Hugs:<br />
<br />
$ runhugs 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Great! We're on the network.<br />
<br />
== Talking IRC ==<br />
<br />
Now we're listening to the server, we better start sending some information back. Three details are important: the nick, the user name, and a channel to join. So let's send those.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
import Text.Printf<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
write h "NICK" nick<br />
write h "USER" (nick++" 0 * :tutorial bot")<br />
write h "JOIN" chan<br />
listen h<br />
<br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
<br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
Now, we've done quite a few things here. Firstly, we import <code>Text.Printf</code>, which will be useful. We also set up a channel name and bot nickname. The <code>main</code> function has been extended to send messages back to the IRC server using a <code>write</code> function. Let's look at that a bit more closely:<br />
<br />
<haskell><br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
</haskell><br />
<br />
We've given <code>write</code> an explicit type to help document it, and we'll use explicit types signatures from now on, as they're just good practice (though of course not required, as Haskell uses type inference to work out the types anyway).<br />
<br />
The <code>write</code> function takes 3 arguments; a handle (our socket), and then two strings representing an IRC protocol action, and any arguments it takes. <code>write</code> then uses <code>hPrintf</code> to build an IRC message and write it over the wire to the server. For debugging purposes we also print to standard output the message we send.<br />
<br />
Our second function, <code>listen</code>, is as follows:<br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
This function takes a Handle argument, and sits in an infinite loop reading lines of text from the network and printing them. We take advantage of two powerful features; lazy evaluation and higher order functions to roll our own loop control structure, <code>forever</code>, as a normal function! <code>forever</code> takes a chunk of code as an argument, evaluates it and recurses - an infinite loop function. It is very common to roll our own control structures in Haskell this way, using higher order functions. No need to add new syntax to the language, lisp-like macros or meta programming - you just write a normal function to implement whatever control flow you wish. We can also avoid <code>do</code>-notation, and directly write: <code>forever a = a >> forever a</code>.<br />
<br />
Let's run this thing:<br />
<br />
<haskell><br />
$ runhaskell 2.hs<br />
> NICK tutbot<br />
> USER tutbot 0 * :tutorial bot<br />
> JOIN #tutbot-testing<br />
NOTICE AUTH :*** Looking up your hostname...<br />
NOTICE AUTH :*** Found your hostname, welcome back<br />
NOTICE AUTH :*** Checking ident<br />
NOTICE AUTH :*** No identd (auth) response<br />
:orwell.freenode.net 001 tutbot :Welcome to the freenode IRC Network tutbot<br />
:orwell.freenode.net 002 tutbot :Your host is orwell.freenode.net<br />
...<br />
:tutbot!n=tutbot@aa.bb.cc.dd JOIN :#tutbot-testing<br />
:orwell.freenode.net MODE #tutbot-testing +ns<br />
:orwell.freenode.net 353 tutbot @ #tutbot-testing :@tutbot<br />
:orwell.freenode.net 366 tutbot #tutbot-testing :End of /NAMES list.<br />
</haskell><br />
<br />
And we're in business! From an IRC client, we can watch the bot connect:<br />
<br />
15:02 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:02 dons> hello<br />
<br />
And the bot logs to standard output:<br />
<br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :hello<br />
<br />
We can now implement some commands.<br />
<br />
== A simple interpreter ==<br />
<br />
Add these additional imports before changing the <code>listen</code> function.<br />
<br />
<haskell><br />
import Data.List<br />
import System.Exit<br />
</haskell><br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
t <- hGetLine h<br />
let s = init t<br />
if ping s then pong s else eval h (clean s)<br />
putStrLn s<br />
where<br />
forever a = a >> forever a<br />
<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write h "PONG" (':' : drop 6 x)<br />
</haskell><br />
<br />
We add 3 features to the bot here by modifying <code>listen</code>.<br />
Firstly, it responds to <code>PING</code> messages: <code>if ping s then pong s ... </code>.<br />
This is useful for servers that require pings to keep clients connected.<br />
Before we can process a command, remember the IRC protocol generates<br />
input lines of the form:<br />
<br />
<haskell><br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :!id foo<br />
</haskell><br />
<br />
so we need a <code>clean</code> function to simply drop the leading ':' character, and then everything up to the next ':', leaving just the actual command content. We then pass this cleaned up string to <code>eval</code>, which then dispatches bot commands.<br />
<br />
<haskell><br />
eval :: Handle -> String -> IO ()<br />
eval h "!quit" = write h "QUIT" ":Exiting" >> exitWith ExitSuccess<br />
eval h x | "!id " `isPrefixOf` x = privmsg h (drop 4 x)<br />
eval _ _ = return () -- ignore everything else<br />
</haskell><br />
<br />
So, if the single string "!quit" is received, we inform the server and exit the program. If a string beginning with "!id" appears, we echo any argument string back to the server (<code>id</code> is the Haskell identity function, which just returns its argument). Finally, if no other matches occur, we do nothing.<br />
<br />
We add the <code>privmsg</code> function - a useful wrapper over <code>write</code> for sending <code>PRIVMSG</code> lines to the server.<br />
<br />
<haskell><br />
privmsg :: Handle -> String -> IO ()<br />
privmsg h s = write h "PRIVMSG" (chan ++ " :" ++ s)<br />
</haskell><br />
<br />
Here's a transcript from our minimal bot running in channel:<br />
<br />
15:12 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:13 dons> !id hello, world!<br />
15:13 tutbot> hello, world!<br />
15:13 dons> !id very pleased to meet you.<br />
15:13 tutbot> very pleased to meet you.<br />
15:13 dons> !quit<br />
15:13 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
Now, before we go further, let's refactor the code a bit.<br />
<br />
== Roll your own monad ==<br />
<br />
A small annoyance so far has been that we've had to thread around our socket to every function that needs to talk to the network. The socket is essentially <em>immutable state</em>, that could be treated as a global read only value in other languages. In Haskell, we can implement such a structure using a state <em>monad</em>. Monads are a very powerful abstraction, and we'll only touch on them here. The interested reader is referred to [http://www.haskell.org/haskellwiki/All_About_Monads All About Monads]. We'll be using a custom monad specifically to implement a read-only global state for our bot.<br />
<br />
The key requirement is that we wish to be able to perform IO actions, as well as thread a small state value transparently through the program. As this is Haskell, we can take the extra step of partitioning our stateful code from all other program code, using a new type.<br />
<br />
So let's define a small state monad:<br />
<haskell><br />
data Bot = Bot { socket :: Handle }<br />
<br />
type Net = ReaderT Bot IO<br />
</haskell><br />
<br />
Firstly, we define a data type for the global state. In this case, it is the <code>Bot</code> type, a simple struct storing our network socket. We then layer this data type over our existing IO code, with a <em>monad transformer</em>. This isn't as scary as it sounds and the effect is that we can just treat the socket as a global read-only value anywhere we need it. We'll call this new io + state structure the <code>Net</code> monad. <code>ReaderT</code> is a <em>type constructor</em>, essentially a type function, that takes 2 types as arguments, building a result type: the <code>Net</code> monad type.<br />
<br />
We can now throw out all that socket threading and just grab the socket when we need it. The key steps are connecting to the server, followed by the initialisation of our new state monad and then to run the main bot loop with that state. We add a small function, which takes the intial bot state and evaluates the bot's <code>run</code> loop "in" the Net monad, using the Reader monad's <code>runReaderT</code> function:<br />
<br />
<haskell><br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
where <code>run</code> is a small function to register the bot's nick, join a channel, and start listening for commands.<br />
<br />
While we're here, we can tidy up the main function a little by using <code>Control.Exception.bracket</code> to explicitly delimit the connection, shutdown and main loop phases of the program - a useful technique.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
That is, the higher order function <code>bracket</code> takes 3 arguments: a function to connect to the server, a function to disconnect and a main loop to run in between. We can use <code>bracket</code> whenever we wish to run some code before and after a particular action - like <code>forever</code>, this is another control structure implemented as a normal Haskell function.<br />
<br />
Rather than threading the socket around, we can now simply ask for it when needed. Note that the type of <code>write</code> changes - it is in the Net monad, which tells us that the bot must already by connected to a server (and thus it is ok to use the socket, as it is initialised).<br />
<br />
<haskell><br />
--<br />
-- Send a message out to the server we're currently connected to<br />
--<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
</haskell><br />
<br />
In order to use both state and IO, we use the small <code>io</code> function to <em>lift</em> an IO expression into the Net monad making that IO function available to code in the <code>Net</code> monad.<br />
<br />
<haskell><br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Similarly, we can combine IO actions with pure functions by lifting them into the IO monad. We can therefore simplify our <code>hGetLine</code> call:<br />
<haskell><br />
do t <- io (hGetLine h)<br />
let s = init t<br />
</haskell><br />
by lifting <code>init</code> over IO:<br />
<haskell><br />
do s <- init `fmap` io (hGetLine h)<br />
</haskell><br />
<br />
The monadic, stateful, exception-handling bot in all its glory:<br />
<br />
<haskell><br />
import Data.List<br />
import Network<br />
import System.IO<br />
import System.Exit<br />
import Control.Arrow<br />
import Control.Monad.Reader<br />
import Control.Exception<br />
import Text.Printf<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
-- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state.<br />
type Net = ReaderT Bot IO<br />
data Bot = Bot { socket :: Handle }<br />
<br />
-- Set up actions to run on start and end, and run the main loop<br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = runReaderT run st<br />
<br />
-- Connect to the server and return the initial bot state<br />
connect :: IO Bot<br />
connect = notify $ do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h)<br />
where<br />
notify a = bracket_<br />
(printf "Connecting to %s ... " server >> hFlush stdout)<br />
(putStrLn "done.")<br />
a<br />
<br />
-- We're in the Net monad now, so we've connected successfully<br />
-- Join a channel, and start processing commands<br />
run :: Net ()<br />
run = do<br />
write "NICK" nick<br />
write "USER" (nick++" 0 * :tutorial bot")<br />
write "JOIN" chan<br />
asks socket >>= listen<br />
<br />
-- Process each line from the server<br />
listen :: Handle -> Net ()<br />
listen h = forever $ do<br />
s <- init `fmap` io (hGetLine h)<br />
io (putStrLn s)<br />
if ping s then pong s else eval (clean s)<br />
where<br />
forever a = a >> forever a<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write "PONG" (':' : drop 6 x)<br />
<br />
-- Dispatch a command<br />
eval :: String -> Net ()<br />
eval "!quit" = write "QUIT" ":Exiting" >> io (exitWith ExitSuccess)<br />
eval x | "!id " `isPrefixOf` x = privmsg (drop 4 x)<br />
eval _ = return () -- ignore everything else<br />
<br />
-- Send a privmsg to the current chan + server<br />
privmsg :: String -> Net ()<br />
privmsg s = write "PRIVMSG" (chan ++ " :" ++ s)<br />
<br />
-- Send a message out to the server we're currently connected to<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
<br />
-- Convenience.<br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Note that we threw in a new control structure, <code>notify</code>, for fun. Now we're almost done! Let's run this bot. Using runhaskell:<br />
<br />
$ runhaskell 4.hs<br />
<br />
or using GHC:<br />
<br />
$ ghc --make 4.hs -o tutbot<br />
Chasing modules from: 4.hs<br />
Compiling Main ( 4.hs, 4.o )<br />
Linking ...<br />
$ ./tutbot<br />
<br />
If you're using Hugs, you'll have to use the <code>-98</code> flag:<br />
<br />
$ runhugs -98 4.hs<br />
<br />
And from an IRC client we can watch it connect:<br />
<br />
15:26 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:28 dons> !id all good?<br />
15:28 tutbot> all good?<br />
15:28 dons> !quit<br />
15:28 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
So we now have a bot with explicit read-only monadic state, error handling, and some basic IRC operations. If we wished to add read-write state, we need only change the <code>ReaderT</code> transformer to <code>StateT</code>.<br />
<br />
== Extending the bot ==<br />
<br />
Let's implement a basic new command: uptime tracking. Conceptually, we need to remember the time the bot starts. Then, if a user requests, we work out the total running time and print it as a string. A nice way to do this is to extend the bot's state with a start time field:<br />
<br />
<haskell><br />
import System.Time<br />
</haskell><br />
<br />
<haskell><br />
data Bot = Bot { socket :: Handle, starttime :: ClockTime }<br />
</haskell><br />
<br />
We can then modify the initial <code>connect</code> function to also set the start time.<br />
<br />
<haskell><br />
connect :: IO Bot<br />
connect = notify $ do<br />
t <- getClockTime<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h t)<br />
</haskell><br />
<br />
We then add a new case to the <code>eval</code> function, to handle uptime requests:<br />
<br />
<haskell><br />
eval "!uptime" = uptime >>= privmsg<br />
</haskell><br />
<br />
This will just run the <code>uptime</code> function and send it back to the server. <code>uptime</code> itself is:<br />
<br />
<haskell><br />
uptime :: Net String<br />
uptime = do<br />
now <- io getClockTime<br />
zero <- asks starttime<br />
return . pretty $ diffClockTimes now zero<br />
</haskell><br />
<br />
That is, in the Net monad, find the current time and the start time, and then calculate the difference, returning that number as a string. Rather than use the normal representation for dates, we'll write our own custom formatter for dates:<br />
<br />
<haskell><br />
--<br />
-- Pretty print the date in '1d 9h 9m 17s' format<br />
--<br />
pretty :: TimeDiff -> String<br />
pretty td =<br />
unwords $ map (uncurry (++) . first show) $<br />
if null diffs then [(0,"s")] else diffs<br />
where merge (tot,acc) (sec,typ) = let (sec',tot') = divMod tot sec<br />
in (tot',(sec',typ):acc)<br />
metrics = [(86400,"d"),(3600,"h"),(60,"m"),(1,"s")]<br />
diffs = filter ((/= 0) . fst) $ reverse $ snd $<br />
foldl' merge (tdSec td,[]) metrics<br />
</haskell><br />
<br />
And that's it. Running the bot with this new command:<br />
<br />
16:03 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
16:03 dons> !uptime<br />
16:03 tutbot> 51s<br />
16:03 dons> !uptime<br />
16:03 tutbot> 1m 1s<br />
16:12 dons> !uptime<br />
16:12 tutbot> 9m 46s<br />
<br />
== Where to now? ==<br />
<br />
This is just a flavour of application programming in Haskell, and only<br />
hints at the power of Haskell's lazy evaluation, static typing, monadic<br />
effects and higher order functions. There is much, much more to be said<br />
on these topics. Some places to start:<br />
<br />
* The [[/Source|complete bot source]] (also [http://www.cse.unsw.edu.au/~dons/irc/bot.html mirrored here])<br />
* A [[/Transcript|full transcript]].<br />
* [[Haskell|Haskell.org]]<br />
* [[Example_code|More Haskell code]]<br />
* [[Books and tutorials|Learning Haskell]]<br />
* A gallery of [[Libraries_and_tools/Network|network apps]] in Haskell<br />
<br />
Or take the bot home and hack! Some suggestions:<br />
* Use <code>forkIO</code> to add a command line interface, and you've got yourself an irc client with 4 more lines of code.<br />
* Port some commands from [[Lambdabot]].<br />
<br />
Author: [http://www.cse.unsw.edu.au/~dons Don Stewart]<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Code]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Roll_your_own_IRC_bot&diff=58333Roll your own IRC bot2014-06-15T08:28:32Z<p>Lambda Fairy: Don't silence exceptions -- programs should fail loudly and dramatically</p>
<hr />
<div><br />
This tutorial is designed as a practical guide to writing real world<br />
code in [http://haskell.org Haskell] and hopes to intuitively motivate<br />
and introduce some of the advanced features of Haskell to the novice<br />
programmer. Our goal is to write a concise, robust and elegant<br />
[http://haskell.org/haskellwiki/IRC_channel IRC] bot in Haskell.<br />
<br />
== Getting started ==<br />
<br />
You'll need a reasonably recent version of [http://haskell.org/ghc GHC]<br />
or [http://haskell.org/hugs Hugs]. Our first step is to get on the<br />
network. So let's start by importing the Network package, and the<br />
standard IO library and defining a server to connect to.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
t <- hGetContents h<br />
print t<br />
</haskell><br />
<br />
The key here is the <code>main</code> function. This is the entry point to a Haskell program. We first connect to the server, then set the buffering on the socket off. Once we've got a socket, we can then just read and print any data we receive.<br />
<br />
Put this code in the module <code>1.hs</code> and we can then run it. Use whichever system you like:<br />
<br />
Using runhaskell:<br />
<br />
$ runhaskell 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or we can just compile it to an executable with GHC:<br />
<br />
$ ghc --make 1.hs -o tutbot<br />
Chasing modules from: 1.hs<br />
Compiling Main ( 1.hs, 1.o )<br />
Linking ...<br />
$ ./tutbot<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or using GHCi:<br />
<br />
$ ghci 1.hs<br />
*Main> main<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Or in Hugs:<br />
<br />
$ runhugs 1.hs<br />
"NOTICE AUTH :*** Looking up your hostname...\r\nNOTICE AUTH :***<br />
Checking ident\r\nNOTICE AUTH :*** Found your hostname\r\n ...<br />
<br />
Great! We're on the network.<br />
<br />
== Talking IRC ==<br />
<br />
Now we're listening to the server, we better start sending some information back. Three details are important: the nick, the user name, and a channel to join. So let's send those.<br />
<br />
<haskell><br />
import Network<br />
import System.IO<br />
import Text.Printf<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
main = do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
write h "NICK" nick<br />
write h "USER" (nick++" 0 * :tutorial bot")<br />
write h "JOIN" chan<br />
listen h<br />
<br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
<br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
Now, we've done quite a few things here. Firstly, we import <code>Text.Printf</code>, which will be useful. We also set up a channel name and bot nickname. The <code>main</code> function has been extended to send messages back to the IRC server using a <code>write</code> function. Let's look at that a bit more closely:<br />
<br />
<haskell><br />
write :: Handle -> String -> String -> IO ()<br />
write h s t = do<br />
hPrintf h "%s %s\r\n" s t<br />
printf "> %s %s\n" s t<br />
</haskell><br />
<br />
We've given <code>write</code> an explicit type to help document it, and we'll use explicit types signatures from now on, as they're just good practice (though of course not required, as Haskell uses type inference to work out the types anyway).<br />
<br />
The <code>write</code> function takes 3 arguments; a handle (our socket), and then two strings representing an IRC protocol action, and any arguments it takes. <code>write</code> then uses <code>hPrintf</code> to build an IRC message and write it over the wire to the server. For debugging purposes we also print to standard output the message we send.<br />
<br />
Our second function, <code>listen</code>, is as follows:<br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
s <- hGetLine h<br />
putStrLn s<br />
where<br />
forever a = do a; forever a<br />
</haskell><br />
<br />
This function takes a Handle argument, and sits in an infinite loop reading lines of text from the network and printing them. We take advantage of two powerful features; lazy evaluation and higher order functions to roll our own loop control structure, <code>forever</code>, as a normal function! <code>forever</code> takes a chunk of code as an argument, evaluates it and recurses - an infinite loop function. It is very common to roll our own control structures in Haskell this way, using higher order functions. No need to add new syntax to the language, lisp-like macros or meta programming - you just write a normal function to implement whatever control flow you wish. We can also avoid <code>do</code>-notation, and directly write: <code>forever a = a >> forever a</code>.<br />
<br />
Let's run this thing:<br />
<br />
<haskell><br />
$ runhaskell 2.hs<br />
> NICK tutbot<br />
> USER tutbot 0 * :tutorial bot<br />
> JOIN #tutbot-testing<br />
NOTICE AUTH :*** Looking up your hostname...<br />
NOTICE AUTH :*** Found your hostname, welcome back<br />
NOTICE AUTH :*** Checking ident<br />
NOTICE AUTH :*** No identd (auth) response<br />
:orwell.freenode.net 001 tutbot :Welcome to the freenode IRC Network tutbot<br />
:orwell.freenode.net 002 tutbot :Your host is orwell.freenode.net<br />
...<br />
:tutbot!n=tutbot@aa.bb.cc.dd JOIN :#tutbot-testing<br />
:orwell.freenode.net MODE #tutbot-testing +ns<br />
:orwell.freenode.net 353 tutbot @ #tutbot-testing :@tutbot<br />
:orwell.freenode.net 366 tutbot #tutbot-testing :End of /NAMES list.<br />
</haskell><br />
<br />
And we're in business! From an IRC client, we can watch the bot connect:<br />
<br />
15:02 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:02 dons> hello<br />
<br />
And the bot logs to standard output:<br />
<br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :hello<br />
<br />
We can now implement some commands.<br />
<br />
== A simple interpreter ==<br />
<br />
Add these additional imports before changing the <code>listen</code> function.<br />
<br />
<haskell><br />
import Data.List<br />
import System.Exit<br />
</haskell><br />
<br />
<haskell><br />
listen :: Handle -> IO ()<br />
listen h = forever $ do<br />
t <- hGetLine h<br />
let s = init t<br />
if ping s then pong s else eval h (clean s)<br />
putStrLn s<br />
where<br />
forever a = a >> forever a<br />
<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write h "PONG" (':' : drop 6 x)<br />
</haskell><br />
<br />
We add 3 features to the bot here by modifying <code>listen</code>.<br />
Firstly, it responds to <code>PING</code> messages: <code>if ping s then pong s ... </code>.<br />
This is useful for servers that require pings to keep clients connected.<br />
Before we can process a command, remember the IRC protocol generates<br />
input lines of the form:<br />
<br />
<haskell><br />
:dons!i=dons@my.net PRIVMSG #tutbot-testing :!id foo<br />
</haskell><br />
<br />
so we need a <code>clean</code> function to simply drop the leading ':' character, and then everything up to the next ':', leaving just the actual command content. We then pass this cleaned up string to <code>eval</code>, which then dispatches bot commands.<br />
<br />
<haskell><br />
eval :: Handle -> String -> IO ()<br />
eval h "!quit" = write h "QUIT" ":Exiting" >> exitWith ExitSuccess<br />
eval h x | "!id " `isPrefixOf` x = privmsg h (drop 4 x)<br />
eval _ _ = return () -- ignore everything else<br />
</haskell><br />
<br />
So, if the single string "!quit" is received, we inform the server and exit the program. If a string beginning with "!id" appears, we echo any argument string back to the server (<code>id</code> is the Haskell identity function, which just returns its argument). Finally, if no other matches occur, we do nothing.<br />
<br />
We add the <code>privmsg</code> function - a useful wrapper over <code>write</code> for sending <code>PRIVMSG</code> lines to the server.<br />
<br />
<haskell><br />
privmsg :: Handle -> String -> IO ()<br />
privmsg h s = write h "PRIVMSG" (chan ++ " :" ++ s)<br />
</haskell><br />
<br />
Here's a transcript from our minimal bot running in channel:<br />
<br />
15:12 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:13 dons> !id hello, world!<br />
15:13 tutbot> hello, world!<br />
15:13 dons> !id very pleased to meet you.<br />
15:13 tutbot> very pleased to meet you.<br />
15:13 dons> !quit<br />
15:13 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
Now, before we go further, let's refactor the code a bit.<br />
<br />
== Roll your own monad ==<br />
<br />
A small annoyance so far has been that we've had to thread around our socket to every function that needs to talk to the network. The socket is essentially <em>immutable state</em>, that could be treated as a global read only value in other languages. In Haskell, we can implement such a structure using a state <em>monad</em>. Monads are a very powerful abstraction, and we'll only touch on them here. The interested reader is referred to [http://www.haskell.org/haskellwiki/All_About_Monads All About Monads]. We'll be using a custom monad specifically to implement a read-only global state for our bot.<br />
<br />
The key requirement is that we wish to be able to perform IO actions, as well as thread a small state value transparently through the program. As this is Haskell, we can take the extra step of partitioning our stateful code from all other program code, using a new type.<br />
<br />
So let's define a small state monad:<br />
<haskell><br />
data Bot = Bot { socket :: Handle }<br />
<br />
type Net = ReaderT Bot IO<br />
</haskell><br />
<br />
Firstly, we define a data type for the global state. In this case, it is the <code>Bot</code> type, a simple struct storing our network socket. We then layer this data type over our existing IO code, with a <em>monad transformer</em>. This isn't as scary as it sounds and the effect is that we can just treat the socket as a global read-only value anywhere we need it. We'll call this new io + state structure the <code>Net</code> monad. <code>ReaderT</code> is a <em>type constructor</em>, essentially a type function, that takes 2 types as arguments, building a result type: the <code>Net</code> monad type.<br />
<br />
We can now throw out all that socket threading and just grab the socket when we need it. The key steps are connecting to the server, followed by the initialisation of our new state monad and then to run the main bot loop with that state. We add a small function, which takes the intial bot state and evaluates the bot's <code>run</code> loop "in" the Net monad, using the Reader monad's <code>runReaderT</code> function:<br />
<br />
<haskell><br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
where <code>run</code> is a small function to register the bot's nick, join a channel, and start listening for commands.<br />
<br />
While we're here, we can tidy up the main function a little by using <code>Control.Exception.bracket</code> to explicitly delimit the connection, shutdown and main loop phases of the program - a useful technique.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = runReaderT run st<br />
</haskell><br />
<br />
That is, the higher order function <code>bracket</code> takes 3 arguments: a function to connect to the server, a function to disconnect and a main loop to run in between. We can use <code>bracket</code> whenever we wish to run some code before and after a particular action - like <code>forever</code>, this is another control structure implemented as a normal Haskell function.<br />
<br />
Rather than threading the socket around, we can now simply ask for it when needed. Note that the type of <code>write</code> changes - it is in the Net monad, which tells us that the bot must already by connected to a server (and thus it is ok to use the socket, as it is initialised).<br />
<br />
<haskell><br />
--<br />
-- Send a message out to the server we're currently connected to<br />
--<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
</haskell><br />
<br />
In order to use both state and IO, we use the small <code>io</code> function to <em>lift</em> an IO expression into the Net monad making that IO function available to code in the <code>Net</code> monad.<br />
<br />
<haskell><br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Similarly, we can combine IO actions with pure functions by lifting them into the IO monad. We can therefore simplify our <code>hGetLine</code> call:<br />
<haskell><br />
do t <- io (hGetLine h)<br />
let s = init t<br />
</haskell><br />
by lifting <code>init</code> over IO:<br />
<haskell><br />
do s <- init `fmap` io (hGetLine h)<br />
</haskell><br />
<br />
The monadic, stateful, exception-handling bot in all its glory:<br />
<br />
<haskell><br />
import Data.List<br />
import Network<br />
import System.IO<br />
import System.Exit<br />
import Control.Arrow<br />
import Control.Monad.Reader<br />
import Control.Exception -- *** for base-3<br />
-- import Control.OldException -- *** for base-4<br />
import Text.Printf<br />
import Prelude hiding (catch)<br />
<br />
server = "irc.freenode.org"<br />
port = 6667<br />
chan = "#tutbot-testing"<br />
nick = "tutbot"<br />
<br />
-- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state.<br />
type Net = ReaderT Bot IO<br />
data Bot = Bot { socket :: Handle }<br />
<br />
-- Set up actions to run on start and end, and run the main loop<br />
main :: IO ()<br />
main = bracket connect disconnect loop<br />
where<br />
disconnect = hClose . socket<br />
loop st = catch (runReaderT run st) (const $ return ())<br />
-- catch (runReaderT run st) (\(SomeException _) -> return ()) -- *** Control.Exception with base-4<br />
<br />
-- Connect to the server and return the initial bot state<br />
connect :: IO Bot<br />
connect = notify $ do<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h)<br />
where<br />
notify a = bracket_<br />
(printf "Connecting to %s ... " server >> hFlush stdout)<br />
(putStrLn "done.")<br />
a<br />
<br />
-- We're in the Net monad now, so we've connected successfully<br />
-- Join a channel, and start processing commands<br />
run :: Net ()<br />
run = do<br />
write "NICK" nick<br />
write "USER" (nick++" 0 * :tutorial bot")<br />
write "JOIN" chan<br />
asks socket >>= listen<br />
<br />
-- Process each line from the server<br />
listen :: Handle -> Net ()<br />
listen h = forever $ do<br />
s <- init `fmap` io (hGetLine h)<br />
io (putStrLn s)<br />
if ping s then pong s else eval (clean s)<br />
where<br />
forever a = a >> forever a<br />
clean = drop 1 . dropWhile (/= ':') . drop 1<br />
ping x = "PING :" `isPrefixOf` x<br />
pong x = write "PONG" (':' : drop 6 x)<br />
<br />
-- Dispatch a command<br />
eval :: String -> Net ()<br />
eval "!quit" = write "QUIT" ":Exiting" >> io (exitWith ExitSuccess)<br />
eval x | "!id " `isPrefixOf` x = privmsg (drop 4 x)<br />
eval _ = return () -- ignore everything else<br />
<br />
-- Send a privmsg to the current chan + server<br />
privmsg :: String -> Net ()<br />
privmsg s = write "PRIVMSG" (chan ++ " :" ++ s)<br />
<br />
-- Send a message out to the server we're currently connected to<br />
write :: String -> String -> Net ()<br />
write s t = do<br />
h <- asks socket<br />
io $ hPrintf h "%s %s\r\n" s t<br />
io $ printf "> %s %s\n" s t<br />
<br />
-- Convenience.<br />
io :: IO a -> Net a<br />
io = liftIO<br />
</haskell><br />
<br />
Note that we threw in a new control structure, <code>notify</code>, for fun. Now we're almost done! Let's run this bot. Using runhaskell:<br />
<br />
$ runhaskell 4.hs<br />
<br />
or using GHC:<br />
<br />
$ ghc --make 4.hs -o tutbot<br />
Chasing modules from: 4.hs<br />
Compiling Main ( 4.hs, 4.o )<br />
Linking ...<br />
$ ./tutbot<br />
<br />
If you're using Hugs, you'll have to use the <code>-98</code> flag:<br />
<br />
$ runhugs -98 4.hs<br />
<br />
And from an IRC client we can watch it connect:<br />
<br />
15:26 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
15:28 dons> !id all good?<br />
15:28 tutbot> all good?<br />
15:28 dons> !quit<br />
15:28 -- tutbot [n=tutbot@aa.bb.cc.dd] has quit [Client Quit]<br />
<br />
So we now have a bot with explicit read-only monadic state, error handling, and some basic IRC operations. If we wished to add read-write state, we need only change the <code>ReaderT</code> transformer to <code>StateT</code>.<br />
<br />
== Extending the bot ==<br />
<br />
Let's implement a basic new command: uptime tracking. Conceptually, we need to remember the time the bot starts. Then, if a user requests, we work out the total running time and print it as a string. A nice way to do this is to extend the bot's state with a start time field:<br />
<br />
<haskell><br />
import System.Time<br />
</haskell><br />
<br />
<haskell><br />
data Bot = Bot { socket :: Handle, starttime :: ClockTime }<br />
</haskell><br />
<br />
We can then modify the initial <code>connect</code> function to also set the start time.<br />
<br />
<haskell><br />
connect :: IO Bot<br />
connect = notify $ do<br />
t <- getClockTime<br />
h <- connectTo server (PortNumber (fromIntegral port))<br />
hSetBuffering h NoBuffering<br />
return (Bot h t)<br />
</haskell><br />
<br />
We then add a new case to the <code>eval</code> function, to handle uptime requests:<br />
<br />
<haskell><br />
eval "!uptime" = uptime >>= privmsg<br />
</haskell><br />
<br />
This will just run the <code>uptime</code> function and send it back to the server. <code>uptime</code> itself is:<br />
<br />
<haskell><br />
uptime :: Net String<br />
uptime = do<br />
now <- io getClockTime<br />
zero <- asks starttime<br />
return . pretty $ diffClockTimes now zero<br />
</haskell><br />
<br />
That is, in the Net monad, find the current time and the start time, and then calculate the difference, returning that number as a string. Rather than use the normal representation for dates, we'll write our own custom formatter for dates:<br />
<br />
<haskell><br />
--<br />
-- Pretty print the date in '1d 9h 9m 17s' format<br />
--<br />
pretty :: TimeDiff -> String<br />
pretty td =<br />
unwords $ map (uncurry (++) . first show) $<br />
if null diffs then [(0,"s")] else diffs<br />
where merge (tot,acc) (sec,typ) = let (sec',tot') = divMod tot sec<br />
in (tot',(sec',typ):acc)<br />
metrics = [(86400,"d"),(3600,"h"),(60,"m"),(1,"s")]<br />
diffs = filter ((/= 0) . fst) $ reverse $ snd $<br />
foldl' merge (tdSec td,[]) metrics<br />
</haskell><br />
<br />
And that's it. Running the bot with this new command:<br />
<br />
16:03 -- tutbot [n=tutbot@aa.bb.cc.dd] has joined #tutbot-testing<br />
16:03 dons> !uptime<br />
16:03 tutbot> 51s<br />
16:03 dons> !uptime<br />
16:03 tutbot> 1m 1s<br />
16:12 dons> !uptime<br />
16:12 tutbot> 9m 46s<br />
<br />
== Where to now? ==<br />
<br />
This is just a flavour of application programming in Haskell, and only<br />
hints at the power of Haskell's lazy evaluation, static typing, monadic<br />
effects and higher order functions. There is much, much more to be said<br />
on these topics. Some places to start:<br />
<br />
* The [[/Source|complete bot source]] (also [http://www.cse.unsw.edu.au/~dons/irc/bot.html mirrored here])<br />
* A [[/Transcript|full transcript]].<br />
* [[Haskell|Haskell.org]]<br />
* [[Example_code|More Haskell code]]<br />
* [[Books and tutorials|Learning Haskell]]<br />
* A gallery of [[Libraries_and_tools/Network|network apps]] in Haskell<br />
<br />
Or take the bot home and hack! Some suggestions:<br />
* Use <code>forkIO</code> to add a command line interface, and you've got yourself an irc client with 4 more lines of code.<br />
* Port some commands from [[Lambdabot]].<br />
<br />
Author: [http://www.cse.unsw.edu.au/~dons Don Stewart]<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Code]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Iteratee_I/O&diff=56464Iteratee I/O2013-07-26T21:50:45Z<p>Lambda Fairy: Minor fixes</p>
<hr />
<div>Iteratee I/O is a way to avoid the problems that can occur with lazy I/O. They work by making the I/O operations explicit, making their behavior easier to reason about.<br />
<br />
== The problem with lazy I/O ==<br />
<br />
As a beginner, you probably used Haskell's lazy I/O through the <code>System.IO</code> module. However, while it is good enough for simple programs, its unpredictability makes it unsuitable for practical use.<br />
<br />
For example, a common beginner mistake is to close a file before one has finished reading it:<br />
<br />
<haskell><br />
wrong = do<br />
fileData <- withFile "test.txt" ReadMode hGetContents<br />
putStr fileData<br />
</haskell><br />
<br />
The problem is <code>withFile</code> closes the handle before <code>fileData</code> is forced. The correct way is to pass all the code to <code>withFile</code>:<br />
<br />
<haskell><br />
right = withFile "test.txt" ReadMode $ \handle -> do<br />
fileData <- hGetContents handle<br />
putStr fileData<br />
</haskell><br />
<br />
Here, the data is consumed before <code>withFile</code> finishes.<br />
<br />
Although this is easily fixed, the type system does not enforce the correct solution. Even worse, if you use the former code, it won't even raise an error &ndash; it will just fail silently and return an empty string. Many years passed before a satisfactory solution to the ''streaming data problem'' was found.<br />
<br />
== How iteratees work ==<br />
<br />
When you "step" an iteratee, it reads a chunk of data, updates the internal state and returns a new iteratee along with the data it read. Because an iteratee is simply a function with state, many iteratees can be composed together to form a pipeline.<br />
<br />
Some implementations also provide a resource management layer that releases resources automatically when they are no longer needed. This is very useful in a server, where sockets and file handles are scarce.<br />
<br />
== Implementations ==<br />
<br />
; [http://hackage.haskell.org/package/iteratee iteratee] : The original iteratee library, by Oleg Kiselyov.<br />
; [http://hackage.haskell.org/package/iterIO iterIO] : Yet another implementation.<br />
; [http://hackage.haskell.org/package/enumerator enumerator] : Used in Snap. It does not use any extensions, so it will work with most Haskell compilers.<br />
; [http://hackage.haskell.org/package/pipes pipes] : Elegant streaming library with many unique features <br />
; [http://hackage.haskell.org/package/conduit conduit] : Popular implementation designed with practical use in mind, created by the author of Yesod. Recently heavily influenced by pipes.<br />
; [http://hackage.haskell.org/package/liboleg liboleg] : An evolving collection of Oleg Kiselyov's Haskell modules (depends on the package unix and will therefore not compile on Windows systems).<br />
; [http://hackage.haskell.org/package/io-streams io-streams] : Focuses on streaming IO and having a simpler type framework then the Conduit and Pipes packages.<br />
<br />
== Essays by Oleg ==<br />
<br />
* Oleg's writings: [http://okmij.org/ftp/Streams.html#iteratee Incremental multi-level input processing with left-fold enumerator: predictable, high-performance, safe, and elegant]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/Iteratee.hs An implementation by Oleg, iteratees on Chars and Strings]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/IterateeM.hs A general library by Oleg] <br />
<br />
== Other discussions ==<br />
<br />
* [http://johnlato.blogspot.sg/2012/06/understandings-of-iteratees.html Understandings of Iteratees]<br />
* [http://themonadreader.wordpress.com/2010/05/12/issue-16/ The Monad.Reader Issue 16]; see the section "Iteratee: Teaching an Old Fold New Tricks" by John W. Lato<br />
* [http://www.yesodweb.com/book/conduit Yesod Book: Conduits]<br />
* [http://sites.google.com/site/haskell/notes/lazy-io-considered-harmful-way-to-go-left-fold-enumerator Lazy IO considered harmful; way to go, Left-fold enumerator!]<br />
* [http://www.tiresiaspress.us/haskell/iteratee/ A Darcs repository of an alternative implementation]<br />
* [http://www.scs.stanford.edu/11au-cs240h/notes/iteratee.html Stanford CS240h lecture on iteratee]<br />
<br />
== Users of Iteratee I/O ==<br />
<br />
* [http://snapframework.com Snap]: The Snap web framework<br />
* [http://hackage.haskell.org/package/yaml yaml]: Low-level binding to the libyaml C library<br />
* [http://hackage.haskell.org/package/usb-0.4 usb 0.4]: Communicate with USB devices<br />
* [http://hackage.haskell.org/package/sstable sstable]: SSTables in Haskell<br />
* [http://hackage.haskell.org/package/wai WAI]: a Web Application Interface for haskell web frameworks (used by [http://www.yesodweb.com Yesod]).<br />
<br />
== See also ==<br />
<br />
* [[Enumerator and iteratee]]<br />
* [[Iteratee]]<br />
<br />
[[Category:Idioms]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Interfacing_other_languages&diff=56463Applications and libraries/Interfacing other languages2013-07-26T21:47:50Z<p>Lambda Fairy: Fix formatting</p>
<hr />
<div>{{unknown copyright}}<br />
{{LibrariesPage}}<br />
<br />
== Tools for interfacing with other languages ==<br />
<br />
Haskell builtin features for interfacing to other languages are formally defined in the<br />
[http://www.cse.unsw.edu.au/~chak/haskell/ffi/ Foreign Function Interface (FFI)]. You may learn it by example at the <br />
[http://haskell.org/haskellwiki/IO_inside#Interfacing_with_C.2FC.2B.2B_and_foreign_libraries_.28under_development.29 IO inside] guide.<br />
<br />
See also [[RPC | Web services and RPC]].<br />
<br />
The following tools and libraries either simplify interfacing to C or allow interfacing to other languages and environments (COM, JVM, Python, Tcl, Lua...).<br />
<br />
=== C ===<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ C-&gt;Haskell]<br />
:A lightweight tool for implementing access to C libraries from Haskell.<br />
<br />
;[http://hackage.haskell.org/package/c2hsc/ c2hsc]<br />
:A tool to create Bindings-DSL based interface files for C libraries.<br />
<br />
;[[HSFFIG]]<br />
:Haskell FFI Binding Modules Generator (HSFFIG) is a tool that takes a C library include file (.h) and generates Haskell Foreign Functions Interface import declarations for items (functions, structures, etc.) the header defines.<br />
<br />
;[http://www.astercity.net/~khaliff/haskell/kdirect/index.html KDirect]<br />
:A tool to simplify the process of interfacing C libraries to Haskell. It is less powerful than HaskellDirect, but easier to use and more portable.<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/libffi libffi]<br />
:A binding to libffi, allowing C functions of types only known at runtime to be called from Haskell.<br />
<br />
=== Java ===<br />
<br />
See [http://www.haskell.org/pipermail/haskell-cafe/2013-May/108299.html the discussion on Haskell Cafe].<br />
<br />
=== Python ===<br />
<br />
;[http://quux.org/devel/missingpy MissingPy]<br />
:MissingPy is really two libraries in one. At its lowest level, MissingPy is a library designed to make it easy to call into Python from Haskell. It provides full support for interpreting arbitrary Python code, interfacing with a good part of the Python/C API, and handling Python objects. It also provides tools for converting between Python objects and their Haskell equivalents. Memory management is handled for you, and Python exceptions get mapped to Haskell Dynamic exceptions. At a higher level, MissingPy contains Haskell interfaces to some Python modules.<br />
<br />
=== Others ===<br />
<br />
;[http://web.archive.org/web/20010306205042/http://www.numeric-quest.com/haskell/smartest.html Smarty]<br />
:An interface between Haskell and Squeak, a freely available Smalltalk language and environment.<br />
<br />
;[ftp://ftp.cs.york.ac.uk/pub/haskell/contrib/lp2fp.tar.gz]<br />
:lp2fp is a program-translator from Prolog to Haskell.<br />
<br />
;[http://haskell.org/haskellscript/ HaskellScript]<br />
:HaskellScript is the collective name for all Haskell components, both tools and libararies, that allow interaction with the COM/ActiveX framework.<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg04613.html TclHaskell]<br />
:TclHaskell is a haskell binding to Tcl-Tk that lets you build GUIs in Haskell. It is Haskell98 compliant. It has been tested under hugs98 and ghc-4.04.<br />
<br />
;[[CPlusPlusFromHaskell]]<br />
:A hackish method calling C++ from Haskell.<br />
<br />
;[http://www.mail-archive.com/haskell@haskell.org/msg20614.html Re: &#91;Haskell&#93; C++ bindings]. <br />
:An e-mail describing how to link to C++ <br />
<br />
;[[HsLua]]<br />
:Haskell interface to Lua scripting language (tested with GHC 6.6/6.8).<br />
<br />
;[[Salsa]]<br />
:An experimental .NET Bridge for Haskell.<br />
<br />
;[[/Erlang|Erlang]]<br />
:Impersonates an Erlang node on the network.<br />
<br />
=== Obsolete ===<br />
<br />
;[http://web.archive.org/web/20060411002808/http://www.reid-consulting-uk.ltd.uk/docs/ffi.html Guide to Haskell's Foreign Function Interface] <br />
:Comparision of the different tools.<br />
<br />
;[http://web.archive.org/web/20100905111116/http://www.haskell.org/greencard/ Green Card]<br />
: Green Card is a foreign function interface preprocessor for Haskell, simplifying the task of interfacing Haskell programs to external libraries (which are normally exposed via C interfaces). Green Card is currently able to generate code compatible with [[Implementations#The_Haskell_Interpreter_Hugs| Hugs]] and [[Implementations#nhc98 | nhc]]. Green Card is compatible with the [[Implementations#GHC_the_Glasgow_Haskell_Compiler | Glasgow Haskell Compiler]] (GHC), versions prior to 6.2. <br />
:Green Card is not compatible with GHC versions 6.2 and later because Green Card uses a deprecated form of Foreign Function Interface (FFI) binding, _casm_: such old-style bindings were removed in GHC version 6.2. See [http://www.mail-archive.com/haskell@haskell.org/msg14004.html ANNOUNCE: GHC version 6.2].<br />
<br />
;[http://web.archive.org/web/20100524024455/http://www.haskell.org/hdirect/ HaskellDirect]<br />
:HaskellDirect is an Interface Definition Language (IDL) compiler for Haskell, which helps interfacing Haskell code to libraries or components written in other languages (C). An IDL specification specifies the type signatures and types expected by a set of external functions. One important use of this language neutral specification of interfaces is to specify COM (Microsoft's Component Object Model) interfaces, and HaskellDirect offers special support for both using COM objects from Haskell and creating Haskell COM objects. HaskellDirect groks both the OSF DCE dialect of IDL (including the various extensions introduced by the Microsoft IDL compiler) and the OMG IIOP/CORBA dialect. '''Not compatible with recent versions of GHC (6.6.1)'''<br />
<br />
<br />
==== Java ====<br />
<br />
;[http://labs.businessobjects.com/cal/ CAL]<br />
:A hybrid language of Java and Haskell.<br />
<br />
;[http://www.haskell.org/gcjni GCJNI]<br />
:A Java Native Interface for Haskell. Allows Haskell to invoke Java code. Includes a tool to generate Haskell bindings for a Java library. Works for hugs and ghc under both Linux and Windows. (Based on Greencard, see above.)<br />
<br />
;[http://sourceforge.net/projects/jvm-bridge/ Haskell/Java VM Bridge]<br />
:A bridge to the Java virtual machine via JNI for Haskell.<br />
<br />
;[http://research.microsoft.com/en-us/um/people/emeijer/papers/lambada.pdf Lambada] (PDF)<br />
:A Haskell <=> Java interoperation bridge. Interoperation between Haskell and Java is provided by Lambada via the Java Native Interface (JNI), giving you a set of Haskell abstractions that lets you both call out to Java from Haskell *and* wrap up Haskell code behind a Java-callable veneer. '''Not compatible with recent versions of GHC (6.6.1)'''<br />
<br />
;[http://wiki.brianweb.net/LambdaVM/ LambdaVM]<br />
:A set of patches and additions to GHC that let GHC compile from Core to JVM bytecode. Also has a FFI for calling native Java libraries.</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Functor-Applicative-Monad_Proposal&diff=56118Functor-Applicative-Monad Proposal2013-06-03T02:09:28Z<p>Lambda Fairy: Add more things!</p>
<hr />
<div>The standard class hierarchy is a consequence of Haskell's historical development, rather than logic.<br />
<br />
This article attempts to document various suggestions that have been brought up over the years, along with arguments for and against.<br />
<br />
== Make <hask>Applicative</hask> a superclass of <hask>Monad</hask> ==<br />
<br />
<haskell><br />
class Applicative m => Monad m where<br />
...<br />
</haskell><br />
<br />
=== For ===<br />
<br />
* Code that is polymorphic over the Monad can use Applicative operators rather than the ugly <hask>liftM</hask> and <hask>ap</hask>.<br />
<br />
* Most types that implement Monad also implement Applicative already. This change will only make explicit a current best practice.<br />
<br />
=== Against ===<br />
<br />
* Monad is part of standard Haskell, but Applicative is not. If Monad is made a subclass of Applicative, then we will need to add Applicative to the language standard.<br />
<br />
* Some libraries, such as [http://hackage.haskell.org/packages/archive/blaze-markup/0.5.1.5/doc/html/Text-Blaze-Internal.html#t:MarkupM blaze-markup], only implement Monad for its do-notation. For these types, an Applicative instance would have no meaning.<br />
<br />
== Add <hask>join</hask> as a method of <hask>Monad</hask> ==<br />
<br />
<haskell><br />
class Applicative m => Monad m where<br />
(>>=) :: (a -> m b) -> m a -> m b<br />
join :: m (m a) -> m a<br />
...<br />
m >>= k = join (fmap k m)<br />
join m = m >>= id<br />
</haskell><br />
<br />
=== For ===<br />
<br />
* <hask>fmap</hask>/<hask>join</hask> is more orthogonal, and is closer to the categorical definition.<br />
<br />
* <hask>join</hask> is often easier to implement. See [http://article.gmane.org/gmane.comp.lang.haskell.libraries/14926].<br />
<br />
* The analogous [http://hackage.haskell.org/packages/archive/comonad/3.0.2/doc/html/Control-Comonad.html comonad] package is written this way.<br />
<br />
=== Against ===<br />
<br />
* <hask>>>=</hask> is used much more frequently in real-world code than <hask>join</hask>.<br />
<br />
* Performance: The default implementation of <hask>>>=</hask> requires two traversals. A container-like type which only implements <hask>join</hask> would most likely be slower.<br />
<br />
== Remove <hask>liftM</hask>, <hask>ap</hask>, etc. in favor of their Applicative counterparts ==<br />
<br />
=== For ===<br />
<br />
* We will end up with a simpler base library.<br />
<br />
=== Against ===<br />
<br />
* A lot of code will be broken by this change. Of course, we can gradually deprecate them as with <hask>Prelude.catch</hask>.<br />
<br />
* A common pattern is to write a full instance of Monad, then set <hask>fmap = liftM</hask> and <hask>(<*>) = ap</hask>. The functions are still useful for this purpose.<br />
<br />
== Split <hask>fail</hask> into its own class ==<br />
<br />
<haskell><br />
class Monad m => MonadFail m where<br />
fail :: String -> m a<br />
</haskell><br />
<br />
== Rename <hask>fmap</hask> to <hask>map</hask> ==<br />
<br />
<haskell><br />
class Functor f where<br />
map :: (a -> b) -> f a -> f b<br />
</haskell><br />
<br />
== Export <hask>Applicative</hask> in the Prelude ==<br />
<br />
== Redefine <hask>>></hask> in terms of <hask>*></hask> rather than <hask>>>=</hask> ==<br />
<br />
== Add a <hask>Pointed</hask> class ==<br />
<br />
<haskell><br />
class Pointed p where<br />
point :: a -> p a<br />
</haskell><br />
<br />
This is already implemented in the [http://hackage.haskell.org/package/pointed pointed] package.<br />
<br />
=== For ===<br />
<br />
=== Against ===<br />
<br />
* This class has seen little real-world use. On Hackage, there are only [http://packdeps.haskellers.com/reverse/pointed 9 reverse dependencies] for <code>pointed</code>, most of which are by the same author.<br />
<br />
== Related proposals ==<br />
<br />
* From early 2011: [http://hackage.haskell.org/trac/ghc/ticket/4834 GHC ticket] &ndash; Makes Applicative into a superclass of Monad, but does not deprecate any existing names<br />
** See [http://thread.gmane.org/gmane.comp.lang.haskell.libraries/14883/focus=14905] for the associated discussion.<br />
* [[The Other Prelude]]<br />
<br />
[[Context alias]] would also be a great help with backwards compatibility. The [[class system extension proposal]] may also help.<br />
<br />
[[Category:Proposals]]<br />
[[Category:Functor]]<br />
[[Category:Applicative Functor]]<br />
[[Category:Monad]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Functor-Applicative-Monad_Proposal&diff=56117Functor-Applicative-Monad Proposal2013-06-03T02:05:08Z<p>Lambda Fairy: Rewrite the page!</p>
<hr />
<div>The standard class hierarchy is a consequence of Haskell's historical development, rather than logic.<br />
<br />
This article attempts to document various suggestions that have been brought up over the years, along with arguments for and against.<br />
<br />
== Make <hask>Applicative</hask> a superclass of <hask>Monad</hask> ==<br />
<br />
<haskell><br />
class Applicative m => Monad m where<br />
...<br />
</haskell><br />
<br />
=== For ===<br />
<br />
* Code that is polymorphic over the Monad can use Applicative operators rather than the ugly <hask>liftM</hask> and <hask>ap</hask>.<br />
<br />
* Most types that implement Monad also implement Applicative already. This change will only make explicit a current best practice.<br />
<br />
=== Against ===<br />
<br />
* Monad is part of standard Haskell, but Applicative is not. If Monad is made a subclass of Applicative, then we will need to add Applicative to the language standard.<br />
<br />
* Some libraries, such as [http://hackage.haskell.org/packages/archive/blaze-markup/0.5.1.5/doc/html/Text-Blaze-Internal.html#t:MarkupM blaze-markup], only implement Monad for its do-notation. For these types, an Applicative instance would have no meaning.<br />
<br />
== Add <hask>join</hask> as a method of <hask>Monad</hask> ==<br />
<br />
<haskell><br />
class Applicative m => Monad m where<br />
(>>=) :: (a -> m b) -> m a -> m b<br />
join :: m (m a) -> m a<br />
...<br />
m >>= k = join (fmap k m)<br />
join m = m >>= id<br />
</haskell><br />
<br />
=== For ===<br />
<br />
* <hask>fmap</hask>/<hask>join</hask> is more orthogonal than <hask>fmap</hask>/<hask>>>=</hask>, and the former is closer to the categorical definition.<br />
<br />
* <hask>join</hask> is often easier to implement. See [http://article.gmane.org/gmane.comp.lang.haskell.libraries/14926].<br />
<br />
* The analogous [http://hackage.haskell.org/packages/archive/comonad/3.0.2/doc/html/Control-Comonad.html comonad] package is written this way.<br />
<br />
=== Against ===<br />
<br />
* <hask>>>=</hask> is used much more frequently in real-world code than <hask>join</hask>.<br />
<br />
* Performance: The default implementation of <hask>>>=</hask> requires two traversals. Any container-like type which only implements <hask>fmap</hask> and <hask>join</hask> would be slower.<br />
<br />
== Remove <hask>liftM</hask>, <hask>ap</hask>, etc. in favor of their Applicative counterparts ==<br />
<br />
=== For ===<br />
<br />
* We will end up with a simpler base library.<br />
<br />
=== Against ===<br />
<br />
* A lot of code will be broken by this change. There is no compelling reason to remove these functions outright, rather than gradually deprecating them as with <hask>Prelude.catch</hask>.<br />
<br />
* A common pattern is to write a full instance of Monad, then set <hask>fmap = liftM</hask> and <hask>(<*>) = ap</hask>.<br />
<br />
== Split <hask>fail</hask> into its own class ==<br />
<br />
<haskell><br />
class Monad m => MonadFail m where<br />
fail :: String -> m a<br />
</haskell><br />
<br />
== Rename <hask>fmap</hask> to <hask>map</hask> ==<br />
<br />
== Export <hask>Applicative</hask> in the Prelude ==<br />
<br />
== Redefine <hask>>></hask> in terms of <hask>*></hask> rather than <hask>>>=</hask> ==<br />
<br />
== Add a <hask>Pointed</hask> class ==<br />
<br />
<haskell><br />
class Pointed p where<br />
point :: a -> p a<br />
</haskell><br />
<br />
This is already implemented in the [http://hackage.haskell.org/package/pointed pointed] package.<br />
<br />
=== For ===<br />
<br />
=== Against ===<br />
<br />
* This class has seen little real-world use. On Hackage, there are only [http://packdeps.haskellers.com/reverse/pointed 9 reverse dependencies] for <code>pointed</code>, most of which are by the same author.<br />
<br />
== Related proposals ==<br />
<br />
* From early 2011: [http://hackage.haskell.org/trac/ghc/ticket/4834 GHC ticket] &ndash; Makes Applicative into a superclass of Monad, but does not deprecate any existing names<br />
** See [http://thread.gmane.org/gmane.comp.lang.haskell.libraries/14883/focus=14905] for the associated discussion.<br />
* [[The Other Prelude]]<br />
<br />
[[Context alias]] would also be a great help with backwards compatibility. The [[class system extension proposal]] may also help.<br />
<br />
[[Category:Proposals]]<br />
[[Category:Functor]]<br />
[[Category:Applicative Functor]]<br />
[[Category:Monad]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Iteratee_I/O&diff=46511Iteratee I/O2012-07-12T02:21:46Z<p>Lambda Fairy: /* Other discussions */ Fixed Yesod link</p>
<hr />
<div>Iteratee I/O is a way to avoid the problems that can occur with lazy I/O. They work by making the I/O actions explicit, making their behavior easier to reason about.<br />
<br />
== The problem with lazy I/O ==<br />
<br />
As a beginner, you probably used Haskell's lazy I/O through the <code>System.IO</code> module. However, while it is good enough for simple programs, its unpredictability makes it unsuitable for practical use.<br />
<br />
For example, a common beginner mistake is to close a file before one has finished reading it:<br />
<br />
<haskell><br />
wrong = do<br />
fileData <- withFile "test.txt" ReadMode hGetContents<br />
putStr fileData<br />
</haskell><br />
<br />
The problem is <code>withFile</code> closes the handle before <code>fileData</code> is forced. The correct way is to pass all the code to <code>withFile</code>:<br />
<br />
<haskell><br />
right = withFile "test.txt" ReadMode $ \handle -> do<br />
fileData <- hGetContents handle<br />
putStr fileData<br />
</haskell><br />
<br />
Here, the data is consumed before <code>withFile</code> finishes.<br />
<br />
Although this is easily fixed, the type system does not enforce the correct solution. Even worse, if you use the former code, it won't even raise an error &ndash; it will just fail silently and return an empty string. Many years passed before a satisfactory solution to the ''streaming data problem'' was found.<br />
<br />
== How iteratees work ==<br />
<br />
When you "step" an iteratee, it reads a chunk of data, updates the internal state and returns a new iteratee along with the data it read. Because an iteratee is simply a function with state, many iteratees can be composed together to form a pipeline.<br />
<br />
Some implementations also provide a resource management layer that releases resources automatically when they are no longer needed. This is very useful in a server, where sockets and file handles are scarce.<br />
<br />
== Implementations ==<br />
<br />
; [http://hackage.haskell.org/package/iteratee iteratee] : The original iteratee library, by Oleg Kiselyov.<br />
; [http://hackage.haskell.org/package/iterIO iterIO] : Yet another implementation.<br />
; [http://hackage.haskell.org/package/enumerator enumerator] : Used in Snap. It does not use any extensions, so it will work with most Haskell compilers.<br />
; [http://hackage.haskell.org/package/pipes pipes] : A more recent implementation, which strives to be more elegant than existing libraries.<br />
; [http://hackage.haskell.org/package/pipes-core pipes-core] : Fork of pipes which adds resource finalization.<br />
; [http://hackage.haskell.org/package/conduit conduit] : Popular implementation designed with practical use in mind, created by the author of Yesod. Recently heavily influenced by pipes.<br />
; [http://hackage.haskell.org/package/liboleg liboleg] : An evolving collection of Oleg Kiselyov's Haskell modules (depends on the package unix and will therefore not compile on Windows systems).<br />
<br />
== Essays by Oleg ==<br />
<br />
* Oleg's writings: [http://okmij.org/ftp/Streams.html#iteratee Incremental multi-level input processing with left-fold enumerator: predictable, high-performance, safe, and elegant]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/Iteratee.hs An implementation by Oleg, iteratees on Chars and Strings]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/IterateeM.hs A general library by Oleg] <br />
<br />
== Other discussions ==<br />
<br />
* [http://themonadreader.wordpress.com/2010/05/12/issue-16/ The Monad.Reader Issue 16]; see the section "Iteratee: Teaching an Old Fold New Tricks" by John W. Lato<br />
* [http://www.yesodweb.com/book/conduit Yesod Book: Conduits]<br />
* [http://sites.google.com/site/haskell/notes/lazy-io-considered-harmful-way-to-go-left-fold-enumerator Lazy IO considered harmful; way to go, Left-fold enumerator!]<br />
* [http://www.tiresiaspress.us/haskell/iteratee/ A Darcs repository of an alternative implementation]<br />
* [http://www.scs.stanford.edu/11au-cs240h/notes/iteratee.html Stanford CS240h lecture on iteratee]<br />
<br />
== Users of Iteratee I/O ==<br />
<br />
* [http://snapframework.com Snap]: The Snap web framework<br />
* [http://hackage.haskell.org/package/yaml yaml]: Low-level binding to the libyaml C library]<br />
* [http://hackage.haskell.org/package/usb-0.4 usb 0.4]: Communicate with USB devices<br />
* [http://hackage.haskell.org/package/sstable sstable]: SSTables in Haskell<br />
* [http://hackage.haskell.org/package/wai WAI]: a Web Application Interface for haskell web frameworks (used by [http://www.yesodweb.com Yesod]).<br />
<br />
== See also ==<br />
<br />
* [[Enumerator and iteratee]]<br />
* [[Iteratee]]<br />
<br />
[[Category:Idioms]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Iteratee_I/O&diff=46510Iteratee I/O2012-07-12T02:20:27Z<p>Lambda Fairy: Described iteratees</p>
<hr />
<div>Iteratee I/O is a way to avoid the problems that can occur with lazy I/O. They work by making the I/O actions explicit, making their behavior easier to reason about.<br />
<br />
== The problem with lazy I/O ==<br />
<br />
As a beginner, you probably used Haskell's lazy I/O through the <code>System.IO</code> module. However, while it is good enough for simple programs, its unpredictability makes it unsuitable for practical use.<br />
<br />
For example, a common beginner mistake is to close a file before one has finished reading it:<br />
<br />
<haskell><br />
wrong = do<br />
fileData <- withFile "test.txt" ReadMode hGetContents<br />
putStr fileData<br />
</haskell><br />
<br />
The problem is <code>withFile</code> closes the handle before <code>fileData</code> is forced. The correct way is to pass all the code to <code>withFile</code>:<br />
<br />
<haskell><br />
right = withFile "test.txt" ReadMode $ \handle -> do<br />
fileData <- hGetContents handle<br />
putStr fileData<br />
</haskell><br />
<br />
Here, the data is consumed before <code>withFile</code> finishes.<br />
<br />
Although this is easily fixed, the type system does not enforce the correct solution. Even worse, if you use the former code, it won't even raise an error &ndash; it will just fail silently and return an empty string. Many years passed before a satisfactory solution to the ''streaming data problem'' was found.<br />
<br />
== How iteratees work ==<br />
<br />
When you "step" an iteratee, it reads a chunk of data, updates the internal state and returns a new iteratee along with the data it read. Because an iteratee is simply a function with state, many iteratees can be composed together to form a pipeline.<br />
<br />
Some implementations also provide a resource management layer that releases resources automatically when they are no longer needed. This is very useful in a server, where sockets and file handles are scarce.<br />
<br />
== Implementations ==<br />
<br />
; [http://hackage.haskell.org/package/iteratee iteratee] : The original iteratee library, by Oleg Kiselyov.<br />
; [http://hackage.haskell.org/package/iterIO iterIO] : Yet another implementation.<br />
; [http://hackage.haskell.org/package/enumerator enumerator] : Used in Snap. It does not use any extensions, so it will work with most Haskell compilers.<br />
; [http://hackage.haskell.org/package/pipes pipes] : A more recent implementation, which strives to be more elegant than existing libraries.<br />
; [http://hackage.haskell.org/package/pipes-core pipes-core] : Fork of pipes which adds resource finalization.<br />
; [http://hackage.haskell.org/package/conduit conduit] : Popular implementation designed with practical use in mind, created by the author of Yesod. Recently heavily influenced by pipes.<br />
; [http://hackage.haskell.org/package/liboleg liboleg] : An evolving collection of Oleg Kiselyov's Haskell modules (depends on the package unix and will therefore not compile on Windows systems).<br />
<br />
== Essays by Oleg ==<br />
<br />
* Oleg's writings: [http://okmij.org/ftp/Streams.html#iteratee Incremental multi-level input processing with left-fold enumerator: predictable, high-performance, safe, and elegant]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/Iteratee.hs An implementation by Oleg, iteratees on Chars and Strings]<br />
* [http://okmij.org/ftp/Haskell/Iteratee/IterateeM.hs A general library by Oleg] <br />
<br />
== Other discussions ==<br />
<br />
* [http://themonadreader.wordpress.com/2010/05/12/issue-16/ The Monad.Reader Issue 16]; see the section "Iteratee: Teaching an Old Fold New Tricks" by John W. Lato<br />
* [http://www.yesodweb.com/book/enumerator Yesod Book: Enumerator Package]<br />
* [http://sites.google.com/site/haskell/notes/lazy-io-considered-harmful-way-to-go-left-fold-enumerator Lazy IO considered harmful; way to go, Left-fold enumerator!]<br />
* [http://www.tiresiaspress.us/haskell/iteratee/ A Darcs repository of an alternative implementation]<br />
* [http://www.scs.stanford.edu/11au-cs240h/notes/iteratee.html Stanford CS240h lecture on iteratee]<br />
<br />
== Users of Iteratee I/O ==<br />
<br />
* [http://snapframework.com Snap]: The Snap web framework<br />
* [http://hackage.haskell.org/package/yaml yaml]: Low-level binding to the libyaml C library]<br />
* [http://hackage.haskell.org/package/usb-0.4 usb 0.4]: Communicate with USB devices<br />
* [http://hackage.haskell.org/package/sstable sstable]: SSTables in Haskell<br />
* [http://hackage.haskell.org/package/wai WAI]: a Web Application Interface for haskell web frameworks (used by [http://www.yesodweb.com Yesod]).<br />
<br />
== See also ==<br />
<br />
* [[Enumerator and iteratee]]<br />
* [[Iteratee]]<br />
<br />
[[Category:Idioms]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Performance/IO&diff=46509Performance/IO2012-07-12T02:13:51Z<p>Lambda Fairy: Updated with iteratees</p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|IO]]<br />
<br />
Before continuing, I strongly recommend reading [[Performance/Strings]] first. Fast I/O and string handling overlap in many places, so this page will only discuss the parts that are not specific to strings.<br />
<br />
== Iteratee I/O ==<br />
<br />
[[Iteratee I/O|Iteratees]] are a relatively new approach to streaming I/O. If your code uses I/O extensively (for example, in a web server), iteratees are the best way to do it.<br />
<br />
Using the [http://hackage.haskell.org/package/conduit Conduit] library, a program to read a file and pipe it to stdout can be written as follows:<br />
<br />
<haskell><br />
main = runResourceT (sourceFile "test.txt" $$ sinkHandle stdout)<br />
</haskell><br />
<br />
== Other solutions ==<br />
<br />
If this is too high-level for you,<br />
buffer-based IO is an alternative (<code>hGetBuf</code>/<code>hPutBuf</code>). This can be<br />
particularly effective when combined with packed strings (see [[wc]]). <br />
<br />
Some external libraries also provide memory mapped IO.<br />
<br />
In 2006, someone came up with a solution called [[Library/Streams|Streams]]. However, it does not seem to be maintained anymore.</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Euler_problems&diff=45641Euler problems2012-05-12T05:51:35Z<p>Lambda Fairy: Removed "answers" link. Currently Euler answers redirects back to this page anyway.</p>
<hr />
<div>These are solutions to the problems listed on [http://projecteuler.net/index.php?section=view Project Euler].<br />
<br />
'''WARNING''' - Do not peek at any of these pages if you want to enjoy the<br />
benefits of Project Euler, unless you have already solved the problems.<br />
<br />
The existence of these pages is very controversial; see the [[Talk:Euler problems|talk page]] for discussion. Many P.E. participants regard it as a global Internet competition which is being compromised by these readily available solutions, and some other sites hide their solution methods so that only those who know the answer can view them. The FAQ on the [http://www.projecteuler.net/ front page of the Project Euler site] says the following, which appears to be a reference to pages such as this one:<br />
<br />
<blockquote><br />
<p><em>I solved it by using a search engine, does that matter?</em></p><br />
<p>That depends on your motivation for solving the problems. It probably means that you've missed out on some beautiful and hidden mathematics.</p><br />
</blockquote><br />
<br />
In any case, it is recommended that you try the problems yourself before looking<br />
at the solutions. These are great exercises for improving your Haskell-fu, and reading the solutions beforehand could spoil the experience of solving them yourself.<br />
<br />
Any further reading is at your own risk.<br />
<br />
* [[Euler problems/1 to 10|Questions 1 to 10]]<br />
* [[Euler problems/11 to 20|Questions 11 to 20]]<br />
* [[Euler problems/21 to 30|Questions 21 to 30]]<br />
* [[Euler problems/31 to 40|Questions 31 to 40]]<br />
* [[Euler problems/41 to 50|Questions 41 to 50]]<br />
* [[Euler problems/51 to 60|Questions 51 to 60]]<br />
* [[Euler problems/61 to 70|Questions 61 to 70]]<br />
* [[Euler problems/71 to 80|Questions 71 to 80]]<br />
* [[Euler problems/81 to 90|Questions 81 to 90]]<br />
* [[Euler problems/91 to 100|Questions 91 to 100]]<br />
* [[Euler problems/101 to 110|Questions 101 to 110]]<br />
* [[Euler problems/111 to 120|Questions 111 to 120]]<br />
* [[Euler problems/121 to 130|Questions 121 to 130]]<br />
* [[Euler problems/131 to 140|Questions 131 to 140]]<br />
* [[Euler problems/141 to 150|Questions 141 to 150]]<br />
* [[Euler problems/151 to 160|Questions 151 to 160]]<br />
* [[Euler problems/161 to 170|Questions 161 to 170]]<br />
* [[Euler problems/171 to 180|Questions 171 to 180]]<br />
* [[Euler problems/181 to 190|Questions 181 to 190]]<br />
* [[Euler problems/191 to 200|Questions 191 to 200]]<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Code]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Performance/Strictness&diff=45640Performance/Strictness2012-05-12T05:06:46Z<p>Lambda Fairy: Fixed inconsistent capitalization; minor typos</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 <code-haskell>Int</code-haskell> can be passed as an unboxed value, for example. Strictness analysis sometimes does wonderful things; for example it is very good at optimising <code-haskell>fac</code-haskell>:<br />
<pre-haskell><br />
fac :: Int -> Int<br />
fac n = if n <= 1 then 1 else n * fac (n-1)<br />
</pre-haskell><br />
<br />
Strictness analysis can spot the fact that the argument <code-haskell>n</code-haskell> 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 />
<pre-haskell><br />
main = print (foldl (+) 0 [1..1000000])<br />
</pre-haskell><br />
is compiled in GHC without "-O" flag, it uses a lot of heap and stack. A programmer knows that the long list (<code-haskell>[1..1000000]</code-haskell>) is stored as a thunk, not fully, because the programmer read about [[non-strict semantics]] and [[lazy vs. non-strict]]. The programmer explicitly wrote <code-haskell>sum</code-haskell> 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 />
<pre-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 />
</pre-haskell><br />
<br />
<code-haskell>lgo</code-haskell>, instead of adding elements of the long list, creates '''a thunk''' for <code-haskell>(f z x)</code-haskell>. <code-haskell>z</code-haskell> is stored within that thunk, and <code-haskell>z</code-haskell> is a thunk also, created during the previous call to <code-haskell>lgo</code-haskell>. The program creates the long chain of thunks. Stack is bloated when evaluating that chain.<br />
<br />
With "-O" flag GHC performs strictness analysis, than it knows that <code-haskell>lgo</code-haskell> is strict in <code-haskell>z</code-haskell> 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 />
<pre-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 />
</pre-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 <code-haskell>acc</code-haskell> isn't strict, because there's no guarantee that the caller will evaluate it. The compiler will use a fully boxed <code-haskell>Int</code-haskell> to represent <code-haskell>acc</code-haskell>, although it will probably use an unboxed <code-haskell>Int</code-haskell> to represent <code-haskell>len</code-haskell>. The expression <code-haskell>(acc+x)</code-haskell> 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 <code-haskell>foldl</code-haskell> example, replace <code-haskell>foldl</code-haskell> with <code-haskell>foldl'</code-haskell>.<br />
<br />
For <code-haskell>suminit</code-haskell>, we need to make <code-haskell>acc</code-haskell> strict. The way to do this is using <code-haskell>seq</code-haskell>:<br />
<pre-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 />
</pre-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 BangPatterns GHC extension enabled (either explicitly or with "-fglasgow-exts"), the above can be written as<br />
<pre-haskell><br />
suminit xs !len !acc = …<br />
</pre-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 <code-haskell>($)</code-haskell> that evaluates its argument strictly: <code-haskell>($!)</code-haskell>. This can often be used to great effect in eliminating unnecessary suspensions that the compiler hasn't spotted. eg. in a function application<br />
<pre-haskell><br />
f (g x)<br />
</pre-haskell><br />
writing instead<br />
<pre-haskell><br />
f $! (g x)<br />
</pre-haskell><br />
will be more efficient if (a) you were going to evaluate <code-haskell>(g x)</code-haskell> anyway, and (b) <code-haskell>f</code-haskell> isn't visibly strict, or inlined. If <code-haskell>f</code-haskell> is strict or inlined, then the chances are that <code-haskell>($!)</code-haskell> is unnecessary cruft here.<br />
<br />
A good example is the monadic return. If you find yourself writing<br />
<pre-haskell><br />
do …<br />
…<br />
return (fn x)<br />
</pre-haskell><br />
<br />
then consider instead writing<br />
<pre-haskell><br />
do …<br />
…<br />
return $! fn x<br />
</pre-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 <code-haskell>f</code-haskell> with argument <code-haskell>x</code-haskell> satisfies both conditions:<br />
* <code-haskell>f</code-haskell> calls a function on a function of <code-haskell>x</code-haskell>: <code-haskell>(h (g x))</code-haskell><br />
* is not already strict in <code-haskell>x</code-haskell> (does not inspect <code-haskell>x</code-haskell>'s value), <br />
then it can be helpful to force evaluation:<br />
<br />
Example:<br />
<pre-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 />
</pre-haskell></div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Continuation&diff=43631Continuation2011-12-17T00:17:24Z<p>Lambda Fairy: /* Continuation monad */ Fixed Haddock link</p>
<hr />
<div>__TOC__<br />
<br />
== General or introductory materials ==<br />
<br />
=== Powerful metaphors, images ===<br />
<br />
Here is a collection of short descriptions, analogies or metaphors, that illustrate this difficult concept, or an aspect of it.<br />
<br />
==== Imperative metaphors ====<br />
<br />
* In computing, a continuation is a representation of the execution state of a program (for example, the call stack) at a certain point in time (Wikipedia's [http://en.wikipedia.org/wiki/Continuation Continuation]).<br />
* At its heart, <code>call/cc</code> is something like the <code>goto</code> instruction (or rather, like a label for a <code>goto</code> instruction); but a Grand High Exalted <code>goto</code> instruction... The point about <code>call/cc</code> is that it is not a ''static'' (lexical) <code>goto</code> instruction but a ''dynamic'' one (David Madore's [http://www.madore.org/~david/computers/callcc.html#sec_intro A page about <code>call/cc</code>])<br />
<br />
==== Functional metaphors ====<br />
<br />
* Continuations represent the future of a computation, as a function from an intermediate result to the final result ([http://www.haskell.org/all_about_monads/html/contmonad.html#motivation Continuation monad] section in Jeff Newbern's All About Monads)<br />
* The idea behind CPS is to pass around as a function argument what to do next ([http://darcs.haskell.org/yaht/yaht.pdf Yet Another Haskell Tutorial] written by Hal Daume III, 4.6 Continuation Passing Style, pp 53-56). [http://en.wikibooks.org/wiki/Haskell/YAHT/Type_basics#Continuation_Passing_Style It can be read also in wikified format].<br />
* Rather than return the result of a function, pass one or more [[Higher order function | Higher Order Functions]] to determine what to do with the result. Yes, direct sum like things (or in generally, case analysis, managing cases, alternatives) can be implemented in CPS by passing ''more'' continuations.<br />
<br />
=== External links ===<br />
<br />
* [http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style The appropriate section of Haskell: Functional Programming with Types].<br />
* Wikipedia's [http://en.wikipedia.org/wiki/Continuation Continuation] is a surprisingly good introductory material on this topic. See also [http://en.wikipedia.org/wiki/Continuation-passing_style Continuation-passing style].<br />
* [http://darcs.haskell.org/yaht/yaht.pdf Yet Another Haskell Tutorial] written by Hal Daume III contains a section on continuation passing style (4.6 Continuation Passing Style, pp 53-56). [http://en.wikibooks.org/wiki/Haskell/YAHT/Type_basics#Continuation_Passing_Style It can be read also in wikified format], thanks to Eric Kow.<br />
* David Madore's [http://www.madore.org/~david/computers/callcc.html A page about <code>call/cc</code>] describes the concept, and his [http://www.madore.org/~david/programs/unlambda/ The Unlambda Programming Language] page shows how he implemented this construct in an esoteric functional programming language.<br />
* [http://www.defmacro.org/ramblings/fp.html#part_9 Continuations] section of article [http://www.defmacro.org/ramblings/fp.html Functional Programming For The Rest of Us], an introductory material to functional programming.<br />
* [http://okmij.org/ftp/Computation/Continuations.html Continuations and delimited control]<br />
<br />
== Examples ==<br />
<br />
=== Citing haskellized Scheme examples from Wikipedia ===<br />
<br />
Quoting the Scheme examples (with their explanatory texts) from Wikipedia's [http://en.wikipedia.org/wiki/Continuation-passing_style#Examples Continuation-passing style] article, but Scheme examples are translated to Haskell, and some straightforward modifications are made to the explanations (e.g. replacing word ''Scheme'' with ''Haskell'', or using abbreviated name <hask>fac</hask> instead of <code>factorial</code>).<br />
<br />
In the Haskell programming language, the simplest of direct-style functions is the identity function: <br />
<br />
<haskell><br />
id :: a -> a<br />
id a = a<br />
</haskell><br />
<br />
which in CPS becomes:<br />
<br />
<haskell><br />
idCPS :: a -> (a -> r) -> r<br />
idCPS a ret = ret a<br />
</haskell><br />
where <hask>ret</hask> is the continuation argument (often also called <hask>k</hask>). A further comparison of direct and CPS style is below.<br />
{|<br />
!<center>Direct style</center>!!<center>Continuation passing style</center><br />
|-<br />
|<br />
<haskell><br />
mysqrt :: Floating a => a -> a<br />
mysqrt a = sqrt a<br />
print (mysqrt 4) :: IO ()<br />
</haskell><br />
||<br />
<haskell><br />
mysqrtCPS :: a -> (a -> r) -> r<br />
mysqrtCPS a k = k (sqrt a)<br />
mysqrtCPS 4 print :: IO ()<br />
</haskell><br />
|-<br />
|<br />
<haskell><br />
mysqrt 4 + 2 :: Floating a => a<br />
</haskell><br />
||<br />
<haskell><br />
mysqrtCPS 4 (+ 2) :: Floating a => a<br />
</haskell><br />
|-<br />
|<br />
<haskell><br />
fac :: Integral a => a -> a<br />
fac 0 = 1<br />
fac n'@(n + 1) = n' * fac n<br />
fac 4 + 2 :: Integral a => a<br />
</haskell><br />
||<br />
<haskell><br />
facCPS :: a -> (a -> r) -> r<br />
facCPS 0 k = k 1<br />
facCPS n'@(n + 1) k = facCPS n $ \ret -> k (n' * ret)<br />
facCPS 4 (+ 2) :: Integral a => a<br />
</haskell><br />
|}<br />
<br />
The translations shown above show that CPS is a global transformation; the direct-style factorial, <hask>fac</hask> takes, as might be expected, a single argument. The CPS factorial, <hask>facCPS</hask> takes two: the argument and a continuation. Any function calling a CPS-ed function must either provide a new continuation or pass its own; any calls from a CPS-ed function to a non-CPS function will use implicit continuations. Thus, to ensure the total absence of a function stack, the entire program must be in CPS.<br />
<br />
As an exception, <hask>mysqrt</hask> calls <hask>sqrt</hask> without a continuation &mdash; here <hask>sqrt</hask> is considered a primitive [http://en.wikipedia.org/wiki/Operator_%28programming%29 operator]; that is, it is assumed that <hask>sqrt</hask> will compute its result in finite time and without abusing the stack. Operations considered primitive for CPS tend to be arithmetic, constructors, accessors, or mutators; any [http://en.wikipedia.org/wiki/Big_O_notation O(1) operation] will be considered primitive.<br />
<br />
The quotation ends here.<br />
<br />
=== Intermediate structures ===<br />
<br />
The function <hask>Foreign.C.String.withCString</hask> converts a Haskell string to a C string.<br />
But it does not provide it for external use but restricts the use of the C string to a sub-procedure,<br />
because it will cleanup the C string after its use.<br />
It has signature <hask>withCString :: String -> (CString -> IO a) -> IO a</hask>.<br />
This looks like continuation and the functions from continuation monad can be used,<br />
e.g. for allocation of a whole array of pointers:<br />
<haskell><br />
multiCont :: [(r -> a) -> a] -> ([r] -> a) -> a<br />
multiCont xs = runCont (mapM Cont xs)<br />
<br />
withCStringArray0 :: [String] -> (Ptr CString -> IO a) -> IO a<br />
withCStringArray0 strings act =<br />
multiCont<br />
(map withCString strings)<br />
(\rs -> withArray0 nullPtr rs act)<br />
</haskell><br />
However, the right associativity of <hask>mapM</hask> leads to inefficiencies here.<br />
<br />
See:<br />
* Cale Gibbard in Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2008-February/038963.html A handy little consequence of the Cont monad]<br />
<br />
=== More general examples ===<br />
<br />
Maybe it is confusing, that<br />
* the type of the (non-continuation) argument of the discussed functions (<hask>idCPS</hask>, <hask>mysqrtCPS</hask>, <hask>facCPS</hask>)<br />
* and the type of the argument of the continuations<br />
coincide in the above examples. It is not a necessity (it does not belong to the essence of the continuation concept), so I try to figure out an example which avoids this confusing coincidence:<br />
<haskell><br />
newSentence :: Char -> Bool<br />
newSentence = flip elem ".?!"<br />
<br />
newSentenceCPS :: Char -> (Bool -> r) -> r<br />
newSentenceCPS c k = k (elem c ".?!")<br />
</haskell><br />
but this is a rather uninteresting example. Let us see another one that uses at least recursion:<br />
<haskell><br />
mylength :: [a] -> Integer<br />
mylength [] = 0<br />
mylength (_ : as) = succ (mylength as)<br />
<br />
mylengthCPS :: [a] -> (Integer -> r) -> r<br />
mylengthCPS [] k = k 0<br />
mylengthCPS (_ : as) k = mylengthCPS as (k . succ)<br />
<br />
test8 :: Integer<br />
test8 = mylengthCPS [1..2006] id<br />
<br />
test9 :: IO ()<br />
test9 = mylengthCPS [1..2006] print<br />
</haskell><br />
<br />
You can download the Haskell source code (the original examples plus the new ones): [[Media:Continuation.hs|Continuation.hs]].<br />
<br />
== Continuation monad ==<br />
<br />
* Jeff Newbern's [http://haskell.org/all_about_monads/html/index.html All About Monads] contains a [http://haskell.org/all_about_monads/html/contmonad.html section] on it.<br />
* [http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Cont.html Control.Monad.Cont] is contained by Haskell Hierarchical Libraries.<br />
<br />
== Delimited continuation ==<br />
<br />
* [[Library/CC-delcont]]<br />
* [http://okmij.org/ftp/Computation/Continuations.html#zipper Generic Zipper and its applications], writing that "[[Zipper]] can be viewed as a [[Library/CC-delcont|delimited continuation]] reified as a data structure" (links added).<br />
<br />
== Linguistics ==<br />
<br />
Chris Barker: [http://www.cs.bham.ac.uk/~hxt/cw04/barker.pdf Continuations in Natural Language]<br />
<br />
== Applications ==<br />
<br />
;[http://okmij.org/ftp/Computation/Continuations.html#zipper-fs ZipperFS] <br />
:Oleg Kiselyov's [[zipper]]-based [[Libraries and tools/Operating system|file server/OS]] where threading and exceptions are all realized via [[Library/CC-delcont|delimited continuation]]s.<br />
<br />
[[Category:Idioms]]<br />
[[Category:Glossary]]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Talk:Xmonad/Frequently_asked_questions&diff=43347Talk:Xmonad/Frequently asked questions2011-12-04T01:09:18Z<p>Lambda Fairy: </p>
<hr />
<div>I would like to see here 3.5 and 3.5.1 (if it's possible) applied only to one workspace. Thanks<br />
<br />
What do others think about linking from 4.7 to http://awesome.naquadah.org/wiki/Urxvt_Hints ? Questions with regard to artifacts in urxvt are asked often in #xmonad.<br />
<br />
== Re: "4.12.5 Use JDK 7" ==<br />
<br />
I've tried both OpenJDK 7 and Oracle JDK 7u1 with Xmonad 0.9.2 and Java apps still show the grey screen. Should I change the FAQ? [[User:Lambda Fairy|Lambda Fairy]] 01:09, 4 December 2011 (UTC)</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Memoization&diff=43346Memoization2011-12-04T01:03:37Z<p>Lambda Fairy: /* Memoising CAFS */ Fixed link</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 =<br />
let fib 0 = 0<br />
fib 1 = 1<br />
fib n = memoized_fib (n-2) + memoized_fib (n-1)<br />
in (map fib [0 ..] !!)<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 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]</div>Lambda Fairyhttps://wiki.haskell.org/index.php?title=Xmonad/Frequently_asked_questions&diff=43345Xmonad/Frequently asked questions2011-12-04T00:37:22Z<p>Lambda Fairy: /* Multi head and workspaces (desktops) */ Fixed formatting</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/hardy/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 />
==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/package/xmonad-contrib 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 />
[http://gotmor.googlepages.com/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 />
==== 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 />
(Not recommended) Add <hask>doF W.swapDown</hask> to your manageHook. For instance, a minimal config would look like this:<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
main = xmonad defaultConfig<br />
{ manageHook = manageHook defaultConfig <+> 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. Better would be 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 tranisent 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 flash, etc. should tile or full screen without needing any of the following edits to xmonad.hs. However, if you're here you must be having problems. Try some or all of the following hooks that worked in the past.<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 />
====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 />
# Use a layout which uses these size hints like Hinted Grid, or HintedTile<br />
# Use the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutHints.html layoutHints] modifier on any layout<br />
# Workaround in .vimrc. These lines in your .vimrc lets you change the number of lines with F4/Shift-F4:<br />
<pre><br />
map <F4> :let &lines=&lines-1<CR><br />
map <S-F4> :let &lines=&lines+1<CR><br />
</pre><br />
4. Change the color of default GTK background (white lines), to match gvim background<br />
<pre><br />
style "vimfix" { bg[NORMAL] = "#000000" }<br />
widget "vim-main-window.*GtkForm" style "vimfix"<br />
</pre><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 />
===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 />
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 />
The following workarounds also fix an issue with Java gui applications where menus are not "selectable". (Clicking on the menu item opens the dropdown list of options but you can't select one, or the menu disappears when you are looking at it.)<br />
<br />
If you are still having focus problems, even after implementing the workarounds, see also<br />
[http://code.google.com/p/xmonad/issues/detail?id=177 issue 177].<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"'''. Normally you would use this in<br />
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>Lambda Fairy