https://wiki.haskell.org/api.php?action=feedcontributions&user=Derek+Elkins&feedformat=atomHaskellWiki - User contributions [en]2021-05-18T14:00:40ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=Hac_%CF%86/Talks&diff=55988Hac φ/Talks2013-05-22T00:29:36Z<p>Derek Elkins: /* Talks */</p>
<hr />
<div>If you'd like to give a talk, announce it here; tell us your name, the title of the talk, a short description. Please also let us know if you won't be attending Saturday afternoon and want to present at some other time.<br />
<br />
== Talks == <br />
<br />
{| class="wikitable"<br />
! Talk Name<br />
! Speaker<br />
! Description<br />
|-<br />
| Towards "Big Data" in Haskell<br />
| Edward Kmett<br />
| What is the purpose of the mysterious github.com/analytics account? Why am I doing this? How will it work? What does it mean? When did I start talking to myself?<br />
|-<br />
| Layering Domain Specific Languages and Such<br />
| Gershom Bazerman<br />
| A runthough of the talk (http://lambdajam.com/sessions#bazerman) I'm preparing for lambdajam. It will attempt to have something useful to say about adjunctions. I expect fellow attendees will help me reduce the amount that it is incorrect.<br />
|-<br />
| Signal Processing in (on?) Haskell<br />
| Derek Elkins<br />
| Probably an introduction to some signal processing concepts and examples in Haskell, unless I find a clever way to apply signal processing to combinatorial species, in which case this will be a very different talk.<br />
<!-- copy this template to add your talk<br />
|-<br />
| A Stunning Talk on an Unfathomable Topic<br />
| Joe the Mighty<br />
--><br />
|}<br />
<br />
<br />
[[Category:Community]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Function_decoration_pattern&diff=55273Function decoration pattern2013-01-20T22:36:49Z<p>Derek Elkins: </p>
<hr />
<div>[[Category:Idioms]]<br />
<br />
==Motivation==<br />
<br />
You want to add extra properties to a function type, but you don't want the users to have to tediously project out the decorated type when they don't care about the decorations.<br />
<br />
This can be generalized to arbitrary values instead of just functions.<br />
<br />
==Approach==<br />
<br />
Use type classes to drive the projection by the how the value is used.<br />
<br />
<haskell><br />
{-# LANGUAGE MultiParamTypeClasses, Rank2Types, FlexibleContexts, FlexibleInstances #-}<br />
<br />
-- This implementation is somewhat general, but it is not intended<br />
-- that all examples can be cast in exactly this way.<br />
data Decorate d a b = Decorated (a -> b) (d a b)<br />
<br />
class Decorated d a b dec where<br />
decorated :: (a -> b) -> d a b -> dec a b <br />
-- The above is a Scott-encoding of the below which is equivalent.<br />
-- The Scott-encoded version is often more convenient and efficient.`<br />
-- decorated :: Decorate d a b -> dec a b<br />
<br />
instance Decorated d a b (Decorate d) where<br />
decorated = Decorated<br />
<br />
instance Decorated d a b (->) where<br />
decorated f _ = f<br />
<br />
type IsDecorated d a b = forall dec. Decorated d a b dec => dec a b <br />
<br />
-- Not a very realistic example.<br />
type UnitTested = Decorate (,)<br />
type IsUnitTested a b = IsDecorated (,) a b<br />
<br />
makeTested :: (a -> b) -> a -> b -> IsUnitTested a b<br />
makeTested f a b = decorated f (a, b)<br />
<br />
test :: Eq b => UnitTested a b -> Bool<br />
test (Decorated f (a, b)) = f a == b<br />
<br />
testedSquare :: Num a => IsUnitTested a a<br />
testedSquare = makeTested (\x -> x * x) 3 9<br />
<br />
main = do<br />
print (map testedSquare [1,2,3])<br />
putStrLn (if test testedSquare then "Passed" else "Failed")<br />
</haskell><br />
<br />
<br />
==Examples==<br />
<br />
The archetypical example is the type of isomorphisms e.g. as used in the [http://hackage.haskell.org/packages/archive/lens/3.7.3/doc/html/Control-Lens-Iso.html lens] library.<br />
<br />
An isomorphism is a function equipped with an inverse. Traditionally, this would be represented by a data type such as<br />
<haskell><br />
data Iso a b = Iso { _to :: a -> b, _from :: b -> a }<br />
</haskell><br />
<br />
This would require explicitly projecting out the forward function using <hask>_to</hask>, which makes the code noisy and tedious to write. This can be eliminated by writing: <br />
<haskell><br />
class Isomorphic a b iso where<br />
iso :: (a -> b) -> (b -> a) -> iso a b<br />
<br />
instance Isomorphic a b Iso where<br />
iso = Iso<br />
<br />
instance Isomorphic a b (->) where<br />
iso to _ = to<br />
<br />
type IsIsomorphic a b = forall iso. Isomorphic a b iso => iso a b<br />
</haskell><br />
<br />
Now if we produce values of type <hask>IsIsomorphic a b</hask> rather than <hask>Iso a b</hask> we can just treat them like functions. Note that this should be pursued aggresively. For example, traditionally we'd have two functions <hask>from :: Iso a b -> b -> a</hask> and <hask>op :: Iso a b -> Iso b a</hask> but by using <hask>from :: Iso a b -> IsIsomorphic b a</hask> we get both at once. This can be enforced by making <hask>Iso</hask> abstract.<br />
<br />
Another example would be allowing arrays to used as functions but still being able to get at the bounds when you needed them.<br />
<br />
==Notes==<br />
<br />
This is closely related to the Yoneda lemma and representability. Essentially we are identifying the value <hask>x</hask> with <hask>($ x)</hask>. The instances of the type classes just choose how we want to observe the <hask>x</hask> via <hask>($ x) observation</hask>. <hask>makeTested</hask> makes this pretty explicit especially if the direct (rather than Scott-encoded) representation is used.<br />
<br />
This can be viewed as a special case of the [http://okmij.org/ftp/tagless-final/index.html finally, tagless] encoding.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Function_decoration_pattern&diff=55272Function decoration pattern2013-01-20T20:53:10Z<p>Derek Elkins: </p>
<hr />
<div>[[Category:Idioms]]<br />
<br />
==Motivation==<br />
<br />
You want to add extra properties to a function type, but you don't want the users to have to tediously project out the decorated type when they don't care about the decorations.<br />
<br />
This can be generalized to arbitrary values instead of just functions.<br />
<br />
==Approach==<br />
<br />
Use type classes to drive the projection by the how the value is used.<br />
<br />
<haskell><br />
{-# LANGUAGE MultiParamTypeClasses, Rank2Types, FlexibleContexts, FlexibleInstances #-}<br />
<br />
-- This implementation is somewhat general, but it is not intended<br />
-- that all examples can be cast in exactly this way.<br />
data Decorate d a b = Decorated (a -> b) (d a b)<br />
<br />
class Decorated d a b dec where<br />
decorated :: (a -> b) -> d a b -> dec a b <br />
-- The above is a Scott-encoding of the below which is equivalent.<br />
-- The Scott-encoded version is often more convenient and efficient.`<br />
-- decorated :: Decorate d a b -> dec a b<br />
<br />
instance Decorated d a b (Decorate d) where<br />
decorated = Decorated<br />
<br />
instance Decorated d a b (->) where<br />
decorated f _ = f<br />
<br />
type IsDecorated d a b = forall dec. Decorated d a b dec => dec a b <br />
<br />
-- Not a very realistic example.<br />
type UnitTested = Decorate (,)<br />
type IsUnitTested a b = IsDecorated (,) a b<br />
<br />
makeTested :: (a -> b) -> a -> b -> IsUnitTested a b<br />
makeTested f a b = decorated f (a, b)<br />
<br />
test :: Eq b => UnitTested a b -> Bool<br />
test (Decorated f (a, b)) = f a == b<br />
<br />
testedSquare :: Num a => IsUnitTested a a<br />
testedSquare = makeTested (\x -> x * x) 3 9<br />
<br />
main = do<br />
print (map testedSquare [1,2,3])<br />
putStrLn (if test testedSquare then "Passed" else "Failed")<br />
</haskell><br />
<br />
<br />
==Examples==<br />
<br />
The archetypical example is the type of isomorphisms e.g. as used in the [http://hackage.haskell.org/packages/archive/lens/3.7.3/doc/html/Control-Lens-Iso.html lens] library.<br />
<br />
An isomorphism is a function equipped with an inverse. Traditionally, this would be represented by a data type such as<br />
<haskell><br />
data Iso a b = Iso { _to :: a -> b, _from :: b -> a }<br />
</haskell><br />
<br />
This would require explicitly projecting out the forward function using <hask>_to</hask>, which makes the code noisy and tedious to write. This can be eliminated by writing: <br />
<haskell><br />
class Isomorphic a b iso where<br />
iso :: (a -> b) -> (b -> a) -> iso a b<br />
<br />
instance Isomorphic a b Iso where<br />
iso = Iso<br />
<br />
instance Isomorphic a b (->) where<br />
iso to _ = to<br />
<br />
type IsIsomorphic a b = forall iso. Isomorphic a b iso => iso a b<br />
</haskell><br />
<br />
Now if we produce values of type <hask>IsIsomorphic a b</hask> rather than <hask>Iso a b</hask> we can just treat them like functions. Note that this should be pursued aggresively. For example, traditionally we'd have two functions <hask>from :: Iso a b -> b -> a</hask> and <hask>op :: Iso a b -> Iso b a</hask> but by using <hask>from :: Iso a b -> IsIsomorphic b a</hask> we get both at once. This can be enforced by making <hask>Iso</hask> abstract.<br />
<br />
Another example would be allowing arrays to used as functions but still being able to get at the bounds when you needed them.<br />
<br />
==Notes==<br />
<br />
This is closely related to the Yoneda lemma and representability. Essentially we are identifying the value <hask>x</hask> with <hask>($ x)</hask>. The instances of the type classes just choose how we want to observe the <hask>x</hask> via <hask>($ x) observation</hask>. <hask>makeTested</hask> makes this pretty explicit especially if the direct (rather than Scott-encoded) representation is used.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Function_decoration_pattern&diff=55271Function decoration pattern2013-01-20T20:40:29Z<p>Derek Elkins: New page: Category:Idioms ==Motivation== You want to add extra properties to a function type, but you don't want the users to have to tediously project out the decorated type when they don't c...</p>
<hr />
<div>[[Category:Idioms]]<br />
<br />
==Motivation==<br />
<br />
You want to add extra properties to a function type, but you don't want the users to have to tediously project out the decorated type when they don't care about the decorations.<br />
<br />
This can be generalized to arbitrary values instead of just functions.<br />
<br />
==Approach==<br />
<br />
Use type classes to drive the projection by the how the value is used.<br />
<br />
<haskell><br />
{-# LANGUAGE MultiParamTypeClasses, Rank2Types, FlexibleContexts, FlexibleInstances #-}<br />
<br />
-- This implementation is somewhat general, but it is not intended<br />
-- that all examples can be cast in exactly this way.<br />
data Decorate d a b = Decorated (a -> b) (d a b)<br />
<br />
class Decorated d a b dec where<br />
decorated :: (a -> b) -> d a b -> dec a b <br />
-- The above is a Scott-encoding of the below which is equivalent.<br />
-- The Scott-encoded version is often more convenient and efficient.`<br />
-- decorated :: Decorate d a b -> dec a b<br />
<br />
instance Decorated d a b (Decorate d) where<br />
decorated = Decorated<br />
<br />
instance Decorated d a b (->) where<br />
decorated f _ = f<br />
<br />
type IsDecorated d a b = forall dec. Decorated d a b dec => dec a b <br />
<br />
-- Not a very realistic example.<br />
type UnitTested = Decorate (,)<br />
type IsUnitTested a b = IsDecorated (,) a b<br />
<br />
makeTested :: (a -> b) -> a -> b -> IsUnitTested a b<br />
makeTested f a b = decorated f (a, b)<br />
<br />
test :: Eq b => UnitTested a b -> Bool<br />
test (Decorated f (a, b)) = f a == b<br />
<br />
testedSquare :: Num a => IsUnitTested a a<br />
testedSquare = makeTested (\x -> x * x) 3 9<br />
<br />
main = do<br />
print (map testedSquare [1,2,3])<br />
putStrLn (if test testedSquare then "Passed" else "Failed")<br />
</haskell><br />
<br />
<br />
==Examples==<br />
<br />
The archetypical example is the type of isomorphisms e.g. as used in the [http://hackage.haskell.org/packages/archive/lens/3.7.3/doc/html/Control-Lens-Iso.html lens] library.<br />
<br />
An isomorphism is a function equipped with an inverse. Traditionally, this would be represented by a data type such as<br />
<haskell><br />
data Iso a b = Iso { _to :: a -> b, _from :: b -> a }<br />
</haskell><br />
<br />
This would require explicitly projecting out the forward function using <hask>_to</hask>, which makes the code noisy and tedious to write. This can be eliminated by writing: <br />
<haskell><br />
class Isomorphic a b iso where<br />
iso :: (a -> b) -> (b -> a) -> iso a b<br />
<br />
instance Isomorphic a b Iso where<br />
iso = Iso<br />
<br />
instance Isomorphic a b (->) where<br />
iso to _ = to<br />
<br />
type IsIsomorphic a b = forall iso. Isomorphic a b iso => iso a b<br />
</haskell><br />
<br />
Now if we produce values of type <hask>IsIsomorphic a b</hask> rather than <hask>Iso a b</hask> we can just treat them like functions. Note that this should be pursued aggresively. For example, traditionally we'd have two functions <hask>from :: Iso a b -> b -> a</hask> and <hask>op :: Iso a b -> Iso b a</hask> but by using <hask>from :: Iso a b -> IsIsomorphic b a</hask> we get both at once. This can be enforced by making <hask>Iso</hask> abstract.<br />
<br />
==Notes==<br />
<br />
This is closely related to the Yoneda lemma and representability. Essentially we are identifying the value <hask>x</hask> with <hask>($ x)</hask>. The instances of the type classes just choose how we want to observe the <hask>x</hask> via <hask>($ x) observation</hask>. <hask>makeTested</hask> makes this pretty explicit especially if the direct (rather than Scott-encoded) representation is used.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=IRC_channel&diff=26273IRC channel2009-02-04T06:38:48Z<p>Derek Elkins: </p>
<hr />
<div>Internet Relay Chat is a worldwide text chat service with many thousands<br />
of users among various irc networks.<br />
<br />
The Freenode IRC network hosts the large #haskell channel, and we've had<br />
up to 674 concurrent users (average is 565), making the channel<br />
[http://searchirc.com/search.php?SCHANS=1&SSORT=SIZE&N=freenode the 5th largest]<br />
of the 7000 channels on freenode (Jan 2009). One famous<br />
resident is [[Lambdabot]], another is [http://hpaste.org hpaste] (see<br />
the [[#Bots|Bots]] section below).<br />
<br />
The IRC channel can be an excellent place to learn more about Haskell,<br />
and to just keep in the loop on new things in the Haskell world. Many<br />
new developments in the Haskell world first appear on the irc channel.<br />
<br />
Since 2009, the Haskell channel has grown large enough that we've split it in two parts:<br />
<br />
* #haskell, for all the usual things<br />
* #haskell-in-depth , for those seeking in depth, or more theoretical discussion<br />
<br />
As always, #haskell remains the primary place for new user questions.<br />
<br />
--------------------------<br />
<br />
[http://haskell.org/sitewiki/images/3/3c/Haskell-current.png [[Image:Haskell-current-small.png|thumb|The #haskell social graph, Jan 2008]]]<br />
<br />
[[Image:Irc-raw.png|thumb|Daily traffic in #haskell since 2004]]<br />
<br />
[[Image:Nick-activity.png|thumb|Growth of #haskell]]<br />
<br />
[[Image:Haskell-wordle-irc.png|thumb|Haskell noun map]]<br />
<br />
== Getting there ==<br />
<br />
If you point your irc client to [irc://chat.freenode.net/haskell chat.freenode.net] and then join the #haskell channel, you'll be there. Alternately, you can try [http://www.mibbit.com/ mibbit.com] which connects inside the browser.<br />
<br />
Example, using [http://www.irssi.org/ irssi]:<br />
<br />
$ irssi -c chat.freenode.net -n myname -w mypassword<br />
/join #haskell<br />
<br />
Tip, if you're using Emacs to edit your Haskell sources then why not use it to chat about Haskell? Check out [http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient ERC], The Emacs IRC client. Invoke it like this and follow the commands:<br />
<br />
M-x erc-select<br />
...<br />
/join #haskell<br />
<br />
[[Image:Irc--haskell-screenshot.png|frame|A screenshot of an irssi session in #haskell]]<br />
<br />
== Principles ==<br />
<br />
The #haskell channel is a very friendly, welcoming place to hang out,<br />
teach and learn. The goal of #haskell is to encourage learning and<br />
discussion of Haskell, functional programming, and programming in<br />
general. As part of this we welcome newbies, and encourage teaching of<br />
the language.<br />
<br />
Part of the #haskell success comes from the approach that the community<br />
is quite tight knit -- we know each other -- it's not just a homework<br />
channel. As a result, many collaborative projects have arisen between<br />
Haskell irc channel citizens.<br />
<br />
To maintain the friendly, open culture, the following is required:<br />
<br />
* Low to zero tolerance for ridiculing questions. Insulting new users is unacceptable<br />
<br />
New Haskell users should feel entirely comfortable asking new questions.<br />
Helpful answers should be encouraged with <hask>name++</hask> karma<br />
points, in public, as a reward for providing a good answer.<br />
<br />
As the channel grows, we see a diverse range of people, with different<br />
programming backgrounds, trying to make their way with Haskell. A good<br />
rule of thumb, to avoid frustration is:<br />
<br />
* approach negative comments by asking for details (kind of like [http://en.wikipedia.org/wiki/Socratic_method Socratic questioning]), rather than challenging the competence of the writer (ad hominem).<br />
<br />
<br />
== History ==<br />
<br />
The #haskell channel appeared in the late 90s, and really got going<br />
in early 2001, with the help of Shae Erisson (aka shapr).<br />
<br />
A fairly extensive analysis of the traffic on #haskell over the years is<br />
[http://www.cse.unsw.edu.au/~dons/irc/ kept here]<br />
<br />
== Related channels ==<br />
<br />
In addition to the main Haskell channel there are also:<br />
<br />
{| border="1" cellspacing="0" cellpadding="5" align="center"<br />
! Channel<br />
! Purpose<br />
|-<br />
| #haskell.cz<br />
| Czech speakers<br />
|- <br />
| #haskell.de<br />
| German speakers<br />
|-<br />
| #haskell.dut<br />
| Dutch speakers<br />
|-<br />
| #haskell.es<br />
| Spanish speakers<br />
|-<br />
| #haskell.fi<br />
| Finnish speakers<br />
|-<br />
| #haskell.fr <br />
| French speakers <br />
|-<br />
| #haskell.hr<br />
| Croatian speakers<br />
|-<br />
| #haskell.it <br />
| Italian speakers<br />
|-<br />
| #haskell.jp <br />
| Japanese speakers<br />
|-<br />
| #haskell.no <br />
| Norwegian speakers<br />
|-<br />
| #haskell.ru <br />
| Russian speakers. Seems that most of them migrated to Jabber conference (haskell@conference.jabber.ru).<br />
|-<br />
| #haskell_ru <br />
| Russian speakers again, in UTF-8. For those, who prefer good ol' IRC channel with a lambdabot.<br />
|-<br />
| #haskell.se <br />
| Swedish speakers<br />
|-<br />
| #haskell-overflow<br />
| Overflow conversations<br />
|-<br />
| #haskell-blah <br />
| Haskell people talking about anything except Haskell itself<br />
|-<br />
| #haskell-books <br />
| Authors organizing the collaborative writing of the [http://en.wikibooks.org/wiki/Haskell Haskell wikibook] and other books or tutorials.<br />
|-<br />
| #gentoo-haskell <br />
| [[Gentoo]]/Linux specific Haskell conversations<br />
|-<br />
| #arch-haskell <br />
| [[Arch Linux]]/ specific Haskell conversations<br />
|-<br />
|-<br />
| #darcs <br />
| [[Darcs]] revision control channel (written in Haskell)<br />
|-<br />
| #perl6 <br />
| [http://www.pugscode.org Perl 6] development (plenty of Haskell chat there too)<br />
|-<br />
| #happs<br />
| [http://happs.org HAppS] Haskell Application Server channel<br />
|-<br />
| #xmonad<br />
| [http://xmonad.org Xmonad] a tiling window manager written in Haskell<br />
|}<br />
<br />
== Logs ==<br />
<br />
'''Logs''' are kept at a few places, including<br />
<br />
* [http://tunes.org/~nef/logs/haskell/ tunes.org]<br />
* [http://ircbrowse.com/cdates.html?channel=haskell IRCBrowse]<br />
<br />
<br />
== Bots ==<br />
<br />
=== Lambdabot ===<br />
<br />
[[Lambdabot]] provides many useful services for visitors to the IRC channel. Check out its wiki page for information on its commands.<br />
<br />
=== Hpaste ===<br />
The hpaste bot provides a notification interface to the [http://hpaste.org hpaste pastebin]. [[Hpaste.el|Emacs integration]] is available.<br />
<br />
=== Hackage ===<br />
The hackage bot provides real-time notifications of new package uploads to [http://hackage.haskell.org Hackage].<br />
<br />
== Locations ==<br />
<br />
To get an overview of where everybody on the channel might<br />
be, physically, please visit [[Haskell user locations]].<br />
<br />
<br />
[[Category:Community]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=24255Performance/Monads2008-11-26T03:21:01Z<p>Derek Elkins: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
Note that this is just essentially just ContT M and indeed all of the below is just writing out the ContT implementation.<br />
<br />
Also note that M's (>>=) operation isn't used. It comes up when you implement the other operations M supports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
How and why does this work? We're basically specializing <hask>>>=</hask>. Before, we had<br />
<haskell><br />
m >>= f = case m of<br />
Just a -> f a<br />
Nothing -> Nothing<br />
</haskell><br />
i.e. the monadic bind does a case analysis on how to proceed. In the CPS-representation, we're specializing bind to the two possible constructors:<br />
<haskell><br />
return' a := (return a >>=) = (Just a >>=) = \f -> f a<br />
mzero' := (mzero >>=) = (Nothing >>=) = \f -> Nothing<br />
</haskell><br />
and the case analysis is now "built-in" into <hask>return'</hask> and <hask>mzero'</hask>. In general, embedding a monad in <hask>Cont</hask> specializes <hask>>>=</hask> to its primitive operations, like for example <hask>mzero</hask> or <hask>get</hask>. This is close to specifying the operational semantics of <hask>>>=</hask> directly and can hence be used to implement the monad in the first place, too.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing) -- equivalent to MaybeCPS (Nothing >>=)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].<br />
<br />
See also [http://wwwtcs.inf.tu-dresden.de/~voigt/mpc08.pdf Asymptotic Improvement of Computations over Free Monads].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Stack_overflow&diff=22878Stack overflow2008-09-13T00:18:47Z<p>Derek Elkins: Added foldl' over a tuple</p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
== Folds ==<br />
<br />
First, read [[Performance/Accumulating parameter]]. If you are not writing your code tail-recursively, then that is why you are getting stack overflows. However, making code tail-recursive in a lazy language is not quite the same as in a eager language. This page is more geared to the latter case using foldr/l as the prime culprit/example. As such [[Fold]] may be helpful, but isn't too critical. Also knowing what <hask>seq</hask> and <hask>($!)</hask> do, as covered in [http://users.aber.ac.uk/afc/stricthaskell.html#seq Making Haskell programs faster and smaller] and in the [http://haskell.org/onlinereport/ Haskell Report] is necessary.<br />
<br />
The definitions of the three folds we'll be looking at are as follows:<br />
<haskell><br />
foldr f z [] = z<br />
foldr f z (x:xs) = f x (foldr f z xs)<br />
<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
<br />
foldl' f z [] = z<br />
foldl' f z (x:xs) = (foldl' f $! f z x) xs<br />
<br />
foldl' (found in e.g. Data.List) is just a stricter version of foldl.<br />
</haskell><br />
The one-line summary for folds: if the binary operation is strict use foldl', otherwise use foldr.<br />
<br />
----<br />
<br />
Common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldr (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
If you've read [[Performance/Accumulating parameter]], you should immediately see the problem from the definition of foldr above. Quite simply, foldr isn't tail-recursive! But,<br />
<haskell><br />
concat xss = foldr (++) [[]] xss<br />
</haskell><br />
This is from the Haskell Report. Surely they know what they are doing! And sure enough,<br />
<haskell><br />
main = print (length (concat [[x] | x <- [1..1000000]]))<br />
</haskell><br />
works fine.<br />
<br />
Less common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
So what's going on here. Looking at the code for foldl, it looks tail-recursive. Well, much like you can see the problem with a non-tail-recursive factorial by unfolding a few iterations, let's do the same for our foldl definition of sum, but making sure to use a call-by-name/need evaluation order. Here is the unfolding,<br />
<haskell><br />
mysum [1..10] -><br />
foldl (+) 0 (1:[2..10]) -><br />
foldl (+) (0+1) (2:[3..10]) -><br />
foldl (+) (0+1+2) (3:[4..10]) -><br />
foldl (+) (0+1+2+3) (4:[5..10]) -> <nowiki>...</nowiki><br />
</haskell><br />
I think you get the idea. The problem is that we are building up a chain of thunks that will evaluate the sum instead of just maintaining a running sum. What we need to do is to force the addition before recursing. This is exactly what foldl' does.<br />
<br />
Just to check,<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl' (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
works fine.<br />
<br />
Now let's go back to the foldr sum and concat. What's the difference between sum and concat that makes the sum definition wrong, but the concat definition right. Again, let's evaluate each by hand.<br />
<haskell><br />
mysum (+) 0 [1..10] -><br />
foldr (+) 0 (1:[2..10]) -><br />
1+foldr (+) 0 (2:[3..10]) -><br />
1+(2+foldr (+) 0 (3:[4..10])) -> <nowiki>...</nowiki><br />
</haskell><br />
Okay, no surprise there.<br />
<haskell><br />
concat [[1],[2],[3],<nowiki>...</nowiki>] -><br />
foldr (++) [[]] ([1]:[[2],[3],<nowiki>...</nowiki>]) -><br />
(1:[])++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>] -><br />
1:([]++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>])<br />
</haskell><br />
Notice that there is no '-> ...' at the end. That was the complete evaluation. There is no reason to do anything more, unless we look at the result. We may well GC the 1 before we look at the tail, and GC the first cons cell before we look at the second. So, concat runs in a constant amount of stack and further can handle infinite lists (as a note, it's immediately obvious foldl(') can never work on infinite lists because we'll always be in the (:) case and that always immediately recurses). The differentiator between mysum and concat is that (++) is not strict* in its second argument; we don't have to evaluate the rest of the foldr to know the beginning of concat. In mysum, since (+) is strict in its second argument, we need the results of the whole foldr before we can compute the final result.<br />
<br />
So, we arrive at the one-line summary: <br />
A function strict* in its second argument will always require linear stack space with foldr, so foldl' should be used instead in that case. <br />
If the function is lazy/non-strict in its second argument we should use foldr to 1) support infinite lists and 2) to allow a streaming use of the input list where only part of it needs to be in memory at a time.<br />
<br />
Okay, both here and in the one-line summary, there is no mention of foldl. When should foldl be used? The pragmatic answer is: by and far, it shouldn't be used. A case where it makes a difference is if the function is conditionally strict in its first argument depending on its second, where I use conditionally strict to mean a function that is strict or not in one argument depending on another argument(s). For an example, consider a definition of <hask>(*)</hask> that builds up ASTs of arithmetic expressions and incorporates a simplification (<hask>a*0 = 0</hask> and then <hask>0*a = 0</hask>); then if <hask>product</hask> is defined by <hask>foldl (*) 1</hask>, <hask>product [</hask>&perp;<hask>,0]</hask> will terminate with 0 while a definition in terms of <hask>foldl'</hask> wouldn't. However, I can't think of a really convincing example. In most cases, foldl' is what you want.<br />
<br />
<nowiki>*</nowiki> A strict function is a function <hask>f</hask>, such that <hask>f </hask>&perp;<hask> = </hask>&perp;. Typically, we think of a function "being strict" in an argument as a function that "forces" its argument, but the above definition of strict should immediately suggest another function that is strict and doesn't "force" it's argument in the intuitive sense, namely id. <hask>([]++) = id</hask> and therefore is a strict function. Sure enough, if you were to evaluate <hask>(concat (repeat []))</hask> it would not terminate. As such, <hask>(++)</hask> is a conditionally strict function. This also makes the "always" slightly imprecise, a function that is strict because it just returns it's argument, will not use up stack space (but is, as mentioned, still an issue for infinitely long lists).<br />
<br />
== Weak Head Normal Form ==<br />
<br />
Common newbie stack overflowing code:<br />
<haskell><br />
myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0)<br />
</haskell><br />
<br />
People who understand seq and weak head normal form (whnf) can immediately understand what goes wrong here. <hask>(acc+x, len+1)</hask> is already in whnf, so <hask>seq</hask>, which reduces a value to whnf, does nothing to this. This code will build up thunks just like the original <hask>foldl</hask> example, they'll just be inside a tuple. The solution is just to force the components of the tuple, e.g.<br />
<haskell><br />
myAverage = uncurry (/) . foldl' (\(acc, len) x -> acc `seq` len `seq` (acc+x, len+1)) (0,0)<br />
</haskell><br />
or more clearly and concisely using a recent GHC extension<br />
<haskell><br />
myAverage = uncurry (/) . foldl' (\(!acc, !len) x -> (acc+x, len+1)) (0,0)<br />
</haskell><br />
<br />
== Scans ==<br />
<br />
A subtle stack-overflow surprise comes when<br />
<haskell><br />
print (scanl (+) 0 [1..1000000])<br />
</haskell><br />
completes successfully but<br />
<haskell><br />
print (last (scanl (+) 0 [1..1000000]))<br />
</haskell><br />
causes a stack overflow.<br />
<br />
The latter stack overflow is explained exactly as before, namely,<br />
<haskell><br />
last (scanl (+) 0 [1..5]) -><br />
<nowiki>... several steps ...</nowiki> -><br />
((((0+1)+2)+3)+4)+5<br />
</haskell><br />
This is exactly like <hask>foldl</hask>, building a deep thunk, then evaluating, needing much stack.<br />
<br />
Most puzzling is why the former succeeds without a stack overflow. This is caused by a combination of two factors:<br />
* thunks in the list produced by <hask>scanl</hask> enjoy sharing: late thunks build upon early thunks<br />
* printing a list of numbers evaluates early thunks and then late thunks<br />
To exemplify, here is an abridged progression. I use this pseudo format to depict sharing of thunks<br />
<haskell><br />
expr where var=expr, var=expr<br />
</haskell><br />
although in reality it is more like a pointer graph.<br />
<haskell><br />
print (scanl (+) 0 [1..1000000]) -><br />
print (a : case [1..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (a+x) xs) where a=0 -><br />
<nowiki>... evaluate a to 0 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (a+1) [2..1000000]) where a=0 -><br />
print (b : case [2..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (b+x) xs) where a=0, b=a+1 -><br />
<nowiki>... evaluate b to 1 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (b+2) [3..1000000]) where b=1 -><br />
print (c : case [3..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (c+x) xs) where b=1, c=b+2 -><br />
<nowiki>... evaluate c to 3 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (c+3) [4..1000000]) where c=3 -><br />
print (d : case [4..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (d+x) xs) where c=3, d=c+3 -><br />
<nowiki>... evaluate d to 6 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (d+4) [5..1000000]) where d=6 -> etc.<br />
</haskell><br />
The important thing to watch is the life cycle of intermediate thunks, e.g., <hask>c</hask> is created at some point as a 1-level deep addition, then almost immediately reduced to a number out of necessity, before a later thunk <hask>d</hask> builds upon it. Therefore there is no growth and no stack overflow.<br />
<br />
In contrast, again, <hask>last (scanl (+) 0 [1..1000000])</hask> skips over to the last thunk right away. Since early items are not reduced yet, the last item remains a huge chain and causes overflow.<br />
<br />
As an addendum, there are three ways of handling this problem and similar ones:<br />
# You can have your traversal functions (in this case, last) force the list as it goes along.<br />
# You can use (perhaps custom) versions of the list (or data structure, in general) producing functions (in this case, scanl) that force the elements as it builds the data structure.<br />
# You can use a data structure that's strict in its elements, in this case it would be a head strict list.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=QuotesPage&diff=22328QuotesPage2008-08-10T20:08:40Z<p>Derek Elkins: First pass resurrecting the QuotesPage</p>
<hr />
<div>seen on comp.lang.functional:<br />
<br />
From: Ashley Yakeley <ashley@semantic.org><br />
Subject: Re: Type advocacy<br />
Newsgroups: comp.lang.functional<br />
Date: Thu, 11 Oct 2001 21:16:20 -0700<br />
Organization: Myself<br />
<br />
In article <9pdvgc$u3d$1@news.fas.harvard.edu>, Ken Shan<br />
<ken@digitas.harvard.edu> wrote:<br />
<br />
> I am preparing a three-minute talk to tell incoming graduate students<br />
> at my school about types.<br />
<br />
Oh like that's going to work. You'd be better off selling T-shirts that<br />
say "WHAT PART OF" (and then the Hindley-Milner prinicipal-type<br />
algorithm) "DON'T YOU UNDERSTAND?".<br />
<br />
If anyone gives you any lip, ask them how to find the square-root of a<br />
string. Everything else follows on from that.<br />
<br />
> What pointers should I give?<br />
<br />
Safe ones.<br />
<br />
--<br />
Ashley Yakeley, Seattle WA<br />
<br />
After reading this, I just couldn't resist:<br />
<br />
http://www.cafeshops.com/skicalc<br />
<br />
--Riastradh<br />
<br />
----<br />
<br />
<Pseudonym> Lazy evalution is really, really trippy. <br />
<br />
----<br />
<br />
<nowiki>*</nowiki> jemfinch just printed an infinite list.<br />
<Pseudonym> Quick, type control-C before you run out of bits!<br />
<br />
----<br />
<br />
Not all things worth counting are countable and not all things that count are worth counting. <br />
<br />
-- Albert Einstein<br />
<br />
----<br />
<br />
<tez> Anyway, I think the lesson is "don't drink and derive". Or something.<br />
<br />
----<br />
<br />
seen on The Pragmatic Programmer's yahoo mailing list:<br />
<br />
From: Ronald Legere <rjljr2@yahoo.com><br />
Subject: Re: Jedi Programming (was: [pragprog] Common List or Dylan?)<br />
To: pragprog@yahoogroups.com<br />
Date: Wed, 25 Sep 2002 03:29:01 -0700 (PDT)<br />
Reply-To: pragprog@yahoogroups.com<br />
<br />
No no no, a jedi master must fashion his<br />
OWN language.<br />
<br />
<*grin*><br />
<br />
--- Michael Schuerig <schuerig@acm.org> wrote:<br />
> On Wednesday 25 September 2002 05:27, Edward Wilson<br />
> wrote:<br />
> > The real question is: if you were a Jedi Knight,<br />
> and<br />
> > you could only master *one* language as your<br />
> weapon of<br />
> > choice, what would it be--Common Lisp?<br />
><br />
> Probably. In particular, considering that the Jedi<br />
> seem to be somewhat<br />
> conservative and CL beautifully captures the<br />
> anachronistic elegance and<br />
> power of a programming lightsaber. Future Jedi<br />
> generations might choose<br />
> more modern weapons; Haskell, OCaml and Oz being<br />
> among the contenders.<br />
><br />
> Michael<br />
><br />
> --<br />
> Michael Schuerig<br />
> You should go home and<br />
> mailto:schuerig@acm.org<br />
> reconsider your life.<br />
> http://www.schuerig.de/michael/<br />
> --Obi-Wan, "AotC"<br />
<br />
----<br />
<br />
<shapr> I'm addicted to arrows.<br />
<nowiki>*</nowiki> shapr begins his own paper "Generalizing Arrows to Spears"<br />
<shapr> Spears can do anything efficiently, but they have sixty thousand laws they must satisfy, and we haven't actually found one yet.<br />
<raphael> maybe "Generalizing Arrows to Nuclear Weapons" would simply be: unsafeInterleaveIO<br />
<br />
----<br />
<br />
<Janni> doesn't ghc create really _fast_ code?<br />
<Heffalump> Janni: it creates really fast Haskell code<br />
<br />
----<br />
<br />
seen on #java<br />
<br />
<sh1nta> anyone familiar with javacc or any kind of parser for java object?<br />
<shapr> I know of a good java source parser for Haskell<br />
<sh1nta> shapr:what do you think is a good way to parse an inputstream of strings?<br />
like there is a,b,c coming through the serial stream..i have to grab those data<br />
<shapr> sh1nta: I'd use monadic parser combinators.<br />
<sh1nta> shapr:in simpler words?<br />
<sh1nta> shapr:i am kinda newbie<br />
<Logi> shapr: no fair to use heavy haskell jargon<br />
<nowiki>*</nowiki> mprentice applauds shapr for picking on the n00b<br />
<Logi> sh1nta: shapr would do that cause he'd be doing it in Haskell.<br />
<mprentice> sh1nta: it depends on what kind of data you're parsing, but javacc might be kinda overkill. it'll take a day at least to learn enough to do anything complicated enough to make it worth doing.<br />
<nowiki>*</nowiki> mprentice uses a nuke to kill the pesky cockroach<br />
<Logi> oh, learning enough to use monads will take you a week<br />
<br />
----<br />
<br />
<esap> I think the way to get stuff done is by doing it.<br />
<Marvin--> esap: damn you're smart<br />
<br />
----<br />
<br />
<shapr> GHC has more flags than the UN<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> jlouis replaces dark with a very small higher order function<br />
<br />
----<br />
<br />
<jlouis> Q: When does one know he has programmed too much Haskell? A: When he uses == and /= in everyday IRC chat<br />
<jlouis> or when he tries to fix a relationship by passing himself as a continuation<br />
<br />
----<br />
<br />
<shapr> I think we should make up a name for combinators that works like Java Beans<br />
<shapr> how about calling them Chickens?<br />
<Arnia> Chickens?<br />
<shapr> then we could talk about Currying Chickens<br />
<nowiki>*</nowiki> Arnia groans<br />
<br />
----<br />
<br />
<Grog`> http://www.cse.unsw.edu.au/~cs1011/assignment/assign1/index.html<br />
<Smerdyakov> This isn't a homework answer service.<br />
<Grog`> is it a kind service<br />
<Smerdyakov> Yeah, the answer is "drop the class if you're too dumb to do that problem," directed to whoever is in the class.<br />
<br />
----<br />
<br />
after a long pointless discussion with a fanatically loyal C programmer on comp.lang.functional <a40a15cb.0304160038.585f3e8@posting.google.com>:<br />
<br />
"The best thing to get out of this, I guess,is that Haskell IS becoming more mainstream and even morons have heard of it." -- DerekElkins<br />
<br />
----<br />
<br />
seen on news://comp.lang.functional<br />
<br />
> By the way seriously: how do you debug Haskell programs?<br />
<br />
Mostly seriously: I don't. If the programme doesn't work the<br />
way I intended it, I rewrite bits in a simpler fashion until<br />
I understand it well enough and it works. For the sort of<br />
programme you were asking for, breaking things up until they<br />
are small enough that one can understand the individual<br />
parts completely (as I did in the solution I posted) and<br />
then composing them together really is the best approach.<br />
<br />
If you need to debug a programme that simple, what it's<br />
telling you is that you've written it the wrong way!<br />
<br />
--<br />
Jón Fairbairn<br />
<br />
----<br />
<br />
<Marvin--> the good thing with free software, though, is that I can write my damn software and when someone complains that it doesn't work on their toaster because I'm a moron who can't write portable code, I can say, smiling, "patches welcome"<br />
<shapr> yah, I like that too<br />
<shapr> but then sometimes you get "I can't understand a bit of your Java code"<br />
<Marvin--> that's when you reply "me neither, life's a bitch, isn't it?"<br />
<br />
----<br />
<br />
"So, the essence of XML is this: the problem it solves is not hard, and<br />
it does not solve the problem well." -- Jerome Simeon & Phil Wadler<br />
<br />
----<br />
<br />
in the midst of a discussion about the 'Evil Mangler' in GHC 5.04<br />
<br />
<shapr> the evil mangler uses *perl* ??<br />
<ChilliX> yes...<br />
<ChilliX> it is Evil after all<br />
<br />
----<br />
<br />
<andersca> what meeting?<br />
<Marvin--> research meeting for the cover group<br />
<shapr> are you guys covering up the black ops section?<br />
<Marvin--> shapr: there is no HSU<br />
<shapr> and you're not part of it<br />
<Marvin--> of course not<br />
<br />
----<br />
<br />
In reply to someone who said unsafePerformIO docs didn't include enough warnings, ManuelChakravarty replied:<br />
<br />
After all, you can import any C function with a pure type,<br />
which also allows you to wreak arbitrary havoc. We enable<br />
the user to disguise arbitrary machine code as a Haskell<br />
function of essentially arbitrary type. In comparison,<br />
`unsafePerformIO' seems angelic.<br />
<br />
----<br />
<br />
[discussion of the merits of lazy, eager, macros snipped]<br />
The idea isn't to blunder into a language looking for evidence<br />
to support a bunch of preconceived misconceptions.<br />
the idea is to understand why things are the way they are.<br />
<br />
macros have advantages and disadvantages.<br />
graham lists them in that same chapter.<br />
understanding those lets you choose the right tool for the job.<br />
that's why it's a good book. if you're not interested in choosing the right tool, but only in proving that something is "better" or "worse" than something else, then why waste time reading books?<br />
the world is complex and the more you understand the less certain things become.<br />
if you prefer simple black and white then it's better not to learn...<br />
<br />
(maybe i should add that i don't use lisp;<br />
that normally i find it's lisp users who are annoyingly dismissive of other languages; that i, too, have criticised things before understanding them at times; also it's monday morning and i'm still on my first cup of coffee)<br />
<br />
-- andrew cooke <br />
<br />
----<br />
<br />
<CowGirl> what are the 2 most common recursive errors?<br />
<hdaume> CowGirl: what<br />
<CowGirl> is a question in a past exam on haskell<br />
<CowGirl> 2 of the most common recursive errors<br />
<hdaume> ...oh....i thought it was a lead-in to a joke<br />
<br />
----<br />
<br />
<syntax-laptop> is there a punchline to "how many recursions does it take to screw in a lightbulb?"? <br />
<cale> It takes n recursions to screw in a light bulb, one to turn the light bulb once, and n-1 to screw it in.<br />
<br />
----<br />
<br />
seen on #haskell:<br />
<br />
<Riastradh> What does HFL stand for?<br />
<shapr> Haskell Foundation Libraries<br />
<Igloo> Haskell Foundation Library<br />
<dark> Obviously shapr and Igloo must now duel to the death.<br />
<nowiki>*</nowiki> shapr duals Igloo<br />
<nowiki>*</nowiki> Riastradh hands shapr a monad and Igloo a comonad.<br />
<nowiki>*</nowiki> Igloo waves it around and makes voooob voooob noises<br />
<nowiki>*</nowiki> shapr waves his monad around making boov boov noises<br />
<Heffalump> Igloo: careful with that, it's unsafe<br />
<br />
----<br />
<br />
<shapr> for example: "head (filter (\x -> x > 5) [1..])"<br />
<shapr> in a strict language, you can't easily play with infinite lists<br />
<dark> In a strict language, you would write that as "6" :)<br />
<br />
----<br />
<br />
<Marvin--> I often sigh and say "I could do this way faster and way better in Haskell" and then they say "yeah, and we wouldn't understand a thing of it"<br />
<br />
----<br />
<br />
<ejt> I guess it's time I leant how to interface to foriegn code, any pointers ?<br />
<br />
----<br />
<br />
<Riastradh> There's no Greek letter for it that I can confuse people with?<br />
<br />
The "it" refers to the monadic bind operation.<br />
<br />
----<br />
<br />
<Darius> ($$$) :: HardWork -> Dedication -> IO Money<br />
<Darius> _ $$$ _ = ioError "Ideology overflow"<br />
<br />
----<br />
<br />
Ninja Jones does a not-too-far-off parody of a certain flavor of visitor to #haskell<br />
<br />
*** highlyInterested (~ijones) has joined channel #haskell<br />
<highlyInterested> hi! I'm highly interested, but have no attention span!!!<br />
<highlyInterested> Can anyone help me?!?!?<br />
<nowiki>*</nowiki> highlyInterested runs around!!<br />
*** highlyInterested (~ijones) has quit: Client Quit<br />
<br />
----<br />
<br />
January 9, 2003:<br />
<br />
Heffalump: I need to teach my girlfriend temporal logic.<br />
Marvin--: how so?<br />
Heffalump: she seems to have problems with the "until" operator.<br />
<br />
----<br />
<br />
VersusQuotesPage<br />
<br />
----<br />
<br />
(Ok, remove these c.l.s quotes (or move to some other page) if deemed unappropriate for this QuotesPage !)<br />
<br />
seen on news://comp.lang.scheme :<br />
<br />
From: Shriram Krishnamurthi <sk@cs.brown.edu><br />
Newsgroups: comp.lang.scheme<br />
Subject: Re: What happened to schemers.org?<br />
Date: 17 Sep 2002 11:53:53 -0400<br />
Organization: Brown University<br />
<br />
Luigi Ballabio <luigi.ballabio@fastwebnet.it> writes:<br />
<br />
> I just checked to site only to find out that it was taken over<br />
> by the Dept. of CS at Brown. Is the old site still alive somewhere?<br />
<br />
The Revolution has begun. The department has been taken over.<br />
Comrade Shivers's helicopter will land on College Green at 3.14pm.<br />
Deployment of the Underground begins soon thereafter. Lambda bandanas<br />
will be available at the corner of Thayer and Waterman. Please remain<br />
calm and nobody will get skewered on parentheses.<br />
<br />
[snipped]<br />
<br />
Cmde. Shriram<br />
<br />
From: ds26@goldshoe.gte.com (Dorai Sitaram)<br />
<br />
In article <w7d1y7slii6.fsf@cs.brown.edu>,<br />
Shriram Krishnamurthi <sk@cs.brown.edu> wrote:<br />
>Luigi Ballabio <luigi.ballabio@fastwebnet.it> writes:<br />
[snipped]<br />
<br />
3.14 *pm*, huh? Underground types (once so strong and<br />
dynamic) seem to be getting rather soft and lazy<br />
these days.<br />
<br />
From: "Anton van Straaten" <anton@appsolutions.com><br />
<br />
Dorai Sitaram wrote:<br />
[snipped]<br />
<br />
There's such a thing as being too eager, you know. You wouldn't want an<br />
organization like the Underground to remain static, now, would you? That<br />
might make them weak, and then they'd need a strict hand to recover the type<br />
of discipline they're known for...<br />
<br />
From: Joe Marshall <jrm@ccs.neu.edu><br />
<br />
MJ Ray <markj+0111@cloaked.freeserve.co.uk> writes:<br />
<br />
> Joe Marshall <jrm@ccs.neu.edu> wrote:<br />
> > Maybe the plans have shouldn't have been finalized.<br />
> > There is a lot of collective finger-pointing.<br />
><br />
> Please, this is exceptionally short.<br />
<br />
Damn, you caught me. But you raise an important point.<br />
<br />
> I think it's elaboration time.<br />
<br />
Perhaps, but this message may be read by people who, shall we say,<br />
`don't exercise proper hygiene' and I don't want them to take anything<br />
out of context.<br />
<br />
----<br />
<br />
<DeezNuts> whats the point of programming in haskell beyond it being a cute toy for math fans<br />
<mgoetze> DeezNuts: what's the point of programming in c++ beyond it being a cute toy for masochists?<br />
<br />
----<br />
<br />
<Pseudonym> Well, personally, I don't think dumb people should be let near a programming language.<br />
<br />
----<br />
<br />
<shapr> how will you know when you've written enough?<br />
<kosmikus> I don't really know yet, but one of the following:<br />
(a) if my supervisor tells me I have,<br />
(b) if every chapter heading has content following it,<br />
(c) if the deadline is there<br />
<shapr> that's an excellent heuristic<br />
<br />
----<br />
<br />
<Jerub> I wonder if any interesting languages are going to come out of this parrot thing.<br />
<CrewdenX> Jerub: is that the hybrid perl/python thing?<br />
<Heffalump> it's the common bytecode for the two, yes<br />
<stepcut> see, perl wasn't bad enough, so now you can make your code even more unreadable by written it a mixture of languages<br />
<Jerub> its actually the perl6 vm, but they're trying to be the be all and end all of VMs for languages.<br />
<Riastradh> And they're going to fail miserably and end up with something that sorta kinda works for Python and Perl and doesn't make sense for anything else.<br />
<Riastradh> But they'll persist and say 'ooh ooh look it has continuations so it must work for other languages!' causing more and more people to flock to them more and write more crappy compiler back ends and make the state of the main stream of programming languages suck even more.<br />
<Riastradh> Meanwhile, due to lack of person power, the quality functional language compilers will deteriorate into bitrot, so that the main stream idiots can say 'but look, it doesn't even have a library for X, so it must suck, and I won't even bother thinking about writing it, because my crappy language already has it!'<br />
<Riastradh> Then the revolution will come.<br />
<Riastradh> What happens then I leave up to your imagination, but I can tell you it won't be pretty for the main stream.<br />
<br />
----<br />
<br />
seen in an email from Simon Marlow,<br />
<br />
Simon's cheat sheet for getting fast Haskell code:<br />
Rule 1: don't use String I/O.<br />
Rule 2: Profile your program. Find the inner loop. Look for overloading. Squash. Repeat. Look for laziness. Squash. Repeat.<br />
<br />
----<br />
<br />
Haskell poetry : 16:50 < shapr> the snow falls slowly, the lambdas are lifting, weak head normal form<br />
<br />
----<br />
<br />
/DuelsPage<br />
<br />
----<br />
<br />
<SyntaxNinja> it is a little disturbing when lambdabot starts channeling shapr<br />
<Riastradh> What about when shapr starts channeling lambdabot?<br />
<Riastradh> shapr: @yow<br />
<shapr> I was in MINNETONKA!<br />
<shapr> Butch Cassidy had my children!<br />
<Riastradh> shapr: @eval (X X X) (X (X X)) (X (X X)) ((X (X X) (X X X))<br />
<br />
----<br />
<br />
15:50 < Marvin--> remind me to prod Koen about releasing a new version of QC<br />
15:50 < shapr> Marvin--: hey, could you prod Koen about ...<br />
15:50 < Marvin--> huh?<br />
15:50 < Marvin--> about what?<br />
15:50 < shapr> about releasing a new version of QC!<br />
15:50 * Marvin-- has even shorter attention span than shapr!<br />
<br />
----<br />
<br />
Simon Marlow's How to Translate C to Haskell:<br />
<br />
> On Thu, Mar 25, 2004 at 01:38:44AM +1100, Alex Gontcharov wrote:<br />
> > Hi,<br />
> ><br />
> > I am new to haskell and would look to write a function equivalent<br />
> > to the following loop in C<br />
> ><br />
> > int value = 500000;<br />
> > int part_stack[4];<br />
> > int *part_ptr = part_stack;<br />
> > for (; value; value /= 10000)<br />
> > *part_ptr++ = value % 10000;<br />
><br />
> part_stack :: [Int]<br />
> part_stack = [0,50]<br />
><br />
> Note that I've performed a memoization optimization--this<br />
> makes the code both smaller, faster and easier to read! :P<br />
<br />
Ignore David, he's pulling your leg. Here's the proper translation:<br />
<br />
do<br />
alloca $ \value -> do<br />
poke value (500000::Int)<br />
allocaArray 4 $ \part_stack -> do<br />
alloca $ \part_ptr -> do<br />
poke part_ptr part_stack<br />
let loop = do<br />
val <- peek value<br />
if val == 0 then return () else do<br />
p <- peek part_ptr<br />
poke p (val `rem` 10000)<br />
poke part_ptr (p `plusPtr` 1)<br />
poke value (val `quot` 10000)<br />
loop<br />
loop<br />
<br />
Cheers,<br />
Simon<br />
<br />
----<br />
<br />
IRL is short for "in real life" and refers to face to face communication<br />
<br />
<bring> it seems it's a lot easier to get into a heated discussion (flamewar if you will) in irc, email or news than irl<br />
<bring> something about the lack of non-verbal communication<br />
<shapr> I think assholes don't survive IRL<br />
<bring> making someone not survive must surely count as non-verbal communication<br />
<br />
----<br />
<br />
there's the port we've been missing...<br />
<br />
<ozone> shapr: hugs has been ported to an apple IIIc?<br />
<ozone> shapr: MAIN :: IO (); MAIN = DO PUTSTRLN "GODDAMN CAPS"<br />
<br />
----<br />
<br />
sig seen on usenet :<br />
<br />
--<br />
<nowiki>.:[ dave benjamin: ramen/[sp00] -:- spoomusic.com -:- ramenfest.com ]:.</nowiki><br />
<nowiki>: please talk to your son or daughter about parametric polymorphism. :</nowiki><br />
<br />
----<br />
<br />
In the spirit of the above quote:<br />
<br />
"But I don't _want_ functional programming!"<br />
-- Sarah Peyton Jones, age 11, upon hearing the rules of Go<br />
<br />
----<br />
<br />
Sometimes I wonder if Java will be indirectly responsible for hastening the adoption of functional programming languages by providing a caricature of procedural OO. -- Christopher Hendrie<br />
<br />
----<br />
<br />
<kosmikus> is there a good english translation for the german word gleichnamig"?<br />
<kosmikus> basically: The Chapter "Type-indexed datatypes" is based on the ... paper.<br />
<Igloo> I'd say "on the paper of the same name"<br />
<Shammah> earthy: but apparently german can do it in one word, and we can't be letting the germans get away with a shorter phrase than us for the same concept!!! ;)<br />
<earthy> `Das Kapittel `Type-indexed data types' ist auf dem gleichnamigen Artikel basiert'<br />
<earthy> `The chapter `Type-indexed data types' is based on the article of the same name'<br />
<earthy> you count. :)<br />
<earthy> `Het hoofdstuk `Type-indexed data types' is op het gelijknamige artikel gebaseerd'<br />
<shapr> Det kapitel `Type-indexed data types' &#228;r grunded av det artikel med samma namn.<br />
<earthy> `Le chapitre `Type-indexed data types' est bas&#233; sur l'article du m&#234;me nom'<br />
<adept> Here's in russian: òÁÚÄÅÌ "éÎÄÅËÓÉÒÏ×ÁÎÎÙÅ ÔÉÐÁÍÉ ÔÉÐÙ ÄÁÎÎÙÈ" ÏÓÎÏ×ÁÎ ÎÁ ÏÄÎÉÍÅÎÎÏÊ ÓÔÁÔØÅ<br />
<br />
----<br />
<br />
during a discussion about writing a real-time strategy game in Haskell....<br />
<br />
<shapr> so my idea was to write a strategy combinator library<br />
<det> shapr: you crazy haskellers, a special tool for every program!<br />
<shapr> nah, a way to program your units<br />
<det> shapr: Function Ractive Arrows with Monadic covariance, HOW CAN MY RTS FAIL!<br />
<br />
----<br />
<br />
<Igloo> Waah. LaTeX hates me.<br />
<lispy> Igloo: why is that?<br />
<Igloo> Because it's cast from pure liquid evil, probably<br />
<br />
----<br />
<br />
<Jerub> shapr: we have a new manager. she complained of a bad heart when I told her we didn't have revision control.<br />
<br />
----<br />
<br />
one minute after the 2004 ICFP programming contest task was announced...<br />
<br />
<Lor> This looks pretty darn cool.<br />
<Lor> This also looks pretty darn non-trivial.<br />
<tmoertel> Lor: No, it *is* trivial: Just de-compile a real ant and reverse engineer it.<br />
<tmoertel> :P<br />
<br />
----<br />
<br />
<stepcut> in unrelated news, I think I want to produce and air an infomercial<br />
<stepcut> but I am not sure what to sell yet<br />
<Riastradh> Arrows!<br />
<stepcut> "For just 5 easy payments of $29.95 you can learn haskell in my fun and easy video series"<br />
<stepcut> "You'll have the biggest Monads on your block!"<br />
<stepcut> "Do you want your own house, yacht, or beowolf cluster? Of course you do! With the skills you will learn in my haskell course, and 10 million dollars, you can get all these things AND MORE!"<br />
<blackdog> "Destroy your lucrative career as a Java programmer: Learn Haskell!"<br />
<clausen> how about a spiritual add?<br />
<clausen> "the purity of haskell helped me to deal with the kids, work and the stress of a fast-pace life"<br />
<blackdog> there must be a way to use haskell to sell exercise equipment. they've used everything else.<br />
<stepcut> "I used to be a fat lazy slob, but now, thanks to haskell, I am fully functional..."<br />
<Riastradh> '...and I can still be lazy!'<br />
<br />
----<br />
<br />
<Igloo> Syn: You're looking at how WASH works and are in charge of the cabal project, and you're asking /us/ if cabal 0.1 will handle WASH? :-)<br />
<br />
----<br />
<br />
seen on #java:<br />
<br />
(14:21:13) ricky_clarkson: Is Haskell an interface between programming languages and academics?<br />
<br />
----<br />
<br />
roconnor has joined #haskell<br />
<roconnor> ?<br />
<Riastradh> !<br />
<roconnor> oh, nevermind. I figured it out.<br />
<br />
----<br />
<br />
<Igloo> Oh, I'm going to sue you for emotional trauma, BTW<br />
<Marvin--> uh-oh<br />
<Igloo> I had to use unsafeCoerce# 3 times to write my gtk2hs program<br />
<Marvin--> ouch<br />
<Igloo> I think I'll be scarred for life<br />
<Marvin--> :-/<br />
<br />
----<br />
<br />
The acronym TMI is short for Too Much Information!<br />
<br />
<desrt> wtf. i just opened up my underwear drawer and there was a network card in it<br />
<shapr> desrt: you're a sick sick puppy<br />
<earthy> TMI<br />
<earthy> I won't be borrowing any hardware of desrt anytime in the future, that's for sure ;)<br />
<desrt> earthy; it's all cool. it was in with the socks<br />
<br />
----<br />
<br />
<desrt> how do i turn on PIC code generation for ghc?<br />
<shapr> -fPIC maybe?<br />
<desrt> no<br />
<shapr> -fThaller ?<br />
<desrt> ghc-6.2.2: unrecognised flags: -fThaller<br />
<desrt> :(<br />
<br />
----<br />
<br />
Just after a discussion of Microsoft's involvement in the Haskell world...<br />
<br />
<CosmicRay> Is there a way to, say, convert from a Word32 to a Word8 when I know the data in question will fit in a Word8?<br />
<drlion> CosmicRay: just open the file and Word will ask you to convert it<br />
<br />
----<br />
<br />
<Philippa> I'm fed up of writing uglyprinters for values inside an interpreter<br />
<br />
----<br />
<br />
<kristnjov> QuickCheck is god<br />
<nowiki>*</nowiki> earthy thinks kristnjov has a *weird* religion<br />
<kristnjov> it's called hughes-ism<br />
<kristnjov> a bit new age<br />
<blackdog> this y combinator, which was given to you for the recursion of sins<br />
<earthy> lead me not into global state<br />
<blackdog> yea, though I should walk in the valley of imperative code, I shall fear no evil, for your monad comforts me still<br />
<br />
----<br />
<br />
ISAGN is irc-speak for "I see a great need"<br />
<br />
<nowiki>*</nowiki> shapr throws a lambda boomerang<br />
<Igloo> ISAGN<br />
<shapr> Maybe if ICFP is in .au one year, they can give them away as the entrance gift.<br />
<Igloo> That sounds dangerous. Best to give them away as exit gifts<br />
<ski> or moooonad didgeridoos<br />
<br />
----<br />
<br />
<jemfinch|lambda> maybe I'll write an IRC bot in Haskell or SML.<br />
<dash> what's wrong with lambdabot?<br />
<dash> other than an excess of sarcasm<br />
<br />
----<br />
<br />
during a discussion of endomorphisms, hylomorphisms, catamorphisms, anamorphisms...<br />
<br />
<stepcut> endo-hylo-cata-ana-expi-ali-docious<br />
<br />
----<br />
<br />
<edi> What's SPJ ?<br />
<jadrian> Simon P. Jones<br />
<jadrian> edi: http://research.microsoft.com/Users/simonpj/<br />
<shapr> SPJ is a large part of the reason Haskell is so cool.<br />
<shapr> I'm an obsessive research paper downloader/reader, and I still haven't read everything I have on-disk by SPJ.<br />
<jadrian> shapr: I think SPJ is an obsessive paper uploader/writer, so it's going to be tough competition :)<br />
<br />
----<br />
<br />
<shapr> Tom Lord is darcs' archenemy!<br />
<CosmicRay> shapr: and he's also carpal tunnel's best friend.<br />
<br />
----<br />
<br />
<pesco> I'm currently reading Asimov's Foundation trilogy and Haskell strangely reminds me of the Foundation. I'm just wondering how "avoid success at all costs" fits into the picture.<br />
<shapr> speed of change<br />
<pesco> Exactly!<br />
<shapr> Not sure if that fits into the Foundation trilogy though.<br />
<pesco> Of course! They don't strive to expand and conquer rapidly.<br />
<pesco> They just follow the plan.<br />
<nowiki>*</nowiki> shapr tries to remember all the details of Hari Seldon's plan.<br />
<Igloo> And every year the image of SPJ appears at HW to impart new knowledge upon us...<br />
<Igloo> And it looks so real!<br />
<br />
----<br />
<br />
?CosmicRay introduces us to his treacherous megahal bot...<br />
<br />
<Pseudonym> megamonad, what is haskell?<br />
<MegaMonad> Pseudonym: Well, i'd ask john hughes about using haskell actually.<br />
<Pseudonym> Good advice.<br />
<Pseudonym> megamonad, what is scheme?<br />
<MegaMonad> Pseudonym: Man i love scheme.. So i'll do freelance coding of this is a neat solution.<br />
<Riastradh> MegaMonad, but what _is_ Haskell?<br />
<MegaMonad> Riastradh: It's is always stupid peoples to do this in haskell.<br />
<br />
----<br />
<br />
<bringert> I think the main problem with haskell is that memory use can be hard to predict<br />
<bringert> don't get me wrong, I find it the best language for most things<br />
<bringert> sure, Java uses lots of memory, but I find it easier to predict memory use in java<br />
<bringert> i.e. always lots of it :)<br />
<br />
----<br />
<br />
<lyceen> I speak english, german french and dutch lol<br />
<ibid> what's this language "lol"? never heard<br />
<Lemmih> ibid: It's from the strange land of counter-strike players and noobs.<br />
<ibid> Lemmih: figures<br />
<ibid> are there different dialects, english lol, german lol, and perhaps ... dutch lol?<br />
<Lemmih> I think it means 'end statement' or ';' from C.<br />
<br />
----<br />
<br />
"Haskell is the least-broken programming language available today."<br />
-- Havoc Pennington http://ometer.com/books.html<br />
<br />
----<br />
<br />
<Pseudonym> Ah, poor spouse of mine.<br />
<Pseudonym> She's hit a Windows bug where every few minutes, without fail, it tells her that it's found a new printer.<br />
<Pseudonym> The one which is already installed.<br />
<Pseudonym> "It's like Chinese water torture!"<br />
<Pseudonym> "GOD MAKE IT STOP!!!!!!!"<br />
<Pseudonym> I tried to explain to her that God has no jurisdiction over Windows, and she should talk to the other guy instead. She was not impressed.<br />
<br />
----<br />
<br />
<chip> It seems to me that the authors of the C++ template rules learned Haskell, then got drunk and added it to C++<br />
<chip> process _ _ target "dict" _ = do<br />
<chip> process _ _ target "dict-help" rest = do<br />
<chip> process _ _ target cmd rest = do<br />
<chip> I could spell that in about a screen of C++ templates. Except for the string part. It'd have to be basic values like integers, or enums, or something else that's known and comparable at compile time.<br />
<br />
----<br />
<br />
"I spent about an hour figuring out how to encode things, and working through the type errors, and then of course, it just worked. Yes, I know that this is exactly what haskell is all about, so of course it worked. But it felt so<br />
good to experience it, instead of just hearing about it." -- http://www.kimbly.com/blog/000030.html<br />
<br />
----<br />
<br />
<the_learner> CAN HASKELL BE USED NOW IN A STARTUP TO MAKE MONEY<br />
<wli> the_learner: haskell.org is indeed the root of all MAKE.MONEY.FAST methods<br />
<the_learner> NICE<br />
<the_learner> OK PERL OR HASKELL<br />
<wli> the_learner: ISN'T IT?<br />
<musasabi> I think that making money has little to do with technical quality or the lack of that ;)<br />
<wli> the_learner: HASKELL OF COURSE<br />
<the_learner> HASKELL SEEMS TO HAVE LOTS OF UNFINISHED SUPPORT LIBARY<br />
<the_learner> OK<br />
<the_learner> GNIGHT 4 NOW<br />
<mflux> it's a darn shame I've sacrificed my caps lock for other purposes :-/<br />
<wli> the_learner: HASKELL DOESN'T NEED THE SUPPORT LIBRARIES; ITS ABSTRACTIONS ARE HIGHER-LEVEL<br />
<br />
----<br />
<br />
<Gahhh> monads are usually a personal experience.<br />
<br />
----<br />
<br />
<shapr> I've tried to teach people autodidactism, but I've realized they have to learn it for themselves.<br />
<br />
----<br />
<br />
<Pseudonym> OK, so I try to find stylesheets for magazine-type documents.<br />
<Pseudonym> And I search for "latex magazine".<br />
<Pseudonym> There are some weird magazines out there.<br />
<br />
----<br />
<br />
<SyntaxNinja> Fromagxo: NOT is not not in haskell, nor is "!", but rather, not.<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> autrijus stares at type Eval x = forall r. ContT r (ReaderT x IO) (ReaderT x IO x) and feels very lost<br />
<shapr> Didn't you write that code?<br />
<autrijus> yeah. and it works<br />
<autrijus> I just don't know what it means.<br />
<br />
----<br />
<br />
<SyntaxNinja> I think that the compiler authors will fly here from england just to kill me if I did that<br />
<br />
----<br />
<br />
<samc__> monads are hard, let's go shopping<br />
<br />
----<br />
<br />
<desrt> it was sort of funny. i was sitting in the optimisation lab once and wolfram came in and started talking to wolfgang in german<br />
<desrt> so i'm like "it's awful rude you know, speaking a language that i don't understand right in front of me"<br />
<desrt> so they switch to english, but they were talking about category theory, so i still didn't understand them :(<br />
<br />
----<br />
<br />
"There is a VCS named darcs, which is much more flexible, but is specced using quantum physics language and written in a scary language called Haskell."<br />
<br />
-- AutrijusTang at [WWW]A Plan for Pugs<br />
<br />
Is it just me or does this so crystallize the popular view of Haskell? -- DerekElkins<br />
<br />
----<br />
<br />
After a long series of questions on #haskell from someone writing their own language:<br />
<br />
<autrijus> I think Haskell excels at everything but user base :)<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> Darius imagines XSLT programmers say "It's a one pager" the way most other programmers say "It's a one liner".<br />
<br />
----<br />
<br />
<Forest> why do they make condoms with different smells ?<br />
<Lemmih> Is that a lead-in to a joke or a real question?<br />
<Forest> it's a question<br />
<RemiTurk> now, a question back to Forest: what's its relation to haskell?<br />
<Forest> RemiTurk: learning haskell is a kind of f...ing<br />
<Forest> for first time<br />
<bringert> Forest: how so?<br />
<Forest> bringert: i meant for brains<br />
<bringert> it's awkward the first time, but as you go along you gain experience and confidence. most people enjoy it enough that they continue doing it for the rest of their lives.<br />
<br />
----<br />
<br />
<jjang> Lemmih: dont u have a sourceforge page or so for the module?<br />
<Heffalump> ick, he said sourceforge :-)<br />
<Lemmih> jjang: It's just a small pet project. Nothing serious.<br />
<jjang> why not make it serious<br />
<Lemmih> jjang: And shapr is kinda like sourceforge.<br />
<jjang> ok<br />
<jjang> never heard of shapr<br />
<Heffalump> it's much more intelligent<br />
<Heffalump> better designed<br />
<Heffalump> a touch eccentric, perhaps<br />
<jjang> shapr.org?<br />
<Heffalump> even has a bot on the channel<br />
<vincenz> jjang: shapr is a concept<br />
<jjang> oh<br />
<br />
----<br />
<br />
<shapr> In my experience, Flash is mostly used as the hi-tek replacement for <BLINK><br />
<br />
----<br />
<br />
Life is Hard, But Life is Harder When You're Dumb -- The Austin Lounge Lizards<br />
<br />
----<br />
<br />
seen on #perl6<br />
<br />
<cognominal> autrijus: what is the GADT ,entionned in your journal?<br />
<cognominal> stands, for Glasgow Abstract Data Tree?<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> dons keeps typing 'darcs' when he really means to type 'cvs'<br />
<blackdog> the rest of the world keeps typing cvs when they should be typing darcs...<br />
<br />
----<br />
<br />
<sethk> Are nomads the reproductive organs of Haskell? After all, something does go in and something else usually comes out... ok, kind of lame, but it is 5 AM.<br />
<br />
----<br />
<br />
Refering to typed lambda calculus as "plain ol' code" may be a sign that I need to re-examine some of my prejudices about formalisms. :-) -- LukeGorrie<br />
<br />
http://lambda-the-ultimate.org/node/view/92/536#comment-536<br />
<br />
----<br />
<br />
<pesco> Heh, to deprecate means "to ward off by prayer" in its latin root. Hehe.<br />
<br />
----<br />
<br />
<Gahhh> I told my boss that I had learned Haskell and it made me a better programmer, he gave me the puzzled look you give to homeless people claiming to be Jesus.<br />
<br />
----<br />
<br />
<shapr> Oleg will do something terrifying like implementing type checking in tcp/ip checksums on the router level through some emergent property of BGP and he'll do it all with HSP!<br />
<br />
----<br />
<br />
seen on #debian-devel<br />
<br />
<dilinger> trave11er: CosmicRay's weblog hasn't led me astray yet :P<br />
<trave11er> dilinger: i cannot trust people who can write a 100+ line haskell program :-)<br />
<trave11er> that's almost a legal definition of insanity<br />
<Igloo> You're right; Haskell is such a concise, elegant language that anyone who stretches a program beyond 100+ lines is clearly doing something wrong<br />
<br />
----<br />
<br />
<Huschi> is there a good way to make the first argument of a function the last one?<br />
<skew> Huschi: hand the other party in the argument a gun<br />
<br />
----<br />
<br />
<blackdog> kallo, kallay: my grilf dragged me along to a ceramics class, and I now have a mug with a lambda on one side and the legend "go away, or i will replace you with a trivial lambda expression" on the other.<br />
<br />
(grilf == girlfriend I assume?) (your assumption is correct. i shall get some pictures and post. (unfortunately, i've just realised that the lambda looks an awful lot like the half-life logo, so i'm expecting some confused faces.) --blackdog)<br />
<br />
----<br />
<br />
I'm personally of the opinion that functional programming makes it even harder to shoot yourself in the foot, but when you do, all that's left are a few strands of red goo dangling from the shattered remains of your brain pan.<br />
<br />
--Mike Stone in http://www.perlmonks.org/?node_id=450922<br />
<br />
----<br />
<br />
<wagle> A math professor I once worked for asked me several years ago what I was doing these days. I must have said something like "anything but computer science". He asked "why's that?" I spouted passionately at length why not. He said something like "oh, computer science IS your field!"<br />
<br />
----<br />
<br />
(17:20:51) JohnMeacham: The Hierchical Modules report does contain a section about how it maps to the filesystem, but it specifically says that this is not a part of the specification and just a possible implementation.<br />
(17:21:15) JohnMeacham: This is why I felt okay about jhc breaking it :)<br />
(17:21:25) SamB: nobody is crazy enough to implement it elsehow, though<br />
(17:21:42) CosmicRay: SamB: some crazy people hang out here<br />
<br />
----<br />
<br />
<skew> I think it's pretty neat how other languages struggle and sweat to add new stuff like continuations, and in Haskell somebody just applies about 20,000 IQ-years and invents another monad<br />
<br />
----<br />
<br />
<JohnMeacham> That's a lot of cows.<br />
<br />
----<br />
<br />
<shapr> Where's my socks!?<br />
<shapr> Finding my socks seems to be an NP-complete problem to me.<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> dons X11s his curses installation<br />
<br />
----<br />
<br />
<lambdabot> I'm sitting on my SPEED QUEEN ... To me, it's ENJOYABLE ... I'm WARM<br />
<lambdabot> ... I'm VIBRATORY ...<br />
<dons> yikes!<br />
<dons> hmm. looks like @vixen has been talking to @yow<br />
<br />
----<br />
<br />
seen on #perl6<br />
<br />
<autrijus> using Haskell is like having the power of Reason.<br />
<autrijus> all bad guys listen to Reason.<br />
<br />
----<br />
<br />
(2005.05.30) Lambdabot is female<br />
<br />
<boegel> oh, okay, you're a experienced user then... ever heard about lambdabot ?<br />
<boegel> she's cool<br />
<SyntaxNinja> boegel: lambdabot is a girl?<br />
<boegel> SyntaxNinja: yeah, sure, why not ? :)<br />
<Biker> boegel: I have seen it working here... not used it myself though<br />
<Biker> yeah... she could be :)<br />
<br />
----<br />
<br />
<xerox> What could it mean something like this? "<nowiki><TITLE>Error</TITLE><BODY><H1>Error</H1>FW-1 at sentry2.york.ac.uk: Access denied.</BODY></nowiki>"<br />
<Itkovian> that you're screwed?<br />
<boegel> a HTML-page saying some error has occured ?<br />
<dblhelix> is this a quiz?<br />
<br />
----<br />
<br />
seen on #perl6<br />
<br />
<Limbic_Region> learning Haskell to me is akin to learning an alien (as in space) language<br />
<br />
----<br />
<br />
On #haskell:<br />
<br />
<xerox> I can't read other languages than Haskell anymore, I have the _physical_ need to know the type of the functions used.<br />
<br />
----<br />
<br />
<olliej> java is a great language<br />
<olliej> i like to eat toothpaste<br />
<olliej> :)<br />
<br />
----<br />
<br />
<shapr> Yeah, it does require more than an oleg of type-hackery.<br />
<poetix> oleg's now a unit?<br />
<autrijus> is oleg an unit now?<br />
<shapr> Yup, a rather large unit of type-hackery too.<br />
<br />
----<br />
<br />
<tomdavie> buh... I wish people would stop asking for my source... I keep having to do a make realclean, and then spending half an hour buinding again :(<br />
<nowiki>*</nowiki> earthy grinz<br />
<tomdavie> I suppose I could just back up the work... but hey... that would be inteligent<br />
<earthy> why not manage the stuff with darcs and have a clean tree and a build tree? :)<br />
<earthy> oh right, we don't want to think, we're lazy functional programmers. :P<br />
<br />
----<br />
<br />
<boegel> [BAF64]: you should ask lambdabot, she seems to be willing to donate<br />
<Igloo> [BAF64]: Are you here purely to beg for donations?<br />
<mauke> @vixen are you willing to donate?<br />
<[BAF64]> I'm not begging for donations.<br />
<xs_> oh, lilo needs rent?<br />
<lambdabot> yes, i am<br />
<Igloo> [BAF64]: If you're not here to talk about Haskell, please can you leave?<br />
<[BAF64]> Igloo, sure<br />
<[BAF64]> lambdabot, if you want more info, join #freenode<br />
<nowiki>*</nowiki> [BAF64] (ferrisr@69-169-198-47.sbtnvt.adelphia.net) has left #haskell ("Leaving")<br />
<Igloo> lol!<br />
<br />
----<br />
<br />
<autrijus> Perl: "Easy things are easy, hard things are possible"<br />
<autrijus> Haskell: "Hard things are easy, the impossible just happened"<br />
<br />
----<br />
<br />
<gennet1> i guess i just want the one language to rule them all ;)<br />
<earthy> one language to rule them all, one language to find them, one language to bring them all and in the darkness enthrall them, in the land of ICFP, where the programmers lie?<br />
<br />
----<br />
<br />
Sleep deprivation is bad!<br />
<br />
<Speck> Oh my god. Crickets in the basement.<br />
<Speck> Hundreds of them.<br />
<br />
----<br />
<br />
A http://www.cs.vu.nl/boilerplate/ parody:<br />
<br />
<shapr> autrijus: What's the title of your fabled article? Boil your ScratchPad with Style?<br />
<autrijus> shapr: it's "Boil your scratchpad", "Boil other people's scratchpads", and "Boil your scratchpad with proles". The full name of the first one is "Boil your scratchpad - Genetic frogging in Haskell"<br />
<Pseudonym> Aren't you supposed to boil a frog slowly?<br />
<autrijus> right, that's why genetic frogging is slow<br />
<Pseudonym> And what do the proles have to do with it?<br />
<autrijus> the idea is no-one with class -- not even middle class -- will bother themselves with frog boiling; it offends their bourgeois taste. so need proles to do that<br />
<dons> I see, boiling scratchpads without class<br />
<autrijus> yup.<br />
<br />
----<br />
<br />
<Speck> "That's like cheating. It isn't even programming. You just tell it what to do and it does it." -- My friend upon seeing some Haskell code<br />
<br />
----<br />
<br />
<Beelsebob> DAMN IT! There's a fly *in* my monitor<br />
<Beelsebob> it's somehow got between the LCD and the backlight<br />
<Beelsebob> it seems to have got scared by me chasing it with a cursor<br />
<Beelsebob> ARGH! There's two now<br />
<Beelsebob> has some fly made a nest in there or something?<br />
<Beelsebob> I may have to take this monitor apart<br />
<br />
----<br />
<br />
<Cale> stepcut: You know a library is good when just reading about it removes the particular task it performs from your life altogether.<br />
<br />
----<br />
<br />
<autrijus> (type inference)++ # no need to be a strong typist to enjoy strong typing<br />
<br />
----<br />
<br />
From http://www.perl.com/pub/a/2005/07/28/test_builder_p6.html<br />
<br />
"My productivity increased when Autrijus told me about Haskell's trace function.<br />
He called it a refreshing desert in the oasis of referential transparency."<br />
-- chromatic, on hacking Pugs to implement a unit test framework for Perl 6<br />
<br />
----<br />
<br />
Seen on #haskell:<br />
<br />
goron: Ah.. the halting problem is easy. Step 1 wait an infinite time Step2 Check whether the program halted.<br />
<br />
----<br />
<br />
<darix> the problem with haskell is<br />
<darix> the learning curve is like a mountain in the himalaya ...<br />
<darix> nearly 90degree and close to 8000 m<br />
<darix> but standing up the hill just rocks ;)<br />
<br />
----<br />
<br />
*** mwc (n=matt@CPE0030654f85d8-CM00137189c512.cpe.net.cable.rogers.com) has joined channel #haskell<br />
<mwc> I think that we ought to treat cats that have been sprayed by skunk with the same method as horses with broken legs.<br />
<mwc> After 20 minutes of wet cat Judo, I'm utterly convinced they don't like the common treatment<br />
<mwc> after all that biting, scratching, and attempts to jump out despite me holding its chest down, I decided not to bother drying the little bugger off<br />
<mwc> just threw outside to air dry<br />
<mwc> although after that ordeal the clothes dryer was looking MIGHTY attractive<br />
<mwc> so, that was how my day got started<br />
<br />
----<br />
<br />
<exa> so did haskell have an eval function?<br />
<exa> i remember something like a generic programming tool that allowed you to construct syntax trees but i'm not sure<br />
<nowiki>*</nowiki> exa loves genericity!<br />
<exa> +1 for type classes :)<br />
<stepcut> exa: dons wrote a hsplugins thing that has an eval function<br />
<Philippa> and template haskell effectively has compile-time eval<br />
<autrijus> and you can load hsplugins during compile time too.<br />
<autrijus> (via runIO)<br />
<Philippa> and use TH in plugins<br />
<autrijus> and generally become dangerously close to insanity<br />
<Philippa> I mean really, once we have boxy types and proper existentials... what'll the point of smalltalk /be/? :-)<br />
<br />
----<br />
<br />
On #haskell:<br />
<br />
Heffalump: I think you'll find I'm trolling, not flaming. Pay attention.<br />
...<br />
dcoutts: Heffalump, yeah, you can't really troll when we know you. Come back under another nick and it might work.<br />
<br />
----<br />
<br />
On #haskell:<br />
<br />
22:17 * poetix thinks xerox should write a book on UI programming in Haskell<br />
22:17 < Marty> that's what i'm saying ;)<br />
22:17 < xerox> A _book_ ?!<br />
22:17 < poetix> Get it published by O'Reilly<br />
22:18 < xerox> We could choose an animal for Haskell that way!<br />
22:18 < poetix> Exactly! But which animal?<br />
22:18 < vegai> Sloth?<br />
22:18 < vegai> isn't it obvious? =)<br />
22:18 < poetix> Slime mold?<br />
22:18 < xerox> Something between myth, fantasy and dream.<br />
22:18 < vininim> a catterpillar =p<br />
22:18 < basti_> -g-<br />
22:18 < basti_> with a hookah<br />
22:19 < poetix> Well, we know Haskell is a drug<br />
22:19 < xerox> Yes.<br />
22:19 < basti_> ohh.<br />
22:19 < xerox> So.. hypotic toad?<br />
22:19 < basti_> comparable to what?<br />
22:19 < xerox> *hypnotic tad<br />
22:19 < poetix> liftIO makes you larger, and foldR makes you small<br />
22:19 < poetix> And the id that mother gives you, doesn't do anything at all<br />
22:20 < vininim> o_o<br />
22:20 < basti_> lol<br />
22:20 < poetix> I am really not as old as quoting that makes me sound...<br />
<br />
----<br />
<br />
Seen is #haskell-blah<br />
<br />
poetix_: In ancient Athens, they used to punish adulterers by forcing radishes up their rectums<br />
boegel: poetix_: sounds like fun !<br />
<br />
----<br />
<br />
< int-e> @eval takeWhile ([]/=) $ map (take 2) $ iterate (drop 2)<br />
< schyffe> thanks<br />
< Igloo> unfoldr (\xs -> if null xs then Nothing else Just (splitAt 2 xs)) -- unfoldr strikes again!<br />
< int-e> neat. thanks Igloo<br />
<nowiki>*</nowiki> Heffalump thinks int-e's is clearer<br />
< Igloo> Yes, but mine uses unfoldr<br />
< Heffalump> precisely :-)<br />
< Igloo> I think you're missing the point here :-)<br />
< int-e> so null == ([]/=)<br />
< Heffalump> no, null == not.([]/=)<br />
<br />
----<br />
<br />
<ricebowl> what does >>= do?<br />
<basti_> ricebowl: monads are cute pink fuzzy little things.<br />
<gzl> with plutonium inside.<br />
<br />
----<br />
<br />
Seen on #ruby-lang<br />
<br />
<shevegen> haskell is cool but i personally find it very difficult<br />
<GnuVince> That being said, I hear it's a very nice and fun language, although some things are hard to do in a purely functionnal way<br />
<chris2> i prefer less strict languages<br />
<br />
----<br />
<br />
During a heated discussion:<br />
<br />
23:34 < shapr> Heffalump: You said that my assertions do Haskell a disservice. How does that work?<br />
23:35 < Heffalump> because if people believe you and then discover that you are wrong, they will be more suspicious of future claims by others<br />
23:35 < int-e> work_metaperl: try selling sodas and popcorn.<br />
23:36 < work_metaperl> then Heffalump and shapr will throw them at each other :)<br />
23:36 < Heffalump> eating it is better<br />
23:37 < autrijus> I'd like some pushcorns<br />
23:37 < xerox> Ã²karma- autrijus<br />
23:37 < autrijus> popcorns are overrated.<br />
23:37 < work_metaperl> the only use for soda is throwing it... either throwing it up or throwing it out<br />
23:37 < work_metaperl> it does not belong in the human body<br />
23:37 < shapr> Heffalump: So what? I'm not Haskell. We all just try to figure stuff out the best we can. I'm doing my best, I assume you're doing yours.<br />
23:37 < wagle> throwing popcorn in the exception monad?<br />
23:37 < work_metaperl> push corn, pop corn, unshift corn, shift corn<br />
23:38 < xerox> resetcorns<br />
23:38 < basti_> argh<br />
23:38 < autrijus> splicecorns<br />
23:38 < work_metaperl> :)<br />
23:38 < wagle> cornads<br />
23:38 < basti_> call/cccorns<br />
23:38 < work_metaperl> LOL<br />
23:38 < xerox> call-with-current-corn<br />
23:38 < work_metaperl> cornads .... LOLOLOL<br />
23:38 < Oejet> cocorns<br />
23:38 < xerox> ahah!<br />
23:38 < work_metaperl> lol<br />
23:38 < int-e> cornads are generalized stacks?<br />
23:38 < xerox> co-cornads<br />
23:38 < Heffalump> shapr: I'm just commenting on your opinions. I obviously don't have any power to make you act differently.<br />
23:38 < xerox> (along the lines of co-monads)<br />
23:38 < wagle> xerox: rnads<br />
23:38 < Oejet> xerox: Too late. :-P<br />
23:38 < astrolabe> Online discussions escalate too easily because of lack of non-verbal signals.<br />
23:38 < work_metaperl> thats so corny<br />
<br />
----<br />
<br />
<sethk> what's the definition of a supercombinator? what makes it super?<br />
<dave_m> sethk: supercombinators are only vulnerable to kryptonite<br />
<br />
----<br />
<br />
<ulfdoz> schemers are strange.<br />
<sieni> ulfdoz: why the call/cc would you think that?<br />
<br />
----<br />
<br />
<ValarQ> Oejet: i looked on a webpage that sells books for a haskell book today, i found one and on the page there was a note saying that people who bought that book also bought some book called "the paincarrier" (rough translation)<br />
<Philippa_> haskell's rare enough still that it doesn't take much to give a bookseller a link between it and (say) BDSM<br />
<Philippa_> hell, the only reason I've not contributed to that one myself is I've never bought a book on Haskell<br />
<br />
----<br />
<br />
<nowiki>*</nowiki> Korollary map hug #haskell<br />
<br />
----<br />
<br />
dons discovers the Google Maps API:<br />
<br />
<dons> and you can just zoom in until you see the locations at full res. huh. so this is how I track my enemies<br />
<br />
----<br />
<br />
Another C++ user enters the channel...<br />
<br />
<Megzl> The first task for Haskell would be to implement an L-System.<br />
<Cale> xerox and I wrote a nice L-System generator<br />
<Megzl> Show me the code.<br />
<Megzl> I'm interested in L-Systems; I've spent a ton of time coding them in C++.<br />
<Cale> http://www.haskell.org/hawiki/HaskellIrcPastePage<br />
<Megzl> That's too little code.<br />
<Cale> unfortunately, it involves some abstractions you don't know yet :)<br />
<Megzl> Where are all the other rules besides F.<br />
<br />
----<br />
<br />
No longer Test Driven Development, but intead:<br />
<br />
<autrijus> TDD is actually Tolkien-Driven Development.<br />
<br />
----<br />
<br />
<sieni> is yi+hide trying to be a replacement of emacs for haskell or are people going to incorporate all standard ide suckiness to hide as well?<br />
<dons> emacs for haskell, yes<br />
<dons> suckiness is an optional plugin<br />
<dons> you'll need to download that first<br />
<br />
----<br />
<br />
Seen on #perl6, discussing the weaponry of Haskell<br />
<br />
<autrijus> when I'm preparing the slides... it occured to me that most of the perculiar features in hs is there just so we can fearlessly golf^Wrefactor things, without putting the entire program logic into one's head<br />
<autrijus> aka the power of Reason -- as in Snow Crash<br />
<gaal> http://www.clubhyper.com/reference/images/Gau8a_a.jpg<br />
<gaal> it features strong typing, too, in a way.<br />
<gaal> you definitely know when you're at the wrong end of this fellow.<br />
<autrijus> and static, too<br />
<autrijus> if you stay at the right end you'll probably remain there<br />
<gaal> yes, it's very haskellish to call something static when it fires fifty rounds a second.<br />
<nowiki>*</nowiki> autrijus goes lifting -- I mean fmapping -- this picture into the talk<br />
<br />
----<br />
<br />
<musasabi> Haskell is pure Joy, and joy can be implemented in Haskell.<br />
<br />
----<br />
<br />
<sethk> I used to play in fairly loud bands but I always made sure the speakers were between the audience and me<br />
<sethk> Once they found a seriously high person _inside_ one of the big bass cabinets<br />
<br />
----<br />
<br />
<EdLin> obj c is a sort of cross between smalltalk and c<br />
<dfgp> If you fed Smalltalk lead until it became retarded. ;)<br />
<br />
----<br />
<br />
<dons> hmm, what's the opposite of serialising something ?<br />
<stefanw> deserialising?<br />
<dons> :( yeah, that's currently the function name I have. but it's ugly<br />
<dons> maybe i could use reify and, umm, what's the opposite of reifiying something?<br />
<ski> reflect<br />
<dons> ah, right.<br />
<nowiki>*</nowiki> ski thinks that's a bad idea, though<br />
<dons> hehe.<br />
<ski> hm ..<br />
<ski> 'deify' and 'deflect' ?<br />
<br />
----<br />
<br />
<JohnMeacham> not haskell related but interesting if you know wolfram or his work: http://www.cscs.umich.edu/~crshalizi/reviews/wolfram/<br />
Heh... it makes me wonder what sort of things we will be publishing in our quackery years,<br />
"Monads don't emulate the world, the world is a poor emulation of a monad."<br />
"The second law of thermodynamics as expressed via functional dependencies"<br />
<JohnMeacham> of course any minute now oleg is going to come along and actually express the second law of thermodynamics via functional dependencies as a purely incidental part of improving HList syntax or something.<br />
<br />
----<br />
<br />
<basti_> google has kind of a personality<br />
<basti_> a little like one the "great elder gods" in the cthuluh myth i think.<br />
<br />
----<br />
<br />
<astrolabe> lazyness is next to godliness<br />
<br />
----<br />
<br />
*** BigMike04 (i=BigMike0@d64-180-58-123.bchsia.telus.net) has joined channel #haskell<br />
<BigMike04> hey<br />
<BigMike04> does anyone can give a newbie here a guide to hack?<br />
<astrolabe> @learn<br />
<lambdabot> http://www.haskell.org/learning.html<br />
<BigMike04> @learn<br />
<lambdabot> http://www.haskell.org/learning.html<br />
<BigMike04> @learn<br />
<lambdabot> http://www.haskell.org/learning.html<br />
<BigMike04> opps sorry<br />
<astrolabe> :)<br />
<astrolabe> Give one of those a try<br />
<ski> @google yet another haskell tutorial<br />
<lambdabot> http://www.isi.edu/~hdaume/htut/<br />
<ski> @google haskell c tutorial<br />
<lambdabot> http://www.haskell.org/~pairwise/intro/intro.html<br />
<ulfdoz> Hack? He knows C!<br />
<ski> BigMike04 : check those out, too<br />
<BigMike04> i got one right here but it is exploit tut http://www.wifiscan.net/td/tutorials/exploits.htm<br />
<BigMike04> now, any of you guys actually hack?<br />
<Korollary> Ugh<br />
<Speck> I think we have different working definitions of "hack"<br />
<ulfdoz> I prefer "to program".<br />
<Korollary> "that" kind of hacking... umm no.<br />
<Lemmih> I so hope you're a bad joke.<br />
<astrolabe> You need to say 'where hack = ...'<br />
<Speck> the best advice I can give if you want to learn how to be a hax0r is to learn C. Maybe you'll get so distracted you come out a good programmer by mistake.<br />
<BigMike04> yes a friend told me that<br />
<BigMike04> im only 16 guys..the so far i have taken info tech..next year i will be in cisco<br />
<Speck> what would you do with your hacking knowledge?<br />
<Korollary> Why hack instead of program useful stuff like decent people ...<br />
<BigMike04> what will i do with the hacking knowledge? just like anyonem hack computers! lol im joking. i would use it in good use and not to mess around or anything.<br />
<astrolabe> LOL!<br />
<rep> hacking is fun.<br />
<ulfdoz> He watched 23. This evening it was broadcasted in germany.<br />
<rep> and you learn a lot<br />
<BigMike04> but yeah is cisco worth it?<br />
<yozora> hacking for a noble cause then huh<br />
<Speck> learn C, they probably have a channel somewhere. Haskell is horrible if you want to have dangerous knowledge -- you might accidentally hurt your manhood in Oleg's zipper, but you couldn't DDoS anyone with Haskell; your heap would explode.<br />
*** BigMike04 (i=BigMike0@d64-180-58-123.bchsia.telus.net) has left channel #haskell<br />
<br />
----<br />
<br />
<dons> oh, nice, david roundy is using ion.<br />
<dons> and tuomov is using darcs<br />
<dons> happy happy<br />
<br />
----<br />
<br />
<lispy> Me> "I worked 80 hours today";; TimeBot> "Timesheet updated."<br />
<br />
----<br />
<br />
<dcnstrct> alright people the choice is clear, even the #lisp people say go with haskell so I will<br />
<br />
----<br />
<br />
comparing what to what?<br />
<br />
<Cale> a bunch of oranges, one red<br />
<br />
----<br />
<br />
I tried to formalise a proof of rev (rev l) = l I found in W. Kluges book "Abstract Computing Machines - A Lambda Calculus Perspective" which is pretty much a 'Pimp My Ride' for SECD-machines. --Sebastian Hanowski<br />
<br />
----<br />
<br />
< ihope> data Badger = Badger Badger Badger | Mushroom<br />
< Philippa> Pattern match failure: Snake!<br />
<br />
(to those whom it might concern: this is a reference to a pretty bizarre swf animation that caused an epidemic a few times: http://www.badgerbadgerbadger.com/ )<br />
<br />
----<br />
<br />
<xerox> djinnModule type = askLennart ("write a function of this type: " ++ type) >>= \code -> replyBack code<br />
<br />
----<br />
<br />
< palomer> grr, sml can't derive Ord<br />
< palomer> sml is a pain to use sometimes<br />
< palomer> but sometimes it's a joy!<br />
< palomer> ugh, I take it back, it's a pain<br />
<br />
----<br />
<br />
Just checking:<br />
<br />
< pesco> @vixen PHP<br />
< lambdabot> hey, who did we fight in WWII besides Germany and Russia?<br />
<br />
----<br />
<br />
seen on #perl6:<br />
<br />
< azuroth> I did some of my C++ homework in haskell. teacher didn't like that :-( <br />
< Kattana> and this surprises you?<br />
<br />
----<br />
<br />
<jbc>: Phillipa - a parable: The chinese abacus has 5+2 beads in each column, allowing you to accumulate tens and carry them later. The japanese abacus has 4+1 beads - you carry NOW, dammit, no putting stuff down, don't be lazy. The haskell abacus Only has one bead, and it's not in the column you're using...<br />
<Philippa>: jbc: the haskell abacus has all the beads you want on an n-dimensional board and it'll clear up the mess for you<br />
<Philippa>: (but you're not allowed to move or change beads you've placed)<br />
<br />
----<br />
<br />
<ncalexan> Getting fed up with Haskell and picking up another language is like swapping your Greenpeace spouse for an abusive tyrant. Boy, does vegan sound good after beatings.<br />
<br />
----<br />
<br />
"In My Egotistical Opinion, most people's C programs should be<br />
indented six feet downward and covered with dirt."<br />
-- Blair P. Houghton<br />
<br />
----<br />
<br />
< Bobstopper> Assuming the universe will eventually die of heat death, counting will cease when that happens. So if you start counting now, you'll probably find the largest number (so long as nobody else has found a larger one yet)<br />
< Cale> what about faster ways to produce larger numbers?<br />
< Bobstopper> not after the heat death you can't :P<br />
< dave_m> don't you tell me what I can't do after the heat death of the universe<br />
<br />
----<br />
<br />
''sigfpe'': Haskell is so strict about type safety that randomly generated snippets of code that successfully typecheck are likely to do something useful, even if you've no idea what that useful thing is.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Old-reactive&diff=22092Old-reactive2008-08-01T06:18:29Z<p>Derek Elkins: fixed repo link</p>
<hr />
<div>[[Category:Events]]<br />
[[Category:Reactivity]]<br />
[[Category:FRP]]<br />
[[Category:Packages]]<br />
<br />
== Abstract ==<br />
<br />
'''Reactive''' is a simple foundation for [[Functional Reactive Programming|programming reactive systems functionally]]. Like Fran/FRP, it has a notions of (reactive) behaviors and events. Like [[DataDriven]], Reactive has an efficient, data-driven implementation. The main difference between Reactive and DataDriven are<br />
* Reactive provides and builds on "functional futures", which in turn build on [[GHC/Concurrency|Concurrent Haskell]] threads, while DataDriven builds on continuation-based computations; and<br />
* The algebras of events and reactive values (called events and sources in DataDriven) are ''purely'' functional. I couldn't figure out how to accomplish that in DataDriven.<br />
* Reactive manages (I hope) to get the efficiency of data-driven computation with a (sort-of) demand-driven architecture. For that reason, Reactive is garbage-collector-friendly, while DataDriven depends on weak references (because [[DataDriven#GC_favors_demand-driven_computation|GC favors demand-driven computation]].)<br />
* Reactive elegantly and efficiently ''caches'' values.<br />
* Reactive uses the term "reactive values" (<hask>Reactive</hask>), where DataDriven uses "sources" (<hask>Source</hask>).<br />
<br />
The inspiration for Reactive was Mike Sperber's [http://www-pu.informatik.uni-tuebingen.de/lula/deutsch/publications.html Lula] implementation of FRP. Mike used blocking threads, which I had never considered for FRP before a conversation with him at ICFP 2007. While playing with the idea, I realized that I could give a very elegant and efficient solution to caching, which DataDriven doesn't do. (For an application <hask>f <*> a</hask> of a varying function to a varying argument, caching remembers the latest function to apply to a new argument and the latest argument to which to apply a new function.)<br />
<br />
As with [[DataDriven]], Reactive provides instances for <hask>Monoid</hask>, <hask>Functor</hask>, <hask>Applicative</hask>, and <hask>Monad</hask>.<br />
<br />
Besides this wiki page, here are more ways to find out about Reactive:<br />
* Read [http://darcs.haskell.org/packages/reactive/doc/html the Haddock docs].<br />
* Get the code repository: '''<tt>darcs get http://code.haskell.org/reactive/</tt>'''.<br />
* Install from [http://hackage.haskell.org Hackage].<br />
* See the [[Reactive/Versions| version history]].<br />
<br />
Also, the paper ''[http://conal.net/papers/simply-reactive/ Simply Efficient Functional Reactivity]'', and its [http://conal.net/blog/posts/simply-efficient-functional-reactivity/ blog post with discussion], describe a (not-yet-released) successor to Reactive that solves the determinacy problem mentioned below.<br />
<br />
Please leave comments at the [[Talk:Reactive|Talk page]].<br />
<br />
== Modules ==<br />
<br />
=== Data.Future ===<br />
<br />
A ''[http://en.wikipedia.org/wiki/Futures_and_promises future]'' is a value that will become knowable only later. Primitive futures can be things like "the value of the next key you press", or "the value of LambdaPix stock at noon next Monday". The term "[http://en.wikipedia.org/wiki/Futures_and_promises promise]" might be more fitting.<br />
<br />
Composition is via standard type classes: <hask>Functor</hask>, <hask>Applicative</hask>, <hask>Monad</hask>, and <hask>Monoid</hask>.<br />
* <hask>Monoid</hask>: <hask>mempty</hask> is a future that never becomes knowable. <hask>a `mappend` b</hask> is whichever of <hask>a</hask> and <hask>b</hask> is knowable first.<br />
* <hask>Functor</hask>: apply a function to a future. The result is knowable when the given future is knowable.<br />
* <hask>Applicative</hask>: <hask>pure</hask> gives value knowable since the beginning of time. <hask>(<*>)</hask> applies a future function to a future argument. Result available when ''both'' are available, i.e., it becomes knowable when the later of the two futures becomes knowable.<br />
* Monad: <hask>return</hask> is the same as <hask>pure</hask> (as always). <hask>(>>=)</hask> cascades futures. <hask>join</hask> resolves a future future value into a future value.<br />
<br />
The current implementation is nondeterministic in <hask>mappend</hask> for futures that become knowable at the same time or nearly the same time. I want to make a deterministic implementation.<br />
<br />
==== Garbage collection of futures ====<br />
<br />
Baker & Hewitt's 1977 paper ''[http://citeseer.ist.psu.edu/baker77incremental.html The Incremental Garbage Collection of Processes]'' discusses using garbage collection to prevent the useless threads from consuming resources. In particular, consider <hask>Future</hask>'s <hask>mappend</hask> (sometimes called "parallel or"). Once one thread completes, the other threads are then useless, and some might consume resources forever. My current implementation kill the losing threads. Baker & Hewitt suggest instead using garbage collection. I'm stumped about how to GC non-winning threads in a race between futures ("parallel or"). The winner-kills-loser approach seems to work fine, though is potentially dangerous w.r.t locked resources. Still, the elegance of a GC-based solution appeals to me.<br />
<br />
==== Concurrent Haskell vs STM ====<br />
<br />
Futures are implemented using Concurrent Haskell's <hask>MVar</hask>s. I first tried using STM and <hask>TVar</hask>s, simply using <hask>orElse</hask> to implement <hask>mappend</hask> for futures. However, I didn't see how to avoid nesting <hask>atomically</hask>, which yielded a run-time error.<br />
<br />
=== Data.SFuture ===<br />
<br />
A target denotational semantics for Data.Future -- simple, precise, and deterministic, in terms of time/value pairs.<br />
<br />
=== Data.Reactive ===<br />
<br />
This module defines ''events'' and ''reactive values''. An event is stream of future values in order of availability. A reactive value is a discretly time-varying value. These two types are closely linked: a reactive value is defined by an initial value and an event that yields future values; while an event is simply a future reactive value.<br />
<haskell><br />
data Reactive a = a `Stepper` Event a<br />
newtype Event a = Event (Future (Reactive a))<br />
</haskell><br />
<br />
This <hask>Reactive</hask> representation can be thought of a ''reactive weak head normal form'', to which arbitrary reactive expressions may be rewritten. The rewrite rules and their justification in terms of simple denotational semantics will be described in an upcoming paper.<br />
<br />
Many of the operations on events and reactive values are packaged as instances of standard classes, as described below. See the module documentation for the other operations.<br />
<br />
==== Instances for Event ====<br />
<br />
* '''<hask>Monoid</hask>''': <hask>mempty</hask> is the event that never occurs, and <hask>e `mappend` e'</hask> is the event that combines occurrences from <hask>e</hask> and <hask>e'</hask>. (Fran's <hask>neverE</hask> and <hask>(.|.)</hask>.)<br />
* '''<hask>Functor</hask>''': <hask>fmap f e</hask> is the event that occurs whenever <hask>e</hask> occurs, and whose occurrence values come from applying <hask>f</hask> to the values from <hask>e</hask>. (Fran's <hask>(==>)</hask>.)<br />
* '''<hask>Applicative</hask>''': <hask>pure a</hask> is an event with a single occurrence, available from the beginning of time. <hask>ef <*> ex</hask> is an event whose occurrences are made from the ''product'' of the occurrences of <hask>ef</hask> and <hask>ex</hask>. For every occurrence <hask>f</hask> at time <hask>tf</hask> of <hask>ef</hask> and occurrence <hask>x</hask> at time <hask>tx</hask> of <hask>ex</hask>, <hask>ef <*> ex</hask> has an occurrence <hask>f x</hask> at time <hask>max tf tx</hask>.<br />
* '''<hask>Monad</hask>''': <hask>return a</hask> is the same as <hask>pure a</hask> (as always). In <hask>e >>= f</hask>, each occurrence of <hask>e</hask> leads, through <hask>f</hask>, to a new event. Similarly for <hask>join ee</hask>, which is somehow simpler for me to think about. The occurrences of <hask>e >>= f</hask> (or <hask>join ee</hask>) correspond to the union of the occurrences of all such events. For example, suppose we're playing Asteroids and tracking collisions. Each collision can break an asteroid into more of them, each of which has to be tracked for more collisions. Another example: A chat room has an "enter" event, whose occurrences contain new events like "speak".<br />
<br />
==== Instances for Reactive ====<br />
<br />
The instances for <hask>Reactive</hask> can be understood in terms of (a) a simple semantics of reactive values as functions of time, and (b) the corresponding instances for functions. The semantics is given by the function <hask>at :: Reactive a -> (Time -> a)</hask>.<br />
* '''<hask>Monoid</hask>''': a typical lifted monoid. If <hask>o</hask> is a monoid, then <hask>Reactive o</hask> is a monoid, with <hask>mempty = pure mempty</hask>, and <hask>mappend = liftA2 mappend</hask>. In other words, <hask>mempty `at` t == mempty</hask>, and <hask>(r `mappend` s) `at` t == (r `at` t) `mappend` (s `at` t).</hask><br />
* '''<hask>Functor</hask>''': <hask>fmap f r `at` t == f (r `at` t)</hask>.<br />
* '''<hask>Applicative</hask>''': <hask>pure a `at` t == a</hask>, and <hask>(s <*> r) `at` t == (s `at` t) (r `at` t)</hask>.<br />
* '''<hask>Monad</hask>''': <hask>return a `at` t == a</hask>, and <hask>join rr `at` t == (rr `at` t) `at` t</hask>. As always, <hask>(r >>= f) == join (fmap f r)</hask>.<br />
<br />
==== Continuous reactive behaviors ====<br />
<br />
Although the basic <hask>Reactive</hask> type describes ''discretely''-changing values, ''continuously''-changing are defined simply by composing <hask>Reactive</hask> and a simple type functions of time (see below).<br />
<haskell><br />
type Time = Double<br />
type ReactiveB = Reactive :. Fun Time<br />
</haskell><br />
Because the combination of <hask>Reactive</hask> and <hask>Fun Time</hask> is wrapped in a [[TypeCompose|type composition]], we get <hask>Functor</hask> and <hask>Applicative</hask> instances for free.<br />
<br />
The exact packaging of discrete vs continuous will probably change with more experience. Perhaps I'll fold <hask>Fun Time a</hask> into the <hask>Reactive</hask> type, making a dynamic rather than static distinction.<br />
<br />
=== Data.Fun ===<br />
<br />
This module defines a type of functions optimized for the constant case, together with instances of <hask>Functor</hask>, <hask>Applicative</hask>, <hask>Monad</hask>, and <hask>Arrow</hask>.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=20460Performance/Monads2008-04-07T05:08:52Z<p>Derek Elkins: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
Note that this is just essentially just ContT M and indeed all of the below is just writing out the ContT implementation.<br />
<br />
Also note that M's (>>=) operation isn't used. It comes up when you implement the other operations M supports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
How and why does this work? We're basically specializing <hask>>>=</hask>. Before, we had<br />
<haskell><br />
m >>= f = case m of<br />
Just a -> f a<br />
Nothing -> Nothing<br />
</haskell><br />
i.e. the monadic bind does a case analysis on how to proceed. In the CPS-representation, we're specializing bind to the two possible constructors:<br />
<haskell><br />
return' a := (return a >>=) = (Just a >>=) = \f -> f a<br />
mzero' := (mzero >>=) = (Nothing >>=) = \f -> Nothing<br />
</haskell><br />
and the case analysis is now "built-in" into <hask>return'</hask> and <hask>mzero'</hask>. In general, embedding a monad in <hask>Cont</hask> specializes <hask>>>=</hask> to its primitive operations, like for example <hask>mzero</hask> or <hask>get</hask>. This is close to specifying the operational semantics of <hask>>>=</hask> directly and can hence be used to implement the monad in the first place, too.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing) -- equivalent to MaybeCPS (Nothing >>=)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Research_papers/Functional_pearls&diff=19203Research papers/Functional pearls2008-02-18T23:37:49Z<p>Derek Elkins: </p>
<hr />
<div>Functional pearls are elegant, instructive examples of functional programming. They are supposed to be fun, and they teach important programming techniques and fundamental design principles. They traditionally appear in [http://www.cambridge.org/journals/JFP/ The Journal of Functional Programming], and at [http://www.icfpconference.org/index.html ICFP] and affiliated workshops.<br />
<br />
The history of functional pearls is covered by:<br />
<br />
;[http://icfp06.cs.uchicago.edu/bird-talk.pdf How to Write a Functional Pearl]<br />
:Richard Bird. ICFP 2006.<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1159832&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 Fifteen years of functional pearls]<br />
:Richard Bird. ICFP 2006.<br />
<br />
;[http://spivey.oriel.ox.ac.uk/mike/firstpearl.pdf Strachey's functional pearl, forty years on]<br />
:Mike Spivey, 2006.<br />
<br />
There have been some 64 functional pearls in JFP, and some others at<br />
ICFP and the Haskell Workshop. There is also a collection of them in<br />
[http://web.comlab.ox.ac.uk/oucl/publications/books/fop/ The Fun of Programming].<br />
<br />
The pearls tend to concentrate on:<br />
<br />
* Examples of program calculation and proof<br />
* Neat presentations of new or old data structures<br />
* Interesting applications and techniques<br />
<br />
=== Online ===<br />
<br />
Functional pearls online:<br />
<br />
;[http://wwwtcs.inf.tu-dresden.de/~voigt/popl202-voigtlaender.pdf Much Ado about Two: A Pearl on Parallel Prefix Computation]<br />
:Janis Voigtländer. 2008<br />
<br />
;[http://strictlypositive.org/CJ.pdf Clowns to the Left of me, Jokers to the Right: Dissecting Data Structures]: Conor McBride. 2008.<br />
<br />
;[http://www.ccs.neu.edu/home/dherman/research/papers/icfp07-great-escape.pdf Functional Pearl: The Great Escape: Or how to jump the border without getting caught]<br />
:David Herman. 2007.<br />
<br />
;[https://www.cs.indiana.edu/~adamsmd/papers/scrap_your_zippers/ScrapYourZippers.pdf Scrap Your Zippers]<br />
:Michael Adams 2007<br />
<br />
;[http://www.eecs.harvard.edu/~nr/cs252r/archive/conor-mcbride/epigram-pearl.pdf A type-correct, stack-safe, provably correct expression compiler in Epigram]<br />
:James McKinna and Joel Wright. 2006.<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf Applicative Programming with Effects]<br />
:Conor McBride and Ross Paterson. 2006.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/rationals.pdf Enumerating the rationals]<br />
:Jeremy Gibbons, David Lester and Richard Bird. 2006.<br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/papers/PFP_JFP06.pdf Probabilistic functional programming in Haskell]<br />
:Martin Erwig and Steve Kollmansberger. 2006. <br />
<br />
;[http://cms.brookes.ac.uk/staff/SharonCurtis/publications/marbles.ps.gz Marble mingling]<br />
:Sharon Curtis. 2006.<br />
<br />
;[http://wiki.di.uminho.pt/twiki/pub/Personal/Xana/WebHome/report.pdf Strong Types for Relational Databases]<br />
:Alexandra Silva, Joost Visser. 2006. (Haskell Workshop)<br />
<br />
;[http://okmij.org/ftp/papers/LogicT.pdf Backtracking, interleaving, and terminating monad transformers]<br />
:Oleg Kiselyov, Chung-chieh Shan, Daniel P. Friedman, Amr Sabry. 2005. <br />
<br />
;[http://homepages.inf.ed.ac.uk/jcheney/publications/cheney05icfp.pdf Scrap your Nameplate]<br />
:James Cheney. 2005.<br />
<br />
;[http://research.microsoft.com/~akenn/fun/picklercombinators.pdf Pickler Combinators]<br />
:Andrew Kennedy. 2004.<br />
<br />
;[http://web.cecs.pdx.edu/~mpj/pubs/composing-fractals.pdf Composing fractals]<br />
:Mark P. Jones. 2004.<br />
<br />
;[http://www.cs.dartmouth.edu/~doug/nfa.ps.gz Enumerating the strings of regular languages]<br />
:M. Douglas McIlroy. 2004.<br />
<br />
;[http://pauillac.inria.fr/~maranget/enum/pearl.ps Functional satisfaction]<br />
:Luc Maranget. 2004. ([http://pauillac.inria.fr/~maranget/enum/index.html More info]).<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1017481&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 Implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan. 2004. ([http://www.cs.rutgers.edu/~ccshan/prepose/p1214-kiselyov.pdf also here])<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. 2004. ([http://journals.cambridge.org/action/displayAbstract?fromPage=online&aid=241773 JFP])<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1017477&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 I am not a number -- I am a free variable]<br />
:Conor McBride, James McKinna. 2004. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/2.ps.gz Inverting the Burrows Wheeler transform]<br />
:Richard Bird and Shin-Cheng Mu. 2004. ([http://web.comlab.ox.ac.uk/oucl/work/shin-cheng.mu/pub/bwtJFP.ps.gz Also here], [http://web.comlab.ox.ac.uk/oucl/work/richard.bird/online/BirdMu2004Inverting.pdf And here]).<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/wg21/meeting56/loeh-paper.pdf Parsing permutation phrases]<br />
:Arthur Baars, Andres Loh and S. Doaitse Swierstra. 2004.<br />
<br />
;[http://web.cecs.pdx.edu/~antoy/homepage/publications/inject/paper.pdf Concurrent distinct choices]<br />
:Sergio Antoy and Michael Hanus. 2004. <br />
<br />
;[http://www.ling.gu.se/~peb/pubs/Ljunglof-2004b.pdf Functional chart parsing of context-free grammars]<br />
:Peter Ljunglf. 2004.<br />
<br />
;[http://www.seas.upenn.edu/~sweirich/papers/cast/cast.pdf Type-Safe Cast]<br />
:Stephanie Weirich. 2004.<br />
<br />
;[http://research.microsoft.com/~akenn/fun/picklercombinators.pdf Pickler Combinators]<br />
:Andrew J. Kennedy. 2004.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/jfp04-parser.ps Parallel Parsing Processes]<br />
:Koen Claessen. 2004.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/1.pdf Derivation of a logarithmic time carry lookahead addition circuit]<br />
:John O'Donnell and Gudula Runger. 2004. ([http://portal.acm.org/citation.cfm?coll=GUIDE&dl=GUIDE&id=1030343 ACM]) ([http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=254718 JFP]) ([http://www.informatik.uni-bonn.de/~ralf/hw2001/1.html Homepage]). <br />
<br />
;[http://www.lri.fr/~filliatr/ftp/publis/kr-fp.ps.gz Producing all ideals of a forest, functionally]<br />
:Jean-Christophe Fillitre and Franois Pottier. 2003.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/HW2003.pdf Trouble shared is trouble halved]<br />
:Richard Bird, Ralf Hinze. 2003<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/Format.ps.gz Formatting: a class act]<br />
:Ralf Hinze. 2003.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/SearchTree.ps.gz A fresh look at binary search trees]<br />
:Ralf Hinze. 2002.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/countdown.pdf The countdown problem]<br />
:Graham Hutton. 2002. <br />
<br />
;[http://pdos.csail.mit.edu/papers/packrat-parsing:icfp02.pdf Packrat parsing: simple, powerful, lazy, linear time, functional pearl]<br />
:Bryan Ford. 2002.<br />
<br />
;[http://www.cse.ogi.edu/~magnus/papers/icfp-2002.pdf Monads for Incremental Computing]<br />
:Magnus Carlsson. 2002.<br />
<br />
;[http://eprints.ouls.ox.ac.uk/archive/00000863/01/bird_2001_11_3.pdf Unfolding pointer algorithms]<br />
:Richard Bird. 2001.<br />
<br />
;[http://eprints.ouls.ox.ac.uk/archive/00000862/01/bird_2001.pdf Maximum marking problems]<br />
:Richard Bird. 2001. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/TheWeb.ps.gz Weaving a web]<br />
:Ralf Hinze and Johan Jeuring. 2001. <br />
<br />
;[http://www.brics.dk/RS/01/16/BRICS-RS-01-16.pdf Normalization by evaluation with typed abstract syntax]<br />
:Olivier Danvy, Morten Rhiger and Kristoffer H. Rose. 2001. <br />
<br />
;[http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?]<br />
:Daniel Fridlender and Mia Indrika. 2001.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/IAI-TR-99-4.ps.gz Perfect trees and bit-reversal permutations]<br />
:Ralf Hinze. 2000.<br />
<br />
;[http://spivey.oriel.ox.ac.uk/mike/bfs/bfs.ps Combinators for breadth-first search]<br />
:Michael Spivey. 2000 <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/icfp00.ps Breadth-First Numbering: Lessons from a Small Exercise in Algorithm Design]<br />
:Chris Okasaki. 2000.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/ICFP00.ps.gz Deriving Backtracking Monad Transformers]<br />
:Ralf Hinze. 2000.<br />
<br />
;[http://www.cis.upenn.edu/~bcpierce/papers/rsr.ps Recursive subtyping revealed]<br />
:Vladimir Gapeyev, Michael Y. Levin, Benjamin C. Pierce. 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Papers/financial-contracts/contracts-icfp.ps.gz Composing contracts: an adventure in financial engineering]<br />
:Simon Peyton Jones, Jean-Marc Eber, Julian Seward. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps A poor man's concurrency monad]<br />
:Koen Claessen. 1999. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/BinomialHeaps.ps.gz Explaining binomial heaps]<br />
:Ralf Hinze. 1999. <br />
<br />
;[http://www.cs.dartmouth.edu/~doug/pearl.ps.gz Power series, power serious]<br />
:M. Douglas McIlroy. 1999. <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/jfp99.ps Red-black trees in a functional setting]<br />
:Chris Okasaki. 1999. <br />
<br />
;[http://www.cs.cmu.edu/~rwh/papers/regexp/jfp.ps Proof-directed debugging]<br />
:Robert Harper. 1999. (see also [http://ropas.snu.ac.kr/~kwang/paper/06-jfp-yi.pdf Proof-directed debugging: revisited for a first-order version]).<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/radix.ps.gz A pointless derivation of radix sort]<br />
:Jeremy Gibbons. 1999.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/pearl.pdf Monadic parsing in Haskell]<br />
:Graham Hutton and Erik Meijer . 1998.<br />
<br />
;[http://citeseer.ist.psu.edu/101702.html Polytypic unification]<br />
:Patrik Jansson and Johan Jeuring. 1998. <br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/papers/Diet_JFP98.pdf Diets for fat sets]<br />
:Martin Erwig. 1998. <br />
<br />
;[http://citeseer.ist.psu.edu/163183.html Even higher-order functions for parsing or Why would anyone ever want to use a sixth-order function?]<br />
:Chris Okasaki. 1998.<br />
<br />
;[http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf The Zipper]<br />
:Gerard Huet. 1997. (See also [http://en.wikibooks.org/wiki/Haskell/Zippers The Haskell Wikibook]).<br />
<br />
;[http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes]<br />
:Colin Runciman. 1997. <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/jfp97.ps Three algorithms on Braun trees]<br />
:Chris Okasaki. 1997. <br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/thirdht.ps.gz The Third Homomorphism Theorem]<br />
:Jeremy Gibbons. 1996.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/basics.pdf Back to Basics: Deriving Representation Changers Functionally].<br />
:Graham Hutton, Erik Meijer. 1996.<br />
<br />
;[http://research.microsoft.com/~akenn/fun/DrawingTrees.pdf Drawing Trees]<br />
:Drawing Trees. 1996.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/drawing.ps.gz Deriving Tidy Drawings of Trees]<br />
:Jeremy Gibbons. 1996. (See also [http://www.cs.auckland.ac.nz/CDMTCS//researchreports/003drawing.pdf the research report]).<br />
<br />
;[http://www.swiss.ai.mit.edu/~adams/BB Efficient Sets - A Balancing Act]<br />
:Stephen Adams. 1993. ([http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Set.html Data.Set]).<br />
<br />
=== Potential Pearls ===<br />
<br />
Unpublished pearls.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/Quote.pdf Typed Quote/AntiQuote]<br />
:Ralf Hinze. Unpublished work in progress.<br />
<br />
;[http://www.cs.nott.ac.uk/~txa/publ/alpha-draft.pdf &alpha;-conversion is easy]<br />
:Thorsten Altenkirch. Unpublished draft.<br />
<br />
=== Offline ===<br />
<br />
These appear not to be available online, unfortunately. If you know where they live, please link, and move into the 'online' section!<br />
<br />
;[http://www.journals.cambridge.org/action/displayAbstract?fromPage=online&aid=254707 Linear lambda calculus and PTIME-completeness]<br />
:Harry G. Mairson. 2004. <br />
<br />
;[http://journals.cambridge.org/article_S0956796804005210 Calculating the Sieve of Eratosthenes]<br />
:Lambert Meertens. Journal of Functional Programming, 14(6):759-763, 2004. ([http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/wg21/meeting57/meertens-sieve.pdf slides])<br />
<br />
;[http://www.cs.kent.ac.uk/pubs/2001/1293/index.html Red-black trees with types]<br />
:Stefan Kahrs. 2001. ([http://journals.cambridge.org/article_S0956796801004026 JFP]) ([http://www.cs.kent.ac.uk/people/staff/smk/redblack/rb.html Code!])<br />
<br />
;On generating unique names<br />
:Lennart Augustsson, M Rittri, D Synek. 1994. ([http://www.cs.chalmers.se/~rittri/#publications Rittri's homepage])<br />
<br />
;A Symmetric Set of Efficient List Operations.<br />
:Rob R. Hoogerwoord, 1992. ([https://venus.tue.nl/ep-cgi/ep_publ.opl?taal=NL&fac_id=92&rn=19840694 Hoogerwoord's homepage]).<br />
<br />
;[http://journals.cambridge.org/action/displayAbstract?fromPage=online&aid=335124 Finding celebrities: A lesson in functional programming]<br />
:Richard Bird and Sharon Curtis. 2006. ([http://cms.brookes.ac.uk/staff/SharonCurtis/publications/index.html#celebrities See also]).<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=451101 A program to solve Sudoku]<br />
:Richard Bird. 2006. (slides [http://icfp06.cs.uchicago.edu/bird-talk.pdf appear here]).<br />
<br />
;[http://www.journals.cambridge.org/action/displayAbstract?fromPage=online&aid=254705 On tiling a chessboard]<br />
:Richard Bird. 2004. ([http://portal.acm.org/citation.cfm?id=1030333.1030336 ACM]) <br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=44142 Meertens number]<br />
:Richard Bird. 1998.<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=44092 On merging and selection]<br />
:Richard Bird. 1997. (See also [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/merging.ps.gz More on Merging and Selection]).<br />
<br />
;[http://journals.cambridge.org/article_S0956796897002803 On building trees with minimum height]<br />
:Richard Bird. 1997. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird97:OnBuilding Bib]).<br />
<br />
;The Last Tail. <br />
:Richard Bird. 1993. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird93:Last Bib]).<br />
<br />
;Two Greedy Algorithms<br />
:Richard Bird, 1992. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird92:Two Bib]).<br />
<br />
;On Removing Duplicates<br />
:Richard Bird. 1991. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#DBLP:journals/jfp/Bird91a Bib]).<br />
<br />
[[Category:Research]] [[Category:Tutorials]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Stack_overflow&diff=18712Stack overflow2008-01-28T00:32:29Z<p>Derek Elkins: </p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
== Folds ==<br />
<br />
First, read [[Performance/Accumulating parameter]]. If you are not writing your code tail-recursively, then that is why you are getting stack overflows. However, making code tail-recursive in a lazy language is not quite the same as in a eager language. This page is more geared to the latter case using foldr/l as the prime culprit/example. As such [[Fold]] may be helpful, but isn't too critical. Also knowing what <hask>seq</hask> and <hask>($!)</hask> do as briefly covered in ForcingEagerEvaluation or in the [http://haskell.org/onlinereport/ Haskell Report] is necessary.<br />
<br />
The definitions of the three folds we'll be looking at are as follows,<br />
<haskell><br />
foldr f z [] = z<br />
foldr f z (x:xs) = f x (foldr f z xs)<br />
<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
<br />
foldl' f z [] = z<br />
foldl' f z (x:xs) = (foldl' f $! f z x) xs<br />
<br />
foldl' (found in e.g. Data.List) is just a stricter version of foldl.<br />
</haskell><br />
The one-line summary for folds: if the binary operation is strict use foldl' otherwise use foldr.<br />
<br />
----<br />
<br />
Common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldr (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
If you've read [[Performance/Accumulating parameter]], you should immediately see the problem from the definition of foldr above. Quite simply, foldr isn't tail-recursive! But,<br />
<haskell><br />
concat xss = foldr (++) [[]] xss<br />
</haskell><br />
This is from the Haskell Report. Surely they know what they are doing! And sure enough,<br />
<haskell><br />
main = print (length (concat [[x] | x <- [1..1000000]]))<br />
</haskell><br />
works fine.<br />
<br />
Less common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
So what's going on here. Looking at the code for foldl, it looks tail-recursive. Well, much like you can see the problem with a non-tail-recursive factorial by unfolding a few iterations, let's do the same for our foldl definition of sum, but making sure to use a call-by-name/need evaluation order. Here is the unfolding,<br />
<haskell><br />
mysum [1..10] -><br />
foldl (+) 0 (1:[2..10]) -><br />
foldl (+) (0+1) (2:[3..10]) -><br />
foldl (+) (0+1+2) (3:[4..10]) -><br />
foldl (+) (0+1+2+3) (4:[5..10]) -> <nowiki>...</nowiki><br />
</haskell><br />
I think you get the idea. The problem is that we are building up a chain of thunks that will evaluate the sum instead of just maintaining a running sum. What we need to do is to force the addition before recursing. This is exactly what foldl' does.<br />
<br />
Just to check,<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl' (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
works fine.<br />
<br />
Now let's go back to the foldr sum and concat. What's the difference between sum and concat that makes the sum definition wrong, but the concat definition right. Again, let's evaluate each by hand.<br />
<haskell><br />
mysum (+) 0 [1..10] -><br />
foldr (+) 0 (1:[2..10]) -><br />
1+foldr (+) 0 (2:[3..10]) -><br />
1+(2+foldr (+) 0 (3:[4..10])) -> <nowiki>...</nowiki><br />
</haskell><br />
Okay, no surprise there.<br />
<haskell><br />
concat [[1],[2],[3],<nowiki>...</nowiki>] -><br />
foldr (++) [[]] ([1]:[[2],[3],<nowiki>...</nowiki>]) -><br />
(1:[])++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>] -><br />
1:([]++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>])<br />
</haskell><br />
Notice that there is no '-> ...' at the end. That was the complete evaluation. There is no reason to do anything more unless we look at the more of the result. We may well GC the 1 before we look at the tail, and GC the first cons cell before we look at the second. So, concat runs in a constant amount of stack and further can handle infinite lists (as a note, it's immediately obvious foldl(') can never work on infinite lists because we'll always be in the (:) case and that always immediately recurses). The differentiator between mysum and concat is that (++) is not strict* in its second argument; we don't have to evaluate the rest of the foldr to know the beginning of concat. In mysum, since (+) is strict in its second argument we need the results of the whole foldr before we can compute the final result.<br />
<br />
So, we arrive at the one-line summary: A function strict in its second argument will always* require linear stack space with foldr, so foldl' should be used instead in that case. If the function is lazy/non-strict in its second argument we should use foldr to 1) support infinite lists and 2) to allow a streaming use of the input list where only part of it needs to be in memory at a time.<br />
<br />
Okay, both here and in the one-line summary, there is no mention of foldl. When should foldl be used? The pragmatic answer is: by and far it shouldn't be used. A case where it makes a difference is if the function is conditionally strict in its first argument depending on its second, where I use conditionally strict to mean a function that is strict or not in one argument depending on another argument(s). For an example, consider a definition of <hask>(*)</hask> that builds up ASTs of arithmetic expressions and incorporates a simplification <hask>(a*0 = 0 and then 0*a = 0)</hask>; then if <hask>product</hask> is defined by <hask>foldl (*) 1</hask>, <hask>product [</hask>&perp;<hask>,0]</hask> will terminate with 0 while a definition in terms of <hask>foldl'</hask> wouldn't. However, I can't think of a really convincing example. In most cases, foldl' is what you want.<br />
<br />
* A strict function is a function, f such that f &perp; = &perp;. Typically, we think of a function "being strict" in an argument as a function that "forces" its argument, but the above definition of strict should immediately suggest another function that is strict and doesn't "force" it's argument in the intuitive sense, namely id. ([]++) = id and therefore is a strict function. Sure enough, if you were to evaluate (concat (repeat [])) it would not terminate. As such (++) is a conditionally strict function. This also makes the "always" slightly imprecise, a function that is strict because it just returns it's argument will not use up stack space (but is, as I mentioned, still an issue for infinitely long lists).<br />
<br />
== Scans ==<br />
<br />
A subtle stack-overflow surprise comes when<br />
<haskell><br />
print (scanl (+) 0 [1..1000000])<br />
</haskell><br />
completes successfully but<br />
<haskell><br />
print (last (scanl (+) 0 [1..1000000]))<br />
</haskell><br />
causes a stack overflow.<br />
<br />
The latter stack overflow is explained exactly as before, namely,<br />
<haskell><br />
last (scanl (+) 0 [1..5]) -><br />
<nowiki>... several steps ...</nowiki> -><br />
((((0+1)+2)+3)+4)+5<br />
</haskell><br />
This is exactly like <hask>foldl</hask>, building a deep thunk, then evaluating, needing much stack.<br />
<br />
Most puzzling is why the former succeeds without a stack overflow. This is caused by a combination of two factors:<br />
* thunks in the list produced by <hask>scanl</hask> enjoy sharing: late thunks build upon early thunks<br />
* printing a list of numbers evaluates early thunks and then late thunks<br />
To exemplify, here is an abridged progression. I use this pseudo format to depict sharing of thunks<br />
<haskell><br />
expr where var=expr, var=expr<br />
</haskell><br />
although in reality it is more like a pointer graph.<br />
<haskell><br />
print (scanl (+) 0 [1..1000000]) -><br />
print (a : case [1..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (a+x) xs) where a=0 -><br />
<nowiki>... evaluate a to 0 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (a+1) [2..1000000]) where a=0 -><br />
print (b : case [2..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (b+x) xs) where a=0, b=a+1 -><br />
<nowiki>... evaluate b to 1 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (b+2) [3..1000000]) where b=1 -><br />
print (c : case [3..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (c+x) xs) where b=1, c=b+2 -><br />
<nowiki>... evaluate c to 3 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (c+3) [4..1000000]) where c=3 -><br />
print (d : case [4..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (d+x) xs) where c=3, d=c+3 -><br />
<nowiki>... evaluate d to 6 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (d+4) [5..1000000]) where d=6 -> etc.<br />
</haskell><br />
The important thing to watch is the life cycle of intermediate thunks, e.g., <hask>c</hask> is created at some point as a 1-level deep addition, then almost immediately reduced to a number out of necessity, before a later thunk <hask>d</hask> builds upon it. Therefore there is no growth and no stack overflow.<br />
<br />
In contrast, again, <hask>last (scanl (+) 0 [1..1000000])</hask> skips over to the last thunk right away. Since early items are not reduced yet, the last item remains a huge chain and causes overflow.<br />
<br />
As an addendum, there are three ways of handling this problem and similar ones:<br />
# You can have your traversal functions (in this case, last) force the list as it goes along.<br />
# You can use (perhaps custom) versions of the list (or data structure, in general) producing functions (in this case, scanl) that force the elements as it builds the data structure.<br />
# You can use a data structure that's strict in its elements, in this case it would be a head strict list.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Parsec&diff=18711Parsec2008-01-28T00:15:32Z<p>Derek Elkins: </p>
<hr />
<div>== Parsec ==<br />
<br />
[[Category:Compiler tools]]<br />
[[Category:Combinators]]<br />
<br />
Parsec is an industrial strength, monadic parser combinator library for<br />
Haskell. It can parse context-sensitive, infinite look-ahead grammars<br />
but it performs best on predictive (LL[1]) grammars. <br />
<br />
See [http://www.cs.uu.nl/people/daan/download/parsec/parsec.html the Parsec site] <br />
for downloads and documentation.<br />
<br />
=== Usage ===<br />
<br />
Parsec lets you construct parsers by combining higher-order<br />
[[Combinator]]s to create larger expressions. Combinator parsers are<br />
written and used within the same programming language as the rest of the<br />
program. The parsers are first-class citizens of the language , unlike<br />
[[Happy]] parsers, which must be generated via a preprocessor.<br />
<br />
Much more documentation can be found on the parsec site.<br />
<br />
{{Template:Stub}}<br />
<br />
=== Parsec clones in other languages ===<br />
<br />
* PCL for O'Caml http://lprousnth.files.wordpress.com/2007/08/pcl.pdf<br />
* JParsec for Java http://jparsec.codehaus.org/JParsec+Overview<br />
* NParsec, JParsec ported to C# http://jparsec.codehaus.org/NParsec+Tutorial<br />
* Ruby Parsec, JParsec ported to Ruby http://jparsec.codehaus.org/Ruby+Parsec<br />
* FParsec for F# http://www.quanttec.com/fparsec/<br />
* A small Parsec in Erlang http://www.engr.uconn.edu/~jeffm/Source/Erlang/<br />
* AliceParsec for Alice ML http://www.ps.uni-sb.de/alice/contribs.html<br />
* Parsnip for C++ http://parsnip-parser.sourceforge.net/<br />
* Somewhere there is a Nemerle port<br />
<br />
Interesting non-Parsec parser combinator libraries:<br />
* Spirit for C++ http://spirit.sourceforge.net/documentation.html<br />
* Scala http://www.scala-lang.org/docu/files/api/scala/util/parsing/combinator$content.html</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Stack_overflow&diff=17737Stack overflow2007-12-21T17:36:46Z<p>Derek Elkins: </p>
<hr />
<div>[[Category:Tutorials]]<br />
<br />
== Folds ==<br />
<br />
First, read [[Performance/Accumulating parameter]]. If you are not writing your code tail-recursively, then that is why you are getting stack overflows. However, as the bottom of that page suggests, making code tail-recursive in a lazy language is not quite the same as in a eager language. This page is more geared to the latter case using foldr/l as the prime culprit/example. As such [[Fold]] may be helpful, but isn't too critical. Also knowing what <hask>seq</hask> and <hask>($!)</hask> do as briefly covered in ForcingEagerEvaluation or in the [http://haskell.org/onlinereport/ Haskell Report] is necessary.<br />
<br />
The definitions of the three folds we'll be looking at are as follows,<br />
<haskell><br />
foldr f z [] = z<br />
foldr f z (x:xs) = f x (foldr f z xs)<br />
<br />
foldl f z [] = z<br />
foldl f z (x:xs) = foldl f (f z x) xs<br />
<br />
foldl' f z [] = z<br />
foldl' f z (x:xs) = (foldl' f $! f z x) xs<br />
<br />
foldl' (found in e.g. Data.List) is just a stricter version of foldl.<br />
</haskell><br />
The one-line summary for folds: if the binary operation is strict use foldl' otherwise use foldr.<br />
<br />
----<br />
<br />
Common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldr (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
If you've read [[Performance/Accumulating parameter]], you should immediately see the problem from the definition of foldr above. Quite simply, foldr isn't tail-recursive! But,<br />
<haskell><br />
concat xss = foldr (++) [[]] xss<br />
</haskell><br />
This is from the Haskell Report. Surely they know what they are doing! And sure enough,<br />
<haskell><br />
main = print (length (concat [[x] | x <- [1..1000000]]))<br />
</haskell><br />
works fine.<br />
<br />
Less common newbie stack overflowing code:<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
So what's going on here. Looking at the code for foldl, it looks tail-recursive. Well, much like you can see the problem with a non-tail-recursive factorial by unfolding a few iterations, let's do the same for our foldl definition of sum, but making sure to use a call-by-name/need evaluation order. Here is the unfolding,<br />
<haskell><br />
mysum [1..10] -><br />
foldl (+) 0 (1:[2..10]) -><br />
foldl (+) (0+1) (2:[3..10]) -><br />
foldl (+) (0+1+2) (3:[4..10]) -><br />
foldl (+) (0+1+2+3) (4:[5..10]) -> <nowiki>...</nowiki><br />
</haskell><br />
I think you get the idea. The problem is that we are building up a chain of thunks that will evaluate the sum instead of just maintaining a running sum. What we need to do is to force the addition before recursing. This is exactly what foldl' does.<br />
<br />
Just to check,<br />
<haskell><br />
mysum :: [Integer] -> Integer<br />
mysum = foldl' (+) 0<br />
<br />
main = print (mysum [1..1000000])<br />
</haskell><br />
works fine.<br />
<br />
Now let's go back to the foldr sum and concat. What's the difference between sum and concat that makes the sum definition wrong, but the concat definition right. Again, let's evaluate each by hand.<br />
<haskell><br />
mysum (+) 0 [1..10] -><br />
foldr (+) 0 (1:[2..10]) -><br />
1+foldr (+) 0 (2:[3..10]) -><br />
1+(2+foldr (+) 0 (3:[4..10])) -> <nowiki>...</nowiki><br />
</haskell><br />
Okay, no surprise there.<br />
<haskell><br />
concat [[1],[2],[3],<nowiki>...</nowiki>] -><br />
foldr (++) [[]] ([1]:[[2],[3],<nowiki>...</nowiki>]) -><br />
(1:[])++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>] -><br />
1:([]++foldr (++) [[]] [[2],[3],<nowiki>...</nowiki>])<br />
</haskell><br />
Notice that there is no '-> ...' at the end. That was the complete evaluation. There is no reason to do anything more unless we look at the more of the result. We may well GC the 1 before we look at the tail, and GC the first cons cell before we look at the second. So, concat runs in a constant amount of stack and further can handle infinite lists (as a note, it's immediately obvious foldl(') can never work on infinite lists because we'll always be in the (:) case and that always immediately recurses). The differentiator between mysum and concat is that (++) is not strict* in its second argument; we don't have to evaluate the rest of the foldr to know the beginning of concat. In mysum, since (+) is strict in its second argument we need the results of the whole foldr before we can compute the final result.<br />
<br />
So, we arrive at the one-line summary: A function strict in its second argument will always* require linear stack space with foldr, so foldl' should be used instead in that case. If the function is lazy/non-strict in its second argument we should use foldr to 1) support infinite lists and 2) to allow a streaming use of the input list where only part of it needs to be in memory at a time.<br />
<br />
Okay, both here and in the one-line summary, there is no mention of foldl. When should foldl be used? The pragmatic answer is: by and far it shouldn't be used. A case where it makes a difference is if the function is conditionally strict in its first argument depending on its second, where I use conditionally strict to mean a function that is strict or not in one argument depending on another argument(s). For an example, consider a definition of <hask>(*)</hask> that builds up ASTs of arithmetic expressions and incorporates a simplification <hask>(a*0 = 0 and then 0*a = 0)</hask>; then if <hask>product</hask> is defined by <hask>foldl (*) 1</hask>, <hask>product [</hask>&perp;<hask>,0]</hask> will terminate with 0 while a definition in terms of <hask>foldl'</hask> wouldn't. However, I can't think of a really convincing example. In most cases, foldl' is what you want.<br />
<br />
* A strict function is a function, f such that f &perp; = &perp;. Typically, we think of a function "being strict" in an argument as a function that "forces" its argument, but the above definition of strict should immediately suggest another function that is strict and doesn't "force" it's argument in the intuitive sense, namely id. ([]++) = id and therefore is a strict function. Sure enough, if you were to evaluate (concat (repeat [])) it would not terminate. As such (++) is a conditionally strict function. This also makes the "always" slightly imprecise, a function that is strict because it just returns it's argument will not use up stack space (but is, as I mentioned, still an issue for infinitely long lists).<br />
<br />
== Scans ==<br />
<br />
A subtle stack-overflow surprise comes when<br />
<haskell><br />
print (scanl (+) 0 [1..1000000])<br />
</haskell><br />
completes successfully but<br />
<haskell><br />
print (last (scanl (+) 0 [1..1000000]))<br />
</haskell><br />
causes a stack overflow.<br />
<br />
The latter stack overflow is explained exactly as before, namely,<br />
<haskell><br />
last (scanl (+) 0 [1..5]) -><br />
<nowiki>... several steps ...</nowiki> -><br />
((((0+1)+2)+3)+4)+5<br />
</haskell><br />
This is exactly like <hask>foldl</hask>, building a deep thunk, then evaluating, needing much stack.<br />
<br />
Most puzzling is why the former succeeds without a stack overflow. This is caused by a combination of two factors:<br />
* thunks in the list produced by <hask>scanl</hask> enjoy sharing: late thunks build upon early thunks<br />
* printing a list of numbers evaluates early thunks and then late thunks<br />
To exemplify, here is an abridged progression. I use this pseudo format to depict sharing of thunks<br />
<haskell><br />
expr where var=expr, var=expr<br />
</haskell><br />
although in reality it is more like a pointer graph.<br />
<haskell><br />
print (scanl (+) 0 [1..1000000]) -><br />
print (a : case [1..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (a+x) xs) where a=0 -><br />
<nowiki>... evaluate a to 0 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (a+1) [2..1000000]) where a=0 -><br />
print (b : case [2..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (b+x) xs) where a=0, b=a+1 -><br />
<nowiki>... evaluate b to 1 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (b+2) [3..1000000]) where b=1 -><br />
print (c : case [3..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (c+x) xs) where b=1, c=b+2 -><br />
<nowiki>... evaluate c to 3 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (c+3) [4..1000000]) where c=3 -><br />
print (d : case [4..1000000] of <nowiki>...</nowiki> x:xs -> scanl (+) (d+x) xs) where c=3, d=c+3 -><br />
<nowiki>... evaluate d to 6 for printing, I/O, some more steps ...</nowiki> -><br />
<br />
print (scanl (+) (d+4) [5..1000000]) where d=6 -> etc.<br />
</haskell><br />
The important thing to watch is the life cycle of intermediate thunks, e.g., <hask>c</hask> is created at some point as a 1-level deep addition, then almost immediately reduced to a number out of necessity, before a later thunk <hask>d</hask> builds upon it. Therefore there is no growth and no stack overflow.<br />
<br />
In contrast, again, <hask>last (scanl (+) 0 [1..1000000])</hask> skips over to the last thunk right away. Since early items are not reduced yet, the last item remains a huge chain and causes overflow.<br />
<br />
As an addendum, there are three ways of handling this problem and similar ones:<br />
# You can have your traversal functions (in this case, last) force the list as it goes along.<br />
# You can use (perhaps custom) versions of the list (or data structure, in general) producing functions (in this case, scanl) that force the elements as it builds the data structure.<br />
# You can use a data structure that's strict in its elements, in this case it would be a head strict list.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=16968Performance/Monads2007-11-24T05:22:02Z<p>Derek Elkins: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
<br />
Note that M's (>>=) operation isn't used. It comes up when you implement the other operations M supports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
How and why does this work? We're basically specializing <hask>>>=</hask>. Before, we had<br />
<haskell><br />
m >>= f = case m of<br />
Just a -> f a<br />
Nothing -> Nothing<br />
</haskell><br />
i.e. the monadic bind does a case analysis on how to proceed. In the CPS-representation, we're specializing bind to the two possible constructors:<br />
<haskell><br />
return' a := (return a >>=) = (Just a >>=) = \f -> f a<br />
mzero' := (mzero >>=) = (Nothing >>=) = \f -> Nothing<br />
</haskell><br />
and the case analysis is now "built-in" into <hask>return'</hask> and <hask>mzero'</hask>. In general, embedding a monad in <hask>Cont</hask> specializes <hask>>>=</hask> to its primitive operations, like for example <hask>mzero</hask> or <hask>get</hask>. This is close to specifying the operational semantics of <hask>>>=</hask> directly and can hence be used to implement the monad in the first place, too.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing) -- equivalent to MaybeCPS (Nothing >>=)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16896AmeroHaskell2007-11-18T03:32:32Z<p>Derek Elkins: </p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
Now a Haskell get together(s) anywhere in the USA with at least one in Portland, OR.<br />
<br />
== Likely Attendees ==<br />
<br />
=== Western ===<br />
<br />
* [[User:Taral|Taral]] - Seattle, WA, will travel.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[TimChevalier]] - Portland, OR. Might be willing to travel, depending on where and when.<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
<br />
=== Eastern ===<br />
<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. <br />
* [[Bjorn Buckwalter]] - Washington, DC. Unlikely to travel.<br />
* [[Betty]] - Raleigh, NC<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.) and/or something on using types to enforce invariants without going ''too'' crazy (e.g. wrapper types, phantom types, type class traits, reasonable examples of type level programming)<br />
* [[TimChevalier]] - if you're really hard up for speakers, I could scrape something up.<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame<br />
* Maybe during SIGCSE in Portland March 12-15<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16895AmeroHaskell2007-11-18T03:28:44Z<p>Derek Elkins: sorted geographically</p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
Now a Haskell get together(s) anywhere in the USA with at least one in Portland, OR.<br />
<br />
== Likely Attendees ==<br />
<br />
* [[User:Taral|Taral]] - Seattle, WA, will travel.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[TimChevalier]] - Portland, OR. Might be willing to travel, depending on where and when.<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. <br />
* [[Bjorn Buckwalter]] - Washington, DC. Unlikely to travel.<br />
* [[Betty]] - Raleigh, NC<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.) and/or something on using types to enforce invariants without going ''too'' crazy (e.g. wrapper types, phantom types, type class traits, reasonable examples of type level programming)<br />
* [[TimChevalier]] - if you're really hard up for speakers, I could scrape something up.<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame<br />
* Maybe during SIGCSE in Portland March 12-15<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16892AmeroHaskell2007-11-18T01:51:03Z<p>Derek Elkins: </p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
Now a Haskell get together(s) anywhere in the USA with at least one in Portland, OR.<br />
<br />
== Likely Attendees ==<br />
<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Betty]] - Raleigh, NC<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
* [[TimChevalier]] - Portland, OR. Might be willing to travel, depending on where and when.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.) and/or something on using types to enforce invariants without going ''too'' crazy (e.g. wrapper types, phantom types, type class traits, reasonable examples of type level programming)<br />
* [[TimChevalier]] - if you're really hard up for speakers, I could scrape something up.<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame<br />
* Maybe during SIGCSE in Portland March 12-15<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16891AmeroHaskell2007-11-18T01:40:31Z<p>Derek Elkins: </p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
Now a Haskell get together(s) anywhere in the USA with at least one in Portland, OR.<br />
<br />
== Likely Attendees ==<br />
<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Betty]] - Raleigh, NC<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
* [[TimChevalier]] - Portland, OR. Might be willing to travel, depending on where and when.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.) and/or something on using types to enforce invariants without going ''too'' crazy (e.g. wrapper types, phantom types, type class traits, reasonable examples of type level programming)<br />
* [[TimChevalier]] - if you're really hard up for speakers, I could scrape something up.<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Category:History&diff=16888Category:History2007-11-18T00:19:50Z<p>Derek Elkins: removed spam</p>
<hr />
<div>[[Category:Community]]<br />
<br />
Articles related to the evolution of Haskell or other developments related to the language.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16887AmeroHaskell2007-11-18T00:16:11Z<p>Derek Elkins: added to Category:Events</p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
Now a Haskell get together(s) anywhere in the USA with at least one in Portland, OR.<br />
<br />
== Likely Attendees ==<br />
<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Betty]] - Raleigh, NC<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.)<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=OzHaskell&diff=16886OzHaskell2007-11-18T00:13:39Z<p>Derek Elkins: added to Category:Events</p>
<hr />
<div>'''There is AngloHaskell and now AmeroHaskell. Doesn't that call for OzHaskell?'''<br />
<br />
Who would be interested to have a Haskell event in Australia, possibly in Sydney? This is just a wild idea without any concrete date or format yet. Jot down any suggestions on this page.<br />
<br />
Interested Haskellers:<br />
<br />
* [[:User:Chak|Manuel Chakravarty]] (Sydney)<br />
* [[:User:TonyMorris|Tony Morris]] (Brisbane)<br />
* [[:User:Brecknell|Matthew Brecknell]] (Brisbane, will travel, prefer late Jan)<br />
* [[:User:Mark_Wassell|Mark Wassell]] - Prefer Jan/Feb option.<br />
* [[:User:Rl|Roman Leshchinskiy]]<br />
* [[:User:cbrad|Brad Clow]] (Brisbane)<br />
* [[:User:nornagon|Jeremy Apthorp]]<br />
* [[:User:AndrewA|Andrew Appleyard]] (Sydney)<br />
* [[:User:bjpop|Bernie Pope]] (Melbourne)<br />
* [[:User:benl23|Ben Lippmeier]]<br />
* [[:User:RohanDrape|Rohan Drape]] (Melbourne)<br />
* [[:User:ivanm|Ivan Miljenovic]] (Brisbane)<br />
* [[:User:EricWilligers|Eric Willigers]]<br />
* [[:User:TonySloane|Tony Sloane]] (Sydney)<br />
* [[:User:Bens|Ben Sinclair]] (Sydney)<br />
* [[:User:andrep|Andre Pang]]<br />
* [[:User:AndrewBromage|Andrew Bromage]] (Melbourne)<br />
* [[:User:Droberts|Dale Roberts]] (Sydney)<br />
* [[:User:GeoffWilson|Geoff Wilson]] (Melbourne)<br />
* [[:User:Saulzar|Oliver Batchelor]] (Brisbane)<br />
* [[:User:Nick|Nick Seow]] (Sydney)<br />
* [[:User:sseefried|Sean Seefried]] (Sydney)<br />
* [[:User:green_tea|Alexis Hazell]] (Melbourne)<br />
* [[:User:PhilipDerrin|Philip Derrin]] (Sydney)<br />
* [[:User:Jeeva|Jeeva]] (Sydney)<br />
* [[:User:michaelneale|Michael Neale]] (Brisbane)<br />
* [[:User:rus|Ruslan Abdulkhalikov]] (Sydney)<br />
* [[:User:doverton|David Overton]] (London, soon to be Melbourne)<br />
(Add your name!)<br />
<br />
== Possible dates ==<br />
<br />
Shall we try to organise something for sometime over the summer? Avoiding the summer holidays, either of the following two periods seem attractive:<br />
<br />
* last week of November/first week of December or<br />
* last week of January/first week of February.<br />
<br />
(Add any additional periods that you would find attractive and/or comment on suitability.)<br />
<br />
Events to avoid clashing with:<br />
<br />
* The 2007 federal election (weekend of 24-25 November).<br />
* linux.conf.au (28 Jan - 2 Feb 2007, unless it's held in conjunction).<br />
* Inevitable family Christmas parties/holiday travel rush (some weekends in December, different for everyone I suspect).<br />
* www.oscd.com.au - late november in Brisbane<br />
<br />
== Format ==<br />
<br />
How about the following?<br />
<br />
* One day meeting with informal talks and demos (preferably on a Friday)<br />
* There could be a second, even less formal day, for those who want to hang out some more and maybe some hacking<br />
* Run it at the University of New South Wales, Sydney<br />
<br />
(Add your thoughts to the above.)<br />
<br />
== Talks and demos ==<br />
<br />
Do you have anything you'd like to talk about or a system you'd like to demo? '''This is just a tentative list - you commit to nothing.'''<br />
<br />
=== Talk proposals ===<br />
<br />
* Manuel Chakravarty: ''Type-level Programming with Type Families''<br />
::GHC recently gained support for data families and type synonym families (which are a generalisation of our earlier proposal for associated types). In this talk, I'd give an overview over this new language feature, illustrate what it is good for, and discuss why I believe it fits Haskell better than functional dependencies.<br />
* Bernie Pope: ''The GHCi debugger''<br />
:: A new breakpoint debugger has been added to GHCi. In this talk, I'd demonstrate how to use the debugger, and also go into some detail about how it works. I might even discuss the relative advantages and disadvantages of this debugger over tools such as Hat.<br />
<br />
=== Demo proposals ===<br />
<br />
* rohan drape: ''supercollider for haskellers''<br />
:: an introduction to, and demonstration of, the [http://slavepianos.org/rd/f/207949/ hsc3] haskell bindings to the [http://supercollider.svn.sourceforge.net/viewvc/*checkout*/supercollider/trunk/build/Help/Help.html supercollider3] real-time audio synthesiser; or making experimental music in experimental haskell.<br />
<br />
[[Category:Events]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=16885AmeroHaskell2007-11-17T23:46:56Z<p>Derek Elkins: </p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
<br />
== Likely Attendees ==<br />
<br />
* [[ShaeErisson]] - located in Tuscaloosa, Alabama - pretty much any date is good for me.<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey) - Washington, DC. Willing to travel some, probably can't take any time off of work but most weekends are good except Nov. 2-4 and 16-18.<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.<br />
* [[Dino]] Morelli - Raleigh, North Carolina. Will travel some, can stay somewhere overnight(s). Week of Oct 13-20 is not doable.<br />
* [[Betty]] - Raleigh, NC<br />
* [[User:CliffordBeshers|CliffordBeshers]] - San Diego, CA, but would consider travelling.<br />
* [[JohnMeacham]] - Pasadena, CA. might be able to travel depending on when. (would prefer somewhere on west coast)<br />
* [[GregFitzgerald]] - San Diego, CA<br />
* [[Adam Peacock]] - NYC, I might come, but Nov 24 to Dec 9 I'm traveling elsewhere.<br />
* [[Peter Gavin]] - Tallahassee, FL, willing to drive a few hours; weekends are best<br />
* [[Bernard Putersznit]] - Ocala, FL, willing to drive a few hours; any day of the week. Available from November onward.<br />
* [[Rahul Kapoor]] - Providence, RI, will travel for Haskell.<br />
* [[BryanOSullivan]] - San Francisco, CA, will travel.<br />
<br />
== Possible locations ==<br />
<br />
* Portland, OR<br />
* Although this is in the North East, Credit Suisse - contact Adam Peacock<br />
<br />
== Potential Presenters ==<br />
<br />
* [[Derek Elkins]] - I can provide a talk for categorical ideas that are directly applicable in Haskell (e.g. free monads, initial algebras, etc.)<br />
<br />
== When ==<br />
<br />
* For a Portland meeting, probably in a January/February time-frame</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=16462Performance/Monads2007-10-29T23:56:53Z<p>Derek Elkins: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
<br />
Note that M's (>>=) operation isn't used. It comes up when you implement the other operations M supports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing) -- equivalent to MaybeCPS (Nothing >>=)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=16426Performance/Monads2007-10-29T13:08:47Z<p>Derek Elkins: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
<br />
Note that M's (>>=) operation isn't used. It comes up when you implement the other operations M suports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing) -- equivalent to MaybeCPS (Nothing >>=)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Performance/Monads&diff=16415Performance/Monads2007-10-28T23:59:02Z<p>Derek Elkins: Using CPS for faster monads</p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|Monads]]<br />
== Unroll your MTL stacks ==<br />
<br />
MTL is an excellent library for programming with monads. However stacked monad transformers do not inline well and the library is in need of an optimization pass. As a result, it can often impose a performance hit of up to 300% (your code will run up to three times slower). <br />
<br />
If you care about this, the best option is to flatten you stack of transformers into a single, hand unrolled monad. An extreme example follows.<br />
<br />
This is a typical MTL monad stack<br />
<br />
newtype DRM a = DRM {unDRM:: ErrorT Finish (RWS () DNA RNA) a}<br />
deriving (MonadState DNA, MonadWriter RNA, MonadError Finish, Monad)<br />
<br />
We can unroll it as follows:<br />
<br />
<haskell><br />
type DRM = DRMonad Finish DNA RNA<br />
newtype DRMonad e s w a = DRMonad {runDRMonad :: s -> (Either e a,s,w)}<br />
<br />
instance (Monoid m, Error e) => Monad (DRMonad e s w) where<br />
return x = DRMonad(\s -> (Right x, s, mempty))<br />
(>>= = bindDRMonad<br />
fail _ = DRMonad (\s->(Left e,s,mempty))<br />
<br />
{-# INLINE bindDRMonad #-}<br />
{-# INLINE bindDRMonad2 #-}<br />
bindDRMonad :: Monoid m => DRMonad a e s w -> (a -> DRMonad b e s w) -> DRMonad b e s w<br />
bindDRMonad m f = DRMonad$ \s -> case runDRMonad m s of<br />
(x',s',w) -><br />
bindDRMonad2 x' (s',w,f)<br />
bindDRMonad2 x' (s',w, f) = case x' of <br />
Left e -> (Left e, s', w)<br />
Right r -> case runDRMonad (f r) s' of<br />
(x'',s'',w') -><br />
(x'', s'', w `mappend` w')<br />
</haskell><br />
<br />
After this, you will also want to add the instances for MonadState, MonadWriter, etc.<br />
<br />
== Use [[Continuation | Continuation Passing Style]] ==<br />
<br />
It is well known that every monad can be "embedded" into the continuation passing monad, Cont. All that is necessary is to make the "answer type" of the Cont monad be the desired monad, e.g.<br />
<haskell><br />
type MCPS a = forall r. Cont (M r) a<br />
<br />
runMCPS m = runCont m return<br />
</haskell><br />
<br />
Note that M's (>>=) operation isn't used. It comes up when you implement the other operations M suports.<br />
<br />
In many cases, this will effectively avoid a layer of interpretation in much of the code using M. To see this, let's look at code that would benefit from using the Maybe monad.<br />
<haskell><br />
liftMaybe2 :: (a -> b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c<br />
liftMaybe2 f a b =<br />
case a of<br />
Nothing -> Nothing<br />
Just a' -> case b of<br />
Nothing -> Nothing<br />
Just b' -> f a' b'<br />
</haskell><br />
<br />
This code screams for using Maybe as a monad in which case it will look like,<br />
<haskell><br />
liftMaybe2 f a b = do<br />
a' <- a<br />
b' <- b<br />
f a' b'<br />
<br />
-- or just<br />
liftMaybe2 = liftM2<br />
</haskell><br />
<br />
One things to note about the original code is that it must constantly check the returned value even though a failure (Nothing) is most likely a rare occurrence, and further more it's possible that we will need to propagate a Nothing through an arbitrary large amount of code, though a lot of times this won't happen.<br />
<br />
Ideally, we want "failure free" code to run as normal and only deal with failure when it occurs and ''immediately'' fail in those cases rather than propagating the failure. This is what using continuation passing style gets us.<br />
<br />
Explicitly expanding Cont we get,<br />
<haskell><br />
newtype MaybeCPS a = MaybeCPS { unMaybeCPS :: forall r. (a -> Maybe r) -> Maybe r }<br />
<br />
runMaybeCPS m = unMaybeCPS m return<br />
<br />
-- The Cont definitions of return and (>>=)<br />
instance Monad MaybeCPS where<br />
return a = MaybeCPS (\k -> k a)<br />
MaybeCPS m >>= f = MaybeCPS (\k -> m (\a -> unMaybeCPS (f a) k))<br />
</haskell><br />
<br />
Note that this code is just normal CPS code and completely independent of the Maybe monad. There are no case analyses. So, "failure free" code will run as normal (CPS) code.<br />
<br />
Now we need to implement the operations.<br />
<haskell><br />
instance MonadPlus MaybeCPS where<br />
mzero = MaybeCPS (\_ -> Nothing)<br />
m `mplus` n = case runMaybeCPS m of<br />
Nothing -> n<br />
Just a -> return a<br />
</haskell><br />
<br />
There are two things to note about this code. mplus is where we use the case analysis. mplus is the only place that we look at what was returned and to do it we have to actually run the computation. This means that we only deal with "effects" when we need to. Further, mzero discards its continuation. This is the typical pattern for aborting a computation in CPS and will lead to an ''immediate'' termination of the computation.<br />
<br />
MaybeCPS should be faster than using Maybe in most cases and should be almost a drop in replacement for Maybe. Usually, using a CPS implementation would be a drop in replacement, but Maybe is not an abstract data type. Anyway, some results for a more complicated example are [http://r6.ca/blog/20071028T162529Z.html here].</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=AmeroHaskell&diff=15580AmeroHaskell2007-09-14T17:14:43Z<p>Derek Elkins: </p>
<hr />
<div>AmeroHaskell, a Haskell get together for/in the SouthEastern USA.<br />
<br />
Likely Attendees:<br />
* [[ShaeErisson]]<br />
* [http://www.travishartwell.net/blog/ Travis B. Hartwell] aka Nafai<br />
* [http://byorgey.wordpress.com Brent Yorgey] (byorgey)<br />
* [[DonStewart]], in OR, but would travel for haskell<br />
* [[Derek Elkins]], in TX, would travel some, probably would only stay for a day or two.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Haskell_Cafe_migration&diff=14287Haskell Cafe migration2007-07-14T00:04:53Z<p>Derek Elkins: </p>
<hr />
<div>Often people post wonderful material to the mailing lists. This can<br />
later be hard to find. The goal of this page is to collect a list of <br />
people who are happy for their contributions to be added directly to<br />
the Haskell wiki.<br />
<br />
If you are happy for your contributions on the Haskell mailing lists to<br />
be relicensed and moved to the new wiki when appropriate, please add<br />
your name to this list, so that others may move your contributions<br />
without fear.<br />
<br />
Contributions will be licensed specifically under a<br />
[[HaskellWiki:Copyrights|Simple Permissive License]].<br />
<br />
* Don Stewart<br />
* Derek Elkins<br />
<br />
[[Category:Community]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Introduction/Direct_Translation&diff=12964Introduction/Direct Translation2007-05-06T20:53:32Z<p>Derek Elkins: </p>
<hr />
<div><haskell><br />
import Control.Monad (when)<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.IArray<br />
import Data.Array.MArray<br />
import System.IO.Unsafe<br />
<br />
qsort :: (IArray a e,Ix i,Enum i,Ord e) => a i e -> a i e<br />
qsort arr = processArray quickSort arr<br />
<br />
processArray <br />
:: (IArray a e,IArray b e,Ix i) <br />
=> (forall s. (STArray s) i e -> ST s ()) -> a i e -> b i e<br />
processArray f (arr :: a i e) = runST (do<br />
arr' <- thaw arr :: ST s (STArray s i e)<br />
f arr'<br />
unsafeFreeze arr')<br />
<br />
quickSort :: (MArray a e m, Ix i, Enum i, Ord e) => a i e -> m ()<br />
quickSort arr = case bounds arr of (lo,hi) -> qsort lo hi<br />
where qsort lo hi | lo >= hi = return ()<br />
| otherwise = do<br />
p <- readArray arr hi<br />
l <- mainLoop p lo hi<br />
swap l hi<br />
qsort lo (pred l)<br />
qsort (succ l) hi<br />
<br />
mainLoop p l h | l >= h = return l<br />
| otherwise = do<br />
l' <- doTil (\l' b -> l' < h && b <= p) succ l <br />
h' <- doTil (\h' b -> h' > l' && b >= p) pred h<br />
when (l' < h') $<br />
swap l' h'<br />
mainLoop p l' h'<br />
<br />
doTil pred op ix = do<br />
b <- readArray arr ix<br />
if pred ix b then doTil pred op (op ix) else return ix<br />
<br />
swap xi yi = do<br />
x <- readArray arr xi<br />
readArray arr yi >>= writeArray arr xi<br />
writeArray arr yi x<br />
</haskell><br />
<br />
This uses various extensions to make the types ridiculously general, but the actual algorithm (quickSort) is plain Haskell.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Research_papers/Functional_pearls&diff=12952Research papers/Functional pearls2007-05-05T23:30:47Z<p>Derek Elkins: </p>
<hr />
<div>Functional pearls are elegant, instructive examples of functional programming. They are supposed to be fun, and they teach important programming techniques and fundamental design principles. They traditionally appear in [http://www.cambridge.org/journals/JFP/ The Journal of Functional Programming], and at [http://www.icfpconference.org/index.html ICFP] and affiliated workshops.<br />
<br />
The history of functional pearls is covered by:<br />
<br />
;[http://icfp06.cs.uchicago.edu/bird-talk.pdf How to Write a Functional Pearl]<br />
:Richard Bird. ICFP 2006.<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1159832&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 Fifteen years of functional pearls]<br />
:Richard Bird. ICFP 2006.<br />
<br />
;[http://spivey.oriel.ox.ac.uk/mike/firstpearl.pdf Strachey's functional pearl, forty years on]<br />
:Mike Spivey, 2006.<br />
<br />
There have been some 64 functional pearls in JFP, and some others at<br />
ICFP and the Haskell Workshop. There is also a collection of them in<br />
[http://web.comlab.ox.ac.uk/oucl/publications/books/fop/ The Fun of Programming].<br />
<br />
The pearls tend to concentrate on:<br />
<br />
* Examples of program calculation and proof<br />
* Neat presentations of new or old data structures<br />
* Interesting applications and techniques<br />
<br />
=== Online ===<br />
<br />
Functional pearls online:<br />
<br />
;[http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf Applicative Programming with Effects]<br />
:Conor McBride and Ross Paterson. 2006.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/rationals.pdf Enumerating the rationals]<br />
:Jeremy Gibbons, David Lester and Richard Bird. 2006.<br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/papers/PFP_JFP06.pdf Probabilistic functional programming in Haskell]<br />
:Martin Erwig and Steve Kollmansberger. 2006. <br />
<br />
;[http://cms.brookes.ac.uk/staff/SharonCurtis/publications/marbles.ps.gz Marble mingling]<br />
:Sharon Curtis. 2006.<br />
<br />
;[http://wiki.di.uminho.pt/twiki/pub/Personal/Xana/WebHome/report.pdf Strong Types for Relational Databases]<br />
:Alexandra Silva, Joost Visser. 2006. (Haskell Workshop)<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1086390&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 Backtracking, interleaving, and terminating monad transformers]<br />
:Oleg Kiselyov, Chung-chieh Shan, Daniel P. Friedman, Amr Sabry. 2005. <br />
<br />
;[http://homepages.inf.ed.ac.uk/jcheney/publications/cheney05icfp.pdf Scrap your Nameplate]<br />
:James Cheney. 2005.<br />
<br />
;[http://www.cs.dartmouth.edu/~doug/nfa.ps.gz Enumerating the strings of regular languages]<br />
:M. Douglas McIlroy. 2004.<br />
<br />
;[http://pauillac.inria.fr/~maranget/enum/pearl.ps Functional satisfaction]<br />
:Luc Maranget. 2004. ([http://pauillac.inria.fr/~maranget/enum/index.html More info]).<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1017481&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 Implicit configurations--or, type classes reflect the values of types]<br />
:Oleg Kiselyov, Chung-chieh Shan. 2004. ([http://www.cs.rutgers.edu/~ccshan/prepose/p1214-kiselyov.pdf also here])<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/Globals.ps Global variables in Haskell]<br />
:John Hughes. 2004. ([http://journals.cambridge.org/action/displayAbstract?fromPage=online&aid=241773 JFP])<br />
<br />
;[http://portal.acm.org/ft_gateway.cfm?id=1017477&type=pdf&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618 I am not a number -- I am a free variable]<br />
:Conor McBride, James McKinna. 2004. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/2.ps.gz Inverting the Burrows Wheeler transform]<br />
:Richard Bird and Shin-Cheng Mu. 2004.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/wg21/meeting56/loeh-paper.pdf Parsing permutation phrases]<br />
:Arthur Baars, Andres Loh and S. Doaitse Swierstra. 2004.<br />
<br />
;[http://web.cecs.pdx.edu/~antoy/homepage/publications/inject/paper.pdf Concurrent distinct choices]<br />
:Sergio Antoy and Michael Hanus. 2004. <br />
<br />
;[http://www.ling.gu.se/~peb/pubs/p04-chart-pearl.pdf Functional chart parsing of context-free grammars]<br />
:Peter Ljunglf. 2004.<br />
<br />
;[http://www.seas.upenn.edu/~sweirich/papers/cast/cast.pdf Type-Safe Cast]<br />
:Stephanie Weirich. 2004.<br />
<br />
;[http://research.microsoft.com/~akenn/fun/picklercombinators.pdf Pickler Combinators]<br />
:Andrew J. Kennedy. 2004.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/jfp04-parser.ps Parallel Parsing Processes]<br />
:Koen Claessen. 2004.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/hw2001/1.pdf Derivation of a logarithmic time carry lookahead addition circuit]<br />
:John O'Donnell and Gudula Runger. 2004. ([http://portal.acm.org/citation.cfm?coll=GUIDE&dl=GUIDE&id=1030343 ACM]) ([http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=254718 JFP]) ([http://www.informatik.uni-bonn.de/~ralf/hw2001/1.html Homepage]). <br />
<br />
;[http://www.lri.fr/~filliatr/ftp/publis/kr-fp.ps.gz Producing all ideals of a forest, functionally]<br />
:Jean-Christophe Fillitre and Franois Pottier. 2003.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/HW2003.pdf Trouble shared is trouble halved]<br />
:Richard Bird, Ralf Hinze. 2003<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/Format.ps.gz Formatting: a class act]<br />
:Ralf Hinze. 2003.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/SearchTree.ps.gz A fresh look at binary search trees]<br />
:Ralf Hinze. 2002.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/countdown.pdf The countdown problem]<br />
:Graham Hutton. 2002. <br />
<br />
;[http://pdos.csail.mit.edu/papers/packrat-parsing:icfp02.pdf Packrat parsing: simple, powerful, lazy, linear time, functional pearl]<br />
:Bryan Ford. 2002.<br />
<br />
;[http://eprints.ouls.ox.ac.uk/archive/00000863/01/bird_2001_11_3.pdf Unfolding pointer algorithms]<br />
:Richard Bird. 2001.<br />
<br />
;[http://eprints.ouls.ox.ac.uk/archive/00000862/01/bird_2001.pdf Maximum marking problems]<br />
:Richard Bird. 2001. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/TheWeb.ps.gz Weaving a web]<br />
:Ralf Hinze and Johan Jeuring. 2001. <br />
<br />
;[http://www.brics.dk/RS/01/16/BRICS-RS-01-16.pdf Normalization by evaluation with typed abstract syntax]<br />
:Olivier Danvy, Morten Rhiger and Kristoffer H. Rose. 2001. <br />
<br />
;[http://www.brics.dk/RS/01/10/BRICS-RS-01-10.ps.gz Do we need dependent types?]<br />
:Daniel Fridlender and Mia Indrika. 2001.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/IAI-TR-99-4.ps.gz Perfect trees and bit-reversal permutations]<br />
:Ralf Hinze. 2000.<br />
<br />
;[http://spivey.oriel.ox.ac.uk/mike/bfs/bfs.ps Combinators for breadth-first search]<br />
:Michael Spivey. 2000 <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/icfp00.ps Breadth-First Numbering: Lessons from a Small Exercise in Algorithm Design]<br />
:Chris Okasaki. 2000.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/ICFP00.ps.gz Deriving Backtracking Monad Transformers]<br />
:Ralf Hinze. 2000.<br />
<br />
;[http://www.cis.upenn.edu/~bcpierce/papers/rsr.ps Recursive subtyping revealed]<br />
:Vladimir Gapeyev, Michael Y. Levin, Benjamin C. Pierce. 2000.<br />
<br />
;[http://research.microsoft.com/Users/simonpj/Papers/financial-contracts/contracts-icfp.ps.gz Composing contracts: an adventure in financial engineering]<br />
:Simon Peyton Jones, Jean-Marc Eber, Julian Seward. 2000.<br />
<br />
;[http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps A poor man's concurrency monad]<br />
:Koen Claessen. 1999. <br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/BinomialHeaps.ps.gz Explaining binomial heaps]<br />
:Ralf Hinze. 1999. <br />
<br />
;[http://www.cs.dartmouth.edu/~doug/pearl.ps.gz Power series, power serious]<br />
:M. Douglas McIlroy. 1999. <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/jfp99.ps Red-black trees in a functional setting]<br />
:Chris Okasaki. 1999. <br />
<br />
;[http://www.cs.cmu.edu/~rwh/papers/regexp/jfp.ps Proof-directed debugging]<br />
:Robert Harper. 1999. (see also [http://ropas.snu.ac.kr/~kwang/paper/06-jfp-yi.pdf Proof-directed debugging: revisited for a first-order version]).<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/radix.ps.gz A pointless derivation of radix sort]<br />
:Jeremy Gibbons. 1999.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/pearl.pdf Monadic parsing in Haskell]<br />
:Graham Hutton and Erik Meijer . 1998.<br />
<br />
;[http://www.cs.chalmers.se/~patrikj/poly/unify/PolytypicUnification.ps Polytypic unification]<br />
:Patrik Jansson and Johan Jeuring. 1998. <br />
<br />
;[http://web.engr.oregonstate.edu/~erwig/papers/Diet_JFP98.pdf Diets for fat sets]<br />
:Martin Erwig. 1998. <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/jfp98.ps Even higher-order functions for parsing or Why would anyone ever want to use a sixth-order function?]<br />
:Chris Okasaki. 1998.<br />
<br />
;[http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf The Zipper]<br />
:Gerard Huet. 1997. (See also [http://en.wikibooks.org/wiki/Haskell/Zippers The Haskell Wikibook]).<br />
<br />
;[http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes]<br />
:Colin Runciman. 1997. <br />
<br />
;[http://www.eecs.usma.edu/webs/people/okasaki/jfp97.ps Three algorithms on Braun trees]<br />
:Chris Okasaki. 1997. <br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/thirdht.ps.gz The Third Homomorphism Theorem]<br />
:Jeremy Gibbons. 1996.<br />
<br />
;[http://www.cs.nott.ac.uk/~gmh/basics.pdf Back to Basics: Deriving Representation Changers Functionally].<br />
:Graham Hutton, Erik Meijer. 1996.<br />
<br />
;[http://research.microsoft.com/~akenn/fun/DrawingTrees.pdf Drawing Trees]<br />
:Drawing Trees. 1996.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/drawing.ps.gz Deriving Tidy Drawings of Trees]<br />
:Jeremy Gibbons. 1996. (See also [http://www.cs.auckland.ac.nz/CDMTCS//researchreports/003drawing.pdf the research report]).<br />
<br />
;[http://www.swiss.ai.mit.edu/~adams/BB Efficient Sets - A Balancing Act]<br />
:Stephen Adams. 1993. ([http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Set.html Data.Set]).<br />
<br />
=== Potential Pearls ===<br />
<br />
Unpublished pearls.<br />
<br />
;[http://www.informatik.uni-bonn.de/~ralf/publications/Quote.pdf Typed Quote/AntiQuote]<br />
:Ralf Hinze. Unpublished work in progress.<br />
<br />
=== Offline ===<br />
<br />
These appear not to be available online, unfortunately. If you know where they live, please link, and move into the 'online' section!<br />
<br />
;[http://www.journals.cambridge.org/action/displayAbstract?fromPage=online&aid=254707 Linear lambda calculus and PTIME-completeness]<br />
:Harry G. Mairson. 2004. <br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=254714 Composing fractals]<br />
:Mark P. Jones. 2004. [http://portal.acm.org/citation.cfm?id=1030333.1030344&coll=GUIDE&dl=GUIDE&CFID=15151515&CFTOKEN=6184618 ACM]<br />
<br />
;[http://journals.cambridge.org/article_S0956796804005210 Calculating the Sieve of Eratosthenes]<br />
:Lambert Meertens. Journal of Functional Programming, 14(6):759-763, 2004 ([http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/wg21/meeting57/meertens-sieve.pdf slides])<br />
<br />
;[http://www.cs.kent.ac.uk/pubs/2001/1293/index.html Red-black trees with types]<br />
:Stefan Kahrs. 2001. ([http://journals.cambridge.org/article_S0956796801004026 JFP]) ([http://www.cs.kent.ac.uk/people/staff/smk/redblack/rb.html Code!])<br />
<br />
;On generating unique names<br />
:Lennart Augustsson, M Rittri, D Synek. 1994. ([http://www.cs.chalmers.se/~rittri/#publications Rittri's homepage])<br />
<br />
;A Symmetric Set of Efficient List Operations.<br />
:Rob R. Hoogerwoord, 1992. ([https://venus.tue.nl/ep-cgi/ep_publ.opl?taal=NL&fac_id=92&rn=19840694 Hoogerwoord's homepage]).<br />
<br />
;[http://journals.cambridge.org/action/displayAbstract?fromPage=online&aid=335124 Finding celebrities: A lesson in functional programming]<br />
:Richard Bird and Sharon Curtis. 2006. ([http://cms.brookes.ac.uk/staff/SharonCurtis/publications/index.html#celebrities See also]).<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=451101 A program to solve Sudoku]<br />
:Richard Bird. 2006. (slides [http://icfp06.cs.uchicago.edu/bird-talk.pdf appear here]).<br />
<br />
;[http://www.journals.cambridge.org/action/displayAbstract?fromPage=online&aid=254705 On tiling a chessboard]<br />
:Richard Bird. 2004. ([http://portal.acm.org/citation.cfm?id=1030333.1030336 ACM]) <br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=44142 Meertens number]<br />
:Richard Bird. 1998.<br />
<br />
;[http://journals.cambridge.org/production/action/cjoGetFulltext?fulltextid=44092 On merging and selection]<br />
:Richard Bird. 1997. (See also [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/merging.ps.gz More on Merging and Selection]).<br />
<br />
;[http://journals.cambridge.org/article_S0956796897002803 On building trees with minimum height]<br />
:Richard Bird. 1997. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird97:OnBuilding Bib]).<br />
<br />
;The Last Tail. <br />
:Richard Bird. 1993. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird93:Last Bib]).<br />
<br />
;Two Greedy Algorithms<br />
:Richard Bird, 1992. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#Bird92:Two Bib]).<br />
<br />
;On Removing Duplicates<br />
:Richard Bird. 1991. ([http://web.comlab.ox.ac.uk/oucl/work/richard.bird/publications-bib.html#DBLP:journals/jfp/Bird91a Bib]).<br />
<br />
[[Category:Research]] [[Category:Tutorials]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Introduction&diff=11937Introduction2007-03-13T04:45:16Z<p>Derek Elkins: </p>
<hr />
<div>[[Category:Tutorials]] [[Category:Language]]<br />
Haskell is a computer programming language. In particular, it is a<br />
'' polymorphically typed, lazy, purely functional '' language, quite<br />
different from most other programming languages. <br />
The language is named for [[Haskell Brooks Curry]], whose work in mathematical logic serves as a foundation for<br />
functional languages. <br />
Haskell is based on ''lambda calculus'', hence the lambda we use as<br />
a logo.<br />
<br />
<br />
==Why use Haskell?==<br />
Writing large software systems that<br />
work is difficult and expensive. Maintaining those systems is even<br />
more difficult and expensive. Functional programming languages, such<br />
as Haskell, can make it easier and cheaper. For example, a new user who<br />
wrote a small relational DBMS in Haskell had this to say:<br />
<blockquote><br />
WOW! I basically wrote this without testing just thinking about my<br />
program in terms of transformations between types. I wrote the<br />
test/example code and had almost no implementation errors in the code! The<br />
compiler/type-system is really really good at preventing you from<br />
making coding mistakes! I've never in my life had a block of code<br />
this big work on the first try. I am WAY impressed.<br />
</blockquote><br />
Even if you are not in a position to use Haskell in your programming projects, learning Haskell can make you a better programmer in any language. <br />
<blockquote><br />
I learned Haskell a couple of years ago, having previously programmed in<br />
Python and (many) other languages. Recently, I've been using Python for a<br />
project (the choice being determined by both technical and non-technical<br />
issues), and find my Python programming style is now heavily influenced (for the better, I hope ;-) by my Haskell programming experience.<br><br><br />
Graham Klyne<br />
</blockquote><br />
<br />
<br />
Haskell offers you:<br />
<br />
*Substantially increased programmer productivity (Ericsson measured an improvement factor of between 9 and 25 using Erlang, a functional programming language similar to Haskell, in one set of experiments on telephony software).<br />
*Shorter, clearer, and more maintainable code.<br />
*Fewer errors, higher reliability.<br />
*A smaller &quot;semantic gap&quot; between the programmer and the language.<br />
*Shorter lead times.<br />
<br />
Haskell is a wide-spectrum language, suitable for a variety of<br />
applications. It is particularly suitable for programs which need to<br />
be highly modifiable and maintainable.<br />
<br />
Much of a software product's life is spent in ''specification'',<br />
''design'' and ''maintenance'', and not in ''programming''.<br />
Functional languages are superb for writing specifications which can<br />
actually be executed (and hence tested and debugged). Such a<br />
specification then ''is'' the first prototype of the final<br />
program.<br />
<br />
Functional programs are also relatively easy to maintain, because the<br />
code is shorter, clearer, and the rigorous control of side effects<br />
eliminates a huge class of unforeseen interactions.<br />
<br />
==What is functional programming?==<br />
C, Java, Pascal, Ada, and so on, are all ''imperative''<br />
languages. They are &quot;imperative&quot; in the sense that they<br />
consist of a sequence of commands, which are executed strictly one<br />
after the other. Haskell is a ''functional'' language. A<br />
functional program is a single expression, which is executed by<br />
evaluating the expression. <br />
<br />
Anyone who has used a spreadsheet has experience of functional<br />
programming. In a spreadsheet, one specifies the value of each cell<br />
in terms of the values of other cells. The focus is on ''what'' is<br />
to be computed, not ''how'' it should be computed. For<br />
example:<br />
*we do not specify the order in which the cells should be calculated -&nbsp;instead we take it for granted that the spreadsheet will compute cells in an order which respects their dependencies.<br />
*we do not tell the spreadsheet how to allocate its memory - rather, we expect it to present us with an apparently infinite plane of cells, and to allocate memory only to those cells which are actually in use.<br />
*for the most part, we specify the value of a cell by an ''expression'' (whose parts can be evaluated in any order), rather than by a ''sequence of commands '' which computes its value.<br />
<br />
An interesting consequence of the spreadsheet's unspecified order<br />
of re-calculation is that the notion of assignment is not very useful.<br />
After all, if you don't know exactly when an assignment will<br />
happen, you can't make much use of it! This contrasts strongly<br />
with programs in conventional languages like C, which consist<br />
essentially of a carefully-specified sequence of assignments, or Java,<br />
in which the ordering of method calls is crucial to the meaning of a<br />
program. <br />
<br />
This focus on the high-level &quot;what&quot; rather than the<br />
low-level &quot;how&quot; is a distinguishing characteristic of<br />
functional programming languages.<br />
<br />
Another well-known nearly-functional language is the standard database<br />
query language SQL. An SQL query is an expression involving<br />
projections, selections, joins and so forth. The query says what<br />
relation should be computed, without saying how it should be computed.<br />
Indeed, the query can be evaluated in any convenient order. SQL<br />
implementations often perform extensive query optimization which<br />
(among other things) figures out the best order in which to evaluate<br />
the expression.<br />
<br />
==What's good about functional programming?==<br />
<br />
Spreadsheets and SQL are both fairly specialized languages. Functional<br />
programming languages take the same ideas and move them into the realm<br />
of general-purpose programming. To get an idea of what a functional<br />
program is like, and the expressiveness of functional languages, look at<br />
the following quicksort programs. They both sort a sequence of numbers<br />
into ascending order using a standard method called "quicksort". The<br />
first program is written in Haskell and the second in C. <br />
<br />
Whereas the C program describes the particular steps the machine must<br />
make to perform a sort -- with most code dealing with the low-level<br />
details of data manipulation -- the Haskell program encodes the sorting<br />
algorithm at a much higher level, with improved brevity and clarity as<br />
a result.<br />
<br />
===Quicksort in Haskell===<br />
<br />
<haskell><br />
qsort [] = []<br />
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)<br />
</haskell><br />
<br />
===Quicksort in C===<br />
<br />
<pre><br />
void qsort(int a[], int lo, int hi) {<br />
{<br />
int h, l, p, t;<br />
<br />
if (lo &lt; hi) {<br />
l = lo;<br />
h = hi;<br />
p = a[hi];<br />
<br />
do {<br />
while ((l &lt; h) &amp;&amp; (a[l] &lt;= p)) <br />
l = l+1;<br />
while ((h &gt; l) &amp;&amp; (a[h] &gt;= p))<br />
h = h-1;<br />
if (l &lt; h) {<br />
t = a[l];<br />
a[l] = a[h];<br />
a[h] = t;<br />
}<br />
} while (l &lt; h);<br />
<br />
t = a[l];<br />
a[l] = a[hi];<br />
a[hi] = t;<br />
<br />
qsort( a, lo, l-1 );<br />
qsort( a, l+1, hi );<br />
}<br />
}<br />
</pre><br />
<br />
A [[/Direct Translation | semi-direct translation]] of the C is here.<br />
<br />
Let's examine some of the benefits of Haskell and functional programming.<br />
A more detailed case for functional programming can be found in <br />
<br />
<BLOCKQUOTE><br />
[http://www.md.chalmers.se/~rjmh/Papers/whyfp.html '''Why Functional Programming Matters'''] by [http://www.md.chalmers.se/~rjmh/ John Hughes], The Computer<br />
Journal, Vol. 32, No. 2, 1989, pp. 98 - 107. Also in: David A. Turner<br />
(ed.): Research Topics in Functional Programming, Addison-Wesley,<br />
1990, pp. 17 - 42. <br />
</BLOCKQUOTE><br />
A slightly less formal essay inspired by the paper above can be found in<br />
<BLOCKQUOTE><br />
[[Why Haskell matters |'''Why Haskell Matters''']] originally by [mailto:sylvan@dtek.chalmers.se Sebastian Sylvan]<br />
</BLOCKQUOTE><br />
<br />
===Brevity===<br />
Functional programs tend to be much more '''concise''' than their<br />
imperative counterparts. Quicksort is a rather extreme case, but in<br />
general functional programs are much shorter (by a factor of two to ten).<br />
<br />
===Ease of understanding===<br />
Functional programs are often easier to '''understand'''. You should be able to understand the program without any previous knowledge of either Haskell or quicksort. The same certainly cannot be said of the C program. It takes quite a while to understand, and even when you do understand it, it is extremely easy to make a small slip and end up with an incorrect program. Here is a detailed explanation of the Haskell quicksort:<br />
<haskell><br />
qsort [] = []<br />
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)<br />
</haskell><br />
The first line reads:<br />
"When you sort an empty list (<tt>[]</tt>), the result is another empty list". <br />
The second line reads: "To sort a list whose first element is named <tt>x</tt> and<br />
the rest of which is named <tt>xs</tt>, sort the elements of <tt>xs</tt> that are less than <tt>x</tt>, sort the elements of <tt>xs</tt> that are greater than or equal to <tt>x</tt>, and concatenate (<tt>++</tt>) the results, with <tt>x</tt> sandwiched in the middle."<br />
<br />
===No core dumps===<br />
Most functional languages, and Haskell in particular, are '''strongly<br />
typed''', eliminating a huge class of easy-to-make errors at compile<br />
time. In particular, strong typing means '''no core dumps'''!<br />
There is simply no possibility of treating an integer as a pointer, or<br />
following a null pointer.<br />
<br />
===Code re-use===<br />
Of course, strong typing is available in many imperative languages, such as Ada or Pascal. However, Haskell's type system is much less restrictive than, say, Pascal's, because it uses '''[[polymorphism]]'''.<br />
<br />
For example, the qsort program given in Figure 1 will not only sort lists of integers, but also lists of floating point numbers, lists of characters, lists of lists; indeed, it will sort lists of ''anything'' for which it is meaningful to have "less-than" and "greater-than" operations. In contrast, the C version can only sort an array of integers, and nothing else.<br />
<br />
Polymorphism enhances re-usability.<br />
<br />
===Strong glue===<br />
"Non-strict" functional languages, such as Haskell, have another powerful feature: they<br />
only evaluate as much of the program as is required to get the answer<br />
- this is called [[Haskell/Lazy evaluation |'''lazy evaluation''']]. This feature is rather<br />
like Unix pipes. For example, the Unix command<br />
<pre><br />
grep printf Foo.c | wc<br />
</pre><br />
counts the number of lines in the file <tt> Foo.c </tt>that include the<br />
string <tt>printf</tt>.<br />
The command <br />
<pre><br />
grep printf Foo.c<br />
</pre><br />
produces all lines which contain the string &quot;<tt>printf</tt>&quot;,<br />
while the &quot;<tt>wc</tt>&quot; command counts them. The pipe,<br />
written &quot;<tt>|</tt>&quot;, takes the output from the first command<br />
and delivers it to the second. The two commands execute together, so<br />
that the output of the first is consumed more-or-less immediately by<br />
the second. In this way, no large intermediate files need be<br />
produced. You can think of <tt>wc</tt> &quot;demanding&quot;<br />
lines from the <tt>grep</tt>.<br />
<br />
If the second command only needs some of the output of the first, then<br />
execution of the first command might never need to be completed. For<br />
example,<br />
<br />
<pre><br />
grep printf Foo.c | head 5<br />
</pre><br />
just prints the first 5 lines which contain &quot;<tt>printf</tt>&quot;.<br />
There is no need to modify the <tt>grep</tt> command to take account of<br />
the fact that its execution might be abandoned.<br />
<br />
[[Lazy vs. non-strict |Non-strict]] languages provide exactly this kind of demand-driven<br />
evaluation. Data structures are evaluated just enough to deliver the<br />
answer, and parts of them may not be evaluated at all. As in the case<br />
of Unix commands, this provides powerful &quot;glue&quot; with which<br />
to compose existing programs together. What this means is that it is<br />
possible to '''re-use programs''', or pieces of programs, much more<br />
often than can be done in an imperative setting. [[Haskell/Lazy evaluation |Lazy evaluation]] allows us to write more '''[[modular programs]]'''.<br />
<br />
===Powerful abstractions===<br />
In general, functional languages offer powerful new ways to<br />
encapsulate '''abstractions'''. An abstraction allows you to define<br />
an object whose internal workings are hidden; a C procedure, for<br />
example, is an abstraction. Abstractions are ''the'' key to<br />
building modular, maintainable programs, so much so that a good<br />
question to ask of any new language is "what mechanisms for<br />
abstraction does it provide?". <br />
<br />
One powerful abstraction mechanism available in functional languages<br />
is the '''[[higher order function]]'''. In Haskell a function is a<br />
first-class citizen: it can freely be passed to other functions,<br />
returned as the result of a function, stored in a data structure, and<br />
so on. It turns out that the judicious use of higher order functions<br />
can substantially improve the structure and modularity of many<br />
programs.<br />
<br />
===Built-in memory management===<br />
Very many sophisticated programs need to allocate dynamic memory from a heap. In C this is done with a call to <tt> malloc</tt>, followed by code to initialize the store just allocated. The programmer is responsible for returning the store to the free pool when it isn't needed any more, a notorious source of "dangling-pointer" errors. To make matters worse, <tt>malloc</tt> is fairly expensive performance-wise, so programmers often <tt>malloc</tt> a single large chunk of store, and then allocate "by hand" out of this.<br />
<br />
Every functional language relieves the programmer of this storage management burden. Store is allocated and initialized implicitly, and recovered automatically by the garbage collector. The technology of storage allocation and garbage collection is now well developed, and the performance costs are rather slight.<br />
<br />
==When C is better==<br />
It isn't all roses, of course. The C quicksort uses an extremely<br />
ingenious technique, invented by Hoare, whereby it sorts the array<br />
''in place''; that is, without using any extra storage. As a<br />
result, it runs quickly, and in a small amount of memory. In<br />
contrast, the Haskell program allocates quite a lot of extra memory<br />
behind the scenes, and runs rather slower than the C program. <br />
<br />
In effect, the C quicksort does some very ingenious storage<br />
management, trading this algorithmic complexity for a reduction in<br />
run-time storage management costs.<br />
<br />
In applications where [[performance]] is required at any cost, or when the<br />
goal is detailed tuning of a low-level algorithm, an imperative<br />
language like C would probably be a better choice than Haskell,<br />
exactly because it provides more intimate control over the exact way<br />
in which the computation is carried out.<br />
<br />
===Functional vs imperative===<br />
But few programs require performance at any cost! After all, we all<br />
stopped writing assembly-language programs, except perhaps for key<br />
inner loops, long ago. The benefits of having a more supportive<br />
programming model (an arbitrary number of named, local variables<br />
instead of a fixed number of registers, for example) far outweigh the<br />
modest run-time costs.<br />
<br />
Similarly, we willingly accept the costs of a virtual memory paging<br />
system, in exchange for the more supportive programming model of an<br />
infinite virtual address space. The days of explicit memory overlays<br />
are over.<br />
<br />
Functional languages take another large step towards a higher-level<br />
programing model. Programs are easier to design, write and maintain,<br />
but the language offers the programmer less control over the machine.<br />
For most programs the result is perfectly acceptable.<br />
<br />
==What is Haskell?==<br />
Haskell is a modern, standard, non-strict, purely-functional<br />
programming language. It provides all the features sketched above,<br />
including polymorphic typing, lazy evaluation and higher-order<br />
functions. It also has an innovative type system which supports a<br />
systematic form of overloading and a module system.<br />
<br />
It is specifically designed to handle a wide range of applications,<br />
from numerical through to symbolic. To this end, Haskell has an<br />
expressive syntax, and a rich variety of built-in data types,<br />
including arbitrary-precision integers and rationals, as well as the<br />
more conventional integer, floating-point and boolean types.<br />
<br />
There are a number of [[compilers and interpreters]] available. All are<br />
free. First-time users may want to start with [[Hugs]], a small, portable Haskell interpreter. <br />
<br />
See also [[History of Haskell|the History of Haskell]]<br />
<br />
==Does anyone use functional programming?==<br />
Functional programming languages are used in substantial applications.<br />
For example:<br />
* Software AG, a major German software company, market an expert system (Natural Expert) which is programmed in a functional language. Their users find it easy to develop their applications in this language, through which they gain access to an underlying database system. It all runs on an IBM mainframe.<br />
*Ericsson have developed a new functional language, Erlang, to use in their future telephony applications. They have already written 130k-line Erlang applications, and find them very much shorter and faster to develop.<br />
*Amoco ran an experiment in which they re-coded in a functional language a substantial fraction of their main oil-reservoir simulation code, a critical application. The resulting program was vastly shorter, and its production revealed a number of errors in the existing software. Amoco subsequently transcribed the functional program into ... with encouraging results. <!-- Into what? Don't leave us hanging here. --><br />
*A researcher at the MITRE corporation is using Haskell to prototype his digital signal-processing applications.<br />
*Researchers at Durham University used a functional language in a seven-year project to build LOLITA, a 30,000-line program for natural-language understanding.<br />
*Query is the query language of the O2 object-oriented database system. O2Query is probably the most sophisticated commercially-available object-oriented database query language and it is a functional language.<br />
*ICAD Inc market a CAD system for mechanical and aeronautical engineers. The language in which the engineers describe their design is functional, and it uses lazy evaluation extensively to avoid recomputing parts of the design which are not currently visible on the screen. This results in substantial performance improvements.<br />
*An incestuous example: the Glasgow Haskell compiler is written in Haskell: a 100,000-line application.<br />
*[http://pugscode.org Pugs], the leading perl6 implementation is written in Haskell<br />
*As is [http://darcs.net Darcs], a cutting edge distributed revision control system<br />
<br />
Some other examples of [[Haskell in practice]].<br />
<br />
Clifford Beshers, of [http://www.linspire.com/ Linspire Inc]., describes their experience with Haskell, and functional programming:<br />
<br />
<blockquote><br />
Linspire, Inc. has used functional programming since its inception in<br />
2001, beginning with extensive use of O'Caml, with a steady shift to<br />
Haskell as its implementations and libraries have matured. Hardware<br />
detection, software packaging and CGI web page generation are all areas<br />
where we have used functional programming extensively.<br />
</blockquote><br />
<br />
<blockquote><br />
Haskell's feature set lets us replace much of our use of little<br />
languages (e.g., bash or awk) and two-level languages (C or C++ bound to<br />
an interpreted language), allowing for faster development, better code<br />
sharing and ultimately faster implementations. Above all, we value<br />
static type checking for minimizing runtime errors in applications that<br />
run in unknown environments and for wrapping legacy programs in strongly<br />
typed functions to ensure that we pass valid arguments.<br />
</blockquote><br />
<br />
==Other frequently-asked questions==<br />
===''Is functional programming hard to learn?''===<br />
<blockquote><br />
Functional programming does require a change in perspective, which<br />
some programmers find hard. But Ericsson's experience in training<br />
programmers in Erlang is that most find the transition easy -<br />
provided they take the training need seriously rather than assuming<br />
that they can "pick it up on the day".<br />
</blockquote><br />
===''Aren't functional programs very slow?''===<br />
<blockquote>They used to be, perhaps 20 years ago. But the compilers<br />
have long since caught up. Haskell programs run fast for all but the<br />
most performance-demanding applications. At the time of writing, Haskell<br />
compiled via GHC is in 2nd place (behind C) in the <br />
[http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=all Great Language Shootout],<br />
with other functional languages also ranked highly.<br />
</blockquote><br />
<br />
===''I already have a large application in C or C++.''===<br />
Also worded as: ''Can I benefit from functional programming without rewriting my whole system?''<br />
<blockquote><br />
<br />
Haskell has been successfully integrated into existing applications in<br />
a number of ways. <br />
[http://www.haskell.org/hdirect/ HaskellDirect] is<br />
an IDL (Interface Description Language) based tool that allows Haskell<br />
programs to work with software components. Low level C/C++ interfaces<br />
can be generated with<br />
[http://www.haskell.org/greencard Green Card] or <br />
[http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ C->Haskell], allowing <br />
tight integration between Haskell and C. These tools have been used<br />
to build a large number of successful, mixed language systems.<br />
</blockquote><br />
<br />
==='' What libraries does Haskell support?''===<br />
<blockquote><br />
Many software libraries have been developed for Haskell. See the<br />
[[Libraries and tools| list of Haskell libraries]] for a list of much of<br />
what is available.<br />
<br />
</blockquote><br />
<br />
==='' What other software tools for Haskell are there? ''===<br />
<blockquote><br />
Glasgow Haskell comes with a profiler which allows you to find which<br />
parts of your program are consuming most time and space. Chalmers<br />
Haskell has a space-profiling tool, and a quasi-parallel simulator<br />
which allows you to experiment with running your program in<br />
parallel. Hugs also has some similar tools. For a complete list, check<br />
the [[Libraries and tools|tools page]].<br />
</blockquote><br />
<br />
===''Can I get a support contract or a help-line?''===<br />
<blockquote><br />
It used to be the case that if you wanted help, you had to persuade a<br />
Haskell research group that your problem was interesting enough or<br />
important enough that they should spend time helping you for free.<br />
<br><br />
Whilst that is still an option, there is now a<br />
[[Consultants|directory of Haskell Consultants]] who provide:<br />
<br />
*Support for compilers, tools and libraries.<br />
*Help with improving code quality (time, space, robustness, maintainability, etc.) using code reviews and tools.<br />
*Help with using libraries, tools and advanced Haskell features such as type system extensions, exception handling, the foreign function interface, test harnesses, and concurrency.<br />
*Library and application development.<br />
*Staff training.<br />
<br />
These companies and individuals tend to work closely with those<br />
developing Haskell (indeed, they have usually made major<br />
contributions to Haskell themselves). <br />
<br />
</blockquote><br />
===''How can I learn Haskell?''===<br />
<blockquote><br />
For more example and explanations, look at the [http://www.haskell.org/tutorial/ Gentle Introduction to Haskell]. There are a<br />
number of textbooks that use Haskell; see [[Books]].<br />
</blockquote><br />
<br />
===''Comparisons to other languages''===<br />
<blockquote><br />
[[Comparison of functional programming languages | Click to see a table comparing features of Haskell to similar languages]]<br />
</blockquote><br />
<br />
''Based on a paper by Simon Peyton Jones.''</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Introduction/Direct_Translation&diff=11936Introduction/Direct Translation2007-03-13T04:44:16Z<p>Derek Elkins: </p>
<hr />
<div><haskell><br />
import Control.Monad (when)<br />
import Control.Monad.ST<br />
import Data.Array.IO<br />
import Data.Array.ST<br />
import Data.Array.IArray<br />
import Data.Array.MArray<br />
import System.IO.Unsafe<br />
<br />
import Data.IORef <br />
<br />
qsort :: (IArray a e,Ix i,Enum i,Ord e) => a i e -> a i e<br />
qsort arr = processArray quickSort arr<br />
<br />
processArray <br />
:: (IArray a e,IArray b e,Ix i) <br />
=> (forall s. (STArray s) i e -> ST s ()) -> a i e -> b i e<br />
processArray f (arr :: a i e) = runST (do<br />
arr' <- thaw arr :: ST s (STArray s i e)<br />
f arr'<br />
unsafeFreeze arr')<br />
<br />
quickSort :: (MArray a e m, Ix i, Enum i, Ord e) => a i e -> m ()<br />
quickSort arr = case bounds arr of (lo,hi) -> qsort lo hi<br />
where qsort lo hi | lo >= hi = return ()<br />
| otherwise = do<br />
p <- readArray arr hi<br />
l <- mainLoop p lo hi<br />
swap l hi<br />
qsort lo (pred l)<br />
qsort (succ l) hi<br />
<br />
mainLoop p l h | l >= h = return l<br />
| otherwise = do<br />
l' <- doTil (\l' b -> l' < h && b <= p) succ l <br />
h' <- doTil (\h' b -> h' > l' && b >= p) pred h<br />
when (l' < h') $<br />
swap l' h'<br />
mainLoop p l' h'<br />
<br />
doTil pred op ix = do<br />
b <- readArray arr ix<br />
if pred ix b then doTil pred op (op ix) else return ix<br />
<br />
swap xi yi = do<br />
x <- readArray arr xi<br />
readArray arr yi >>= writeArray arr xi<br />
writeArray arr yi x<br />
</haskell><br />
<br />
This uses various extensions to make the types ridiculously general, but the actual algorithm (quickSort) is plain Haskell.</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Introduction_to_QuickCheck1&diff=11534Introduction to QuickCheck12007-02-23T05:26:17Z<p>Derek Elkins: </p>
<hr />
<div>A quick introduction to QuickCheck, and testing Haskell code.<br />
<br />
== Motivation ==<br />
<br />
In September 2006, Bruno Martínez<br />
[http://www.haskell.org/pipermail/haskell-cafe/2006-September/018302.html asked] <br />
the following question:<br />
<br />
<haskell><br />
-- I've written a function that looks similar to this one<br />
<br />
getList = find 5 where<br />
find 0 = return []<br />
find n = do<br />
ch <- getChar<br />
if ch `elem` ['a'..'e'] then do<br />
tl <- find (n-1)<br />
return (ch : tl) else<br />
find n<br />
<br />
-- I want to test this function, without hitting the filesystem. In C++ I<br />
-- would use a istringstream. I couldn't find a function that returns a<br />
-- Handle from a String. The closer thing that may work that I could find<br />
-- was making a pipe and convertind the file descriptor. Can I simplify<br />
-- that function to take it out of the IO monad?<br />
</haskell><br />
<br />
So the problem is: how to effectively test this function in Haskell? The<br />
solution we turn to is refactoring and QuickCheck.<br />
<br />
== Keeping things pure ==<br />
<br />
The reason your getList is hard to test, is that the side effecting monadic code <br />
is mixed in with the pure computation, making it difficult to test<br />
without moving entirely into a "black box" IO-based testing model.<br />
Such a mixture is not good for reasoning about code.<br />
<br />
Let's untangle that, and then test the referentially transparent<br />
parts simply with QuickCheck. We can take advantage of lazy IO firstly,<br />
to avoid all the unpleasant low-level IO handling. <br />
<br />
So the first step is to factor out the IO part of the function into a<br />
thin "skin" layer:<br />
<br />
<haskell><br />
-- A thin monadic skin layer<br />
getList :: IO [Char]<br />
getList = fmap take5 getContents<br />
<br />
-- The actual worker<br />
take5 :: [Char] -> [Char]<br />
take5 = take 5 . filter (`elem` ['a'..'e'])<br />
</haskell><br />
<br />
== Testing with QuickCheck ==<br />
<br />
Now we can test the 'guts' of the algorithm, the take5 function, in<br />
isolation. Let's use QuickCheck. First we need an Arbitrary instance for<br />
the Char type -- this takes care of generating random Chars for us to<br />
test with. I'll restrict it to a range of nice chars just for<br />
simplicity:<br />
<br />
<haskell><br />
import Data.Char<br />
import Test.QuickCheck<br />
<br />
instance Arbitrary Char where<br />
arbitrary = choose ('\32', '\128')<br />
coarbitrary c = variant (ord c `rem` 4)<br />
</haskell><br />
<br />
Let's fire up GHCi (or Hugs) and try some generic properties (its nice<br />
that we can use the QuickCheck testing framework directly from the<br />
Haskell prompt). An easy one first, a [Char] is equal to itself:<br />
<br />
<haskell><br />
*A> quickCheck ((\s -> s == s) :: [Char] -> Bool)<br />
OK, passed 100 tests.<br />
</haskell><br />
<br />
What just happened? QuickCheck generated 100 random [Char] values, and<br />
applied our property, checking the result was True for all cases.<br />
QuickCheck ''generated the test sets for us''!<br />
<br />
A more interesting property now: reversing twice is the identity:<br />
<br />
<haskell><br />
*A> quickCheck ((\s -> (reverse.reverse) s == s) :: [Char] -> Bool)<br />
OK, passed 100 tests.<br />
</haskell><br />
<br />
Great!<br />
<br />
== Testing take5 ==<br />
<br />
The first step to testing with QuickCheck is to work out some properties<br />
that are true of the function, for all inputs. That is, we need to find<br />
''invariants''.<br />
<br />
A simple invariant might be:<br />
<math>\forall~s~.~length~(take5~s)~=~5</math><br />
<br />
So let's write that as a QuickCheck property:<br />
<haskell><br />
\s -> length (take5 s) == 5<br />
</haskell><br />
<br />
Which we can then run in QuickCheck as:<br />
<haskell><br />
*A> quickCheck (\s -> length (take5 s) == 5)<br />
Falsifiable, after 0 tests:<br />
""<br />
</haskell><br />
<br />
Ah! QuickCheck caught us out. If the input string contains less than 5<br />
filterable characters, the resulting string will be less than 5<br />
characters long. So let's weaken the property a bit:<br />
<math>\forall~s~.~length~(take5~s)~\le~5</math><br />
<br />
That is, take5 returns a string of at most 5 characters long. Let's test<br />
this: <br />
<haskell><br />
*A> quickCheck (\s -> length (take5 s) <= 5)<br />
OK, passed 100 tests.<br />
</haskell><br />
<br />
Good!<br />
<br />
== Another property ==<br />
<br />
Another thing to check would be that the correct characters are<br />
returned. That is, for all returned characters, those characters are<br />
members of the set ['a','b','c','d','e'].<br />
<br />
We can specify that as:<br />
<math>\forall~s~.~\forall~e~.~e~\in~take5~s~\to~e~\in~[abcde] </math><br />
<br />
And in QuickCheck:<br />
<haskell><br />
*A> quickCheck (\s -> all (`elem` ['a'..'e']) (take5 s))<br />
OK, passed 100 tests.<br />
</haskell><br />
<br />
Excellent. So we can have some confidence that the function neither<br />
returns strings that are too long, nor includes invalid characters.<br />
<br />
== Coverage ==<br />
<br />
One issue with the default QuickCheck configuration, when testing<br />
[Char], is that the standard 100 tests isn't enough for our situation.<br />
In fact, QuickCheck never generates a String greater than 5 characters<br />
long, when using the supplied Arbtrary instance for Char! We can confirm<br />
this:<br />
<br />
<haskell><br />
*A> quickCheck (\s -> length (take5 s) < 5)<br />
OK, passed 100 tests.<br />
</haskell><br />
<br />
QuickCheck wastes its time generating different Chars, when what we<br />
really need is longer strings. One solution to this is to modify<br />
QuickCheck's default configuration to test deeper:<br />
<br />
<haskell><br />
deepCheck p = check (defaultConfig { configMaxTest = 10000}) p<br />
</haskell><br />
<br />
This instructs the system to find at least 10000 test cases before<br />
concluding that all is well. Let's check that it is generating longer<br />
strings:<br />
<br />
<haskell><br />
*A> deepCheck (\s -> length (take5 s) < 5)<br />
Falsifiable, after 125 tests:<br />
";:iD^*NNi~Y\\RegMob\DEL@krsx/=dcf7kub|EQi\DELD*"<br />
</haskell><br />
<br />
We can check the test data QuickCheck is generating using the<br />
'verboseCheck' hook. Here, testing on integers lists:<br />
<br />
<haskell><br />
*A> verboseCheck (\s -> length s < 5)<br />
0: []<br />
1: [0]<br />
2: []<br />
3: []<br />
4: []<br />
5: [1,2,1,1]<br />
6: [2]<br />
7: [-2,4,-4,0,0]<br />
Falsifiable, after 7 tests:<br />
[-2,4,-4,0,0]<br />
</haskell><br />
<br />
== Going further ==<br />
<br />
QuickCheck is effectively an embedded domain specific language for<br />
testing Haskell code, and allows for much more complex properties than<br />
those you've seen here to be tested. Some sources for further reading<br />
are:<br />
* [http://www.cse.unsw.edu.au/~dons/data/QuickCheck.html The QuickCheck source]<br />
* [http://haskell.org/ghc/docs/latest/html/libraries/QuickCheck/Test-QuickCheck.html Library documentation]<br />
* [http://www.cse.unsw.edu.au/~dons/code/fps/tests/Properties.hs A large testsuite of QuickCheck code]<br />
* Paper [http://www.cs.chalmers.se/~koen/pubs/icfp00-quickcheck.ps QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs], Koen Claessen and John Hughes. In Proc. of International Conference on Functional Programming (ICFP), ACM SIGPLAN, 2000.<br />
* Paper [http://www.math.chalmers.se/~koen/pubs/entry-fop-quickcheck.html Specification Based Testing with QuickCheck], Koen Claessen and John Hughes. In Jeremy Gibbons and Oege de Moor (eds.), The Fun of Programming, Cornerstones of Computing, pp. 17--40, Palgrave, 2003.<br />
* Paper [http://www.math.chalmers.se/~koen/pubs/entry-tt04-quickcheck.html QuickCheck: Specification-based Random Testing], Koen Claessen. Presentation at Summer Institute on Trends in Testing: Theory, Techniques and Tools, August 2004.<br />
* Paper [http://www.cs.chalmers.se/~rjmh/Papers/QuickCheckST.ps Testing Monadic Programs with QuickCheck], Koen Claessen, John Hughes. SIGPLAN Notices 37(12): 47-59 (2002):<br />
* More [http://haskell.org/haskellwiki/Research_papers/Testing_and_correctness research on correctness and testing] in Haskell<br />
* Tutorial: [[QuickCheck as a test set generator]]<br />
* Tutorial: [[QuickCheck / GADT]]<br />
<br />
Note, QuickCheck doesn't need to just be an embedded domain specific language for testing ''Haskell'' code. By making instances of Arbitrary for FFI types you can use Haskell and QuickCheck to check code in other languages.<br />
<br />
[[Category:Tutorials]]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=HaWiki_migration&diff=8982HaWiki migration2006-12-08T23:30:15Z<p>Derek Elkins: </p>
<hr />
<div>Remember you need to '''check licences''' before moving content to the new wiki!<br />
Pages to be migrated to the new wiki. Once a page has been moved '''delete it from this list'''.<br />
<br />
When porting new pages, please try to categorise them. This will ease<br />
navigating the wiki in the long term. A list of all categories<br />
[[Special:Categories|is here]]. To categorise a page, insert, for example,<br />
the text:<br />
<haskell><br />
[[Category:Tutorials]]<br />
</haskell><br />
<br />
__TOC__<br />
<br />
== Licenses ==<br />
<br />
If you are happy for your contributions on the old wiki to be relicensed<br />
and moved to the new wiki, please add your name to this list, so that<br />
others may move your contributions without fear:<br />
<br />
* Adrian Hey<br />
* Andrew Bromage<br />
* Bulat Ziganshin<br />
* Cale Gibbard<br />
* Dave Menendez<br />
* David Himmelstrup (Lemmih)<br />
* Derek Elkins<br />
* Don Stewart<br />
* Einar Karttunen<br />
* Henk-Jan van Tuyl<br />
* Henning Thielemann<br />
* Ian Lynagh<br />
* Jason Dagit<br />
* Johannes Ahlmann<br />
* Matthias Fischmann<br />
* Neil Mitchell<br />
* Oleg Kiselyov<br />
* Scott Turner<br />
* Shae Erisson<br />
* Stefan Aeschbacher<br />
* Simon Marlow<br />
* [http://www.haskell.org/hawiki/UdoStenzel Udo Stenzel]<br />
<br />
Add yourself in `sort' order.<br />
<br />
== Uncategorised pages ==<br />
<br />
Please mark pages which you consider ''not'' to be moved with a *.<br />
<br />
===A to E ===<br />
<br />
[http://www.haskell.org/hawiki/ActorModel ActorModel]<br />
<br />
[http://www.haskell.org/hawiki/AdHocPolymorphism AdHocPolymorphism]<br />
<br />
[http://www.haskell.org/hawiki/AddingStrictness AddingStrictness]<br />
<br />
[http://www.haskell.org/hawiki/AlgorithmCorner AlgorithmCorner]<br />
<br />
[http://www.haskell.org/hawiki/AntiBuddha AntiBuddha]<br />
<br />
[http://www.haskell.org/hawiki/ArraysInHaskell ArraysInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/ArraysVsTuples ArraysVsTuples]<br />
<br />
[http://www.haskell.org/hawiki/ArrowRun ArrowRun]<br />
<br />
[http://www.haskell.org/hawiki/AvoidingParameterPassing AvoidingParameterPassing]<br />
<br />
[http://www.haskell.org/hawiki/BFInterpreter BFInterpreter]<br />
<br />
[http://www.haskell.org/hawiki/BaseCasesAndIdentities BaseCasesAndIdentities]<br />
<br />
[http://www.haskell.org/hawiki/BeginnerChronicle BeginnerChronicle]<br />
<br />
[http://www.haskell.org/hawiki/C++FromHaskell C++FromHaskell]<br />
<br />
[http://www.haskell.org/hawiki/C2hs C2hs]<br />
<br />
[http://www.haskell.org/hawiki/CatInHaskell CatInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/CategoryTheory/NaturalTransformation CategoryTheory/NaturalTransformation]<br />
<br />
[http://www.haskell.org/hawiki/CategoryTheory/Functor CategoryTheory/Functor]<br />
<br />
[http://www.haskell.org/hawiki/ChainOfResponsibility ChainOfResponsibility]<br />
<br />
[http://www.haskell.org/hawiki/CircularProgramming CircularProgramming]<br />
<br />
[http://www.haskell.org/hawiki/CoMonad CoMonad]<br />
<br />
[http://www.haskell.org/hawiki/CoMonadArticles CoMonadArticles]<br />
<br />
[http://www.haskell.org/hawiki/CodeExamples CodeExamples] (Polynomial example moved)<br />
<br />
[http://www.haskell.org/hawiki/CodeOnTheWiki CodeOnTheWiki]<br />
<br />
[http://www.haskell.org/hawiki/CodeSnippets CodeSnippets]<br />
<br />
[http://www.haskell.org/hawiki/CombinatorPattern CombinatorPattern]<br />
<br />
[http://www.haskell.org/hawiki/CommonHaskellIdioms CommonHaskellIdioms]<br />
<br />
[http://www.haskell.org/hawiki/CommunityIssues CommunityIssues]<br />
<br />
[http://www.haskell.org/hawiki/ConcreteTypeInstantiation ConcreteTypeInstantiation]<br />
<br />
[http://www.haskell.org/hawiki/ConcreteView ConcreteView]<br />
<br />
[http://www.haskell.org/hawiki/ConcurrencyWithOracles ConcurrencyWithOracles]<br />
<br />
[http://www.haskell.org/hawiki/ConcurrentTutorial ConcurrentTutorial]<br />
<br />
[http://www.haskell.org/hawiki/ContinuationPassingStyle ContinuationPassingStyle]<br />
<br />
[http://www.haskell.org/hawiki/ContinuationsDoneRight ContinuationsDoneRight]<br />
<br />
[http://www.haskell.org/hawiki/ControlOperation ControlOperation]<br />
<br />
[http://www.haskell.org/hawiki/ConundrumBinaryOperationsOnInts ConundrumBinaryOperationsOnInts]<br />
<br />
[http://www.haskell.org/hawiki/CpsInCee CpsInCee]<br />
<br />
[http://www.haskell.org/hawiki/CpsInJava CpsInJava]<br />
<br />
[http://www.haskell.org/hawiki/CpsTransform CpsTransform]<br />
<br />
[http://www.haskell.org/hawiki/CreditCardTransform CreditCardTransform]<br />
<br />
[http://www.haskell.org/hawiki/DataStructureFreeTransformation DataStructureFreeTransformation]<br />
<br />
[http://www.haskell.org/hawiki/DataStructuresNotFunctions DataStructuresNotFunctions]<br />
<br />
[http://www.haskell.org/hawiki/DeFunctionalization DeFunctionalization]<br />
<br />
[http://www.haskell.org/hawiki/DebianUsers DebianUsers]<br />
<br />
[http://www.haskell.org/hawiki/DecoratingStructures DecoratingStructures]<br />
<br />
[http://www.haskell.org/hawiki/DerivingFromSpecifications DerivingFromSpecifications]<br />
<br />
[http://www.haskell.org/hawiki/DerivingInstancesFromTypes DerivingInstancesFromTypes]<br />
<br />
[http://www.haskell.org/hawiki/DesignPatternsForFunctionalStrategicProgramming DesignPatternsForFunctionalStrategicProgramming]<br />
<br />
[http://www.haskell.org/hawiki/DomainSpecificLanguages DomainSpecificLanguages]<br />
<br />
[http://www.haskell.org/hawiki/DynamicErrors DynamicErrors]<br />
<br />
[http://www.haskell.org/hawiki/DynamicTypes DynamicTypes]<br />
<br />
[http://www.haskell.org/hawiki/EasyUnification EasyUnification]<br />
<br />
[http://www.haskell.org/hawiki/ErLang ErLang]<br />
<br />
[http://www.haskell.org/hawiki/ErrorMonad ErrorMonad]<br />
<br />
[http://www.haskell.org/hawiki/EuroHaskell EuroHaskell]<br />
<br />
[http://www.haskell.org/hawiki/EventStats EventStats]<br />
<br />
[http://www.haskell.org/hawiki/EventStats/HitCounts EventStats/HitCounts]<br />
<br />
[http://www.haskell.org/hawiki/EventStats/UserAgents EventStats/UserAgents]<br />
<br />
[http://www.haskell.org/hawiki/ExceptionMonad ExceptionMonad]<br />
<br />
[http://www.haskell.org/hawiki/ExistentialType ExistentialType]<br />
<br />
[http://www.haskell.org/hawiki/ExistentialTypes ExistentialTypes]<br />
<br />
[http://www.haskell.org/hawiki/Existentially_20quantified_20record_20constructors Existentially quantified record constructors]<br />
<br />
[http://www.haskell.org/hawiki/ExperimentalFeatures ExperimentalFeatures]<br />
<br />
[http://www.haskell.org/hawiki/ExternalCommands ExternalCommands]<br />
<br />
=== F to J ===<br />
[http://www.haskell.org/hawiki/FasterFloatingPointWithGhc FasterFloatingPointWithGhc]<br />
<br />
[http://www.haskell.org/hawiki/FeatherweightPerl6 FeatherweightPerl6]<br />
<br />
[http://www.haskell.org/hawiki/FedoraHaskell FedoraHaskell]<br />
<br />
[http://www.haskell.org/hawiki/FedoraRepository FedoraRepository]<br />
<br />
[http://www.haskell.org/hawiki/FfiCookbook FfiCookbook]<br />
<br />
[http://www.haskell.org/hawiki/FfiExample FfiExample]<br />
<br />
[http://www.haskell.org/hawiki/FfiTutorial FfiTutorial]<br />
<br />
[http://www.haskell.org/hawiki/FfiWithArrays FfiWithArrays]<br />
<br />
[http://www.haskell.org/hawiki/FindPage FindPage]<br />
<br />
[http://www.haskell.org/hawiki/FirstClassModules FirstClassModules]<br />
<br />
[http://www.haskell.org/hawiki/FirstSteps FirstSteps]<br />
<br />
[http://www.haskell.org/hawiki/FixedPointCombinator FixedPointCombinator]<br />
<br />
[http://www.haskell.org/hawiki/ForcingEagerEvaluation ForcingEagerEvaluation]<br />
<br />
[http://www.haskell.org/hawiki/ForeignFunctionInterface ForeignFunctionInterface]<br />
<br />
[http://www.haskell.org/hawiki/FptoolsWithDarcs FptoolsWithDarcs]<br />
<br />
[http://www.haskell.org/hawiki/FreeNode FreeNode]<br />
<br />
[http://www.haskell.org/hawiki/FrequentlyAskedQuestions FrequentlyAskedQuestions]<br />
<br />
[http://www.haskell.org/hawiki/FrontPage FrontPage]<br />
<br />
[http://www.haskell.org/hawiki/FunctionalDispatch FunctionalDispatch]<br />
<br />
[http://www.haskell.org/hawiki/FunctionsNotDataStructures FunctionsNotDataStructures]<br />
<br />
[http://www.haskell.org/hawiki/FundamentalConcepts FundamentalConcepts]<br />
<br />
[http://www.haskell.org/hawiki/FutureOfHaskellDiscussionDiscussion FutureOfHaskellDiscussionDiscussion]<br />
<br />
[http://www.haskell.org/hawiki/GADT_20with_20record_20syntax GADT with record syntax]<br />
<br />
[http://www.haskell.org/hawiki/GHCPackageDesignFAQ GHCPackageDesignFAQ]<br />
<br />
[http://www.haskell.org/hawiki/GaleHaskeller GaleHaskeller]<br />
<br />
[http://www.haskell.org/hawiki/GeneralisingTypes GeneralisingTypes]<br />
<br />
[http://www.haskell.org/hawiki/GenericHaskellServer GenericHaskellServer]<br />
<br />
[http://www.haskell.org/hawiki/GennethsCrazyDatabaseConnector GennethsCrazyDatabaseConnector]<br />
<br />
[http://www.haskell.org/hawiki/GentleHaskellDiscuss GentleHaskellDiscuss]<br />
<br />
[http://www.haskell.org/hawiki/GesuchteSeiten GesuchteSeiten]<br />
<br />
[http://www.haskell.org/hawiki/GhcConcurrency GhcConcurrency]<br />
<br />
[http://www.haskell.org/hawiki/GlobalMutableState GlobalMutableState]<br />
<br />
[http://www.haskell.org/hawiki/GoodLargeTeachingProgram GoodLargeTeachingProgram]<br />
<br />
[http://www.haskell.org/hawiki/GreenCard GreenCard]<br />
<br />
[http://www.haskell.org/hawiki/GrepInHaskell GrepInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/Gtk2Hs Gtk2Hs]<br />
<br />
[http://www.haskell.org/hawiki/GtkHs GtkHs]<br />
<br />
[http://www.haskell.org/hawiki/GunnarKedenburg GunnarKedenburg]<br />
<br />
[http://www.haskell.org/hawiki/HaCanon HaCanon]<br />
<br />
[http://www.haskell.org/hawiki/HaWiki HaWiki]<br />
<br />
[http://www.haskell.org/hawiki/HaWikiUsers HaWikiUsers]<br />
<br />
[http://www.haskell.org/hawiki/Hacanon Hacanon]<br />
<br />
[http://www.haskell.org/hawiki/Hackage Hackage]<br />
<br />
[http://www.haskell.org/hawiki/Hackage/TODO Hackage/TODO]<br />
<br />
[http://www.haskell.org/hawiki/HackageDB HackageDB]<br />
<br />
[http://www.haskell.org/hawiki/HashConsing HashConsing]<br />
<br />
[http://www.haskell.org/hawiki/Haskell Haskell]<br />
<br />
[http://www.haskell.org/hawiki/HaskellBookstore HaskellBookstore]<br />
<br />
[http://www.haskell.org/hawiki/HaskellBookstore/TalkAbout HaskellBookstore/TalkAbout]<br />
<br />
[http://www.haskell.org/hawiki/HaskellChannelPeople HaskellChannelPeople]<br />
<br />
[http://www.haskell.org/hawiki/HaskellCheatSheet HaskellCheatSheet]<br />
<br />
[http://www.haskell.org/hawiki/HaskellCommunities HaskellCommunities]<br />
<br />
[http://www.haskell.org/hawiki/HaskellDbTutorial HaskellDbTutorial]<br />
<br />
[http://www.haskell.org/hawiki/HaskellDbandHsp HaskellDbandHsp]<br />
<br />
[http://www.haskell.org/hawiki/HaskellDemo HaskellDemo]<br />
<br />
[http://www.haskell.org/hawiki/HaskellEditor HaskellEditor]<br />
<br />
[http://www.haskell.org/hawiki/HaskellForCompilers HaskellForCompilers]<br />
<br />
[http://www.haskell.org/hawiki/HaskellGoPeople HaskellGoPeople]<br />
<br />
[http://www.haskell.org/hawiki/HaskellIde HaskellIde]<br />
<br />
[http://www.haskell.org/hawiki/HaskellImplementations HaskellImplementations]<br />
<br />
[http://www.haskell.org/hawiki/HaskellInaNutshell HaskellInaNutshell]<br />
<br />
[http://www.haskell.org/hawiki/HaskellIrcChannel HaskellIrcChannel]<br />
<br />
[http://www.haskell.org/hawiki/HaskellIrcPastePage HaskellIrcPastePage]<br />
<br />
[http://www.haskell.org/hawiki/HaskellIrcQuotePage HaskellIrcQuotePage]<br />
<br />
[http://www.haskell.org/hawiki/HaskellLanguage HaskellLanguage]<br />
<br />
[http://www.haskell.org/hawiki/HaskellMailClient HaskellMailClient]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie HaskellNewbie]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/AppendingToLists HaskellNewbie/AppendingToLists]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/BooleanTests HaskellNewbie/BooleanTests]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/CombiningMonads HaskellNewbie/CombiningMonads]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/DivisionOfIntegers HaskellNewbie/DivisionOfIntegers]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/DuplicateInstanceDeclaration HaskellNewbie/DuplicateInstanceDeclaration]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ExternalPrograms HaskellNewbie/ExternalPrograms]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/FactorialsComingOutZero HaskellNewbie/FactorialsComingOutZero]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/FileOperations HaskellNewbie/FileOperations]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/FunctionsAndEquality HaskellNewbie/FunctionsAndEquality]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/HaskellAsAMacroLanguage HaskellNewbie/HaskellAsAMacroLanguage]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/HaskellFromJava HaskellNewbie/HaskellFromJava]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/HaskellInterpreterUsage HaskellNewbie/HaskellInterpreterUsage]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ImplementingUnzipWithFoldr HaskellNewbie/ImplementingUnzipWithFoldr]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/InfiniteCartesianProduct HaskellNewbie/InfiniteCartesianProduct]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/LazyVsStrictEvaluation HaskellNewbie/LazyVsStrictEvaluation]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/LetAndWhere HaskellNewbie/LetAndWhere]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ListComprehensions HaskellNewbie/ListComprehensions]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/LowerCase HaskellNewbie/LowerCase]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ModuleSystemImplementation HaskellNewbie/ModuleSystemImplementation]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/MonadicIO HaskellNewbie/MonadicIO]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/NamespaceClashes HaskellNewbie/NamespaceClashes]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/NumericTypes HaskellNewbie/NumericTypes]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ObjectOrientedVsFunctionalProgramming HaskellNewbie/ObjectOrientedVsFunctionalProgramming]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/PrettyPrintingRecords HaskellNewbie/PrettyPrintingRecords]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/PrintingFloatingPointValues HaskellNewbie/PrintingFloatingPointValues]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/ReadsAndShowsPrec HaskellNewbie/ReadsAndShowsPrec]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/StringParsing HaskellNewbie/StringParsing]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/TcpIpAndNetworking HaskellNewbie/TcpIpAndNetworking]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/TestingWithGetArgs HaskellNewbie/TestingWithGetArgs]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/TracingEvaluation HaskellNewbie/TracingEvaluation]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/TypeSignatureBasicQuestion HaskellNewbie/TypeSignatureBasicQuestion]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/UntypedSKCalculus HaskellNewbie/UntypedSKCalculus]<br />
<br />
[http://www.haskell.org/hawiki/HaskellNewbie/WorkingWithRandomNumbers HaskellNewbie/WorkingWithRandomNumbers]<br />
<br />
[http://www.haskell.org/hawiki/HaskellOhSix HaskellOhSix]<br />
<br />
[http://www.haskell.org/hawiki/HaskellOnMac HaskellOnMac]<br />
<br />
[http://www.haskell.org/hawiki/HaskellOpenGl HaskellOpenGl]<br />
<br />
[http://www.haskell.org/hawiki/HaskellProverbs HaskellProverbs]<br />
<br />
[http://www.haskell.org/hawiki/HaskellServerPages HaskellServerPages]<br />
<br />
[http://www.haskell.org/hawiki/HaskellServerProgramming HaskellServerProgramming]<br />
<br />
[http://www.haskell.org/hawiki/HaskellStreamIO HaskellStreamIO]<br />
<br />
[http://www.haskell.org/hawiki/HaskellStyle HaskellStyle]<br />
<br />
[http://www.haskell.org/hawiki/HaskellSupportFramework HaskellSupportFramework]<br />
<br />
[http://www.haskell.org/hawiki/HaskellToJavaByteCodeCompiler HaskellToJavaByteCodeCompiler]<br />
<br />
[http://www.haskell.org/hawiki/HaskellTutorials HaskellTutorials]<br />
<br />
[http://www.haskell.org/hawiki/HaskellTwo HaskellTwo]<br />
<br />
[http://www.haskell.org/hawiki/HaskellUnixDaemon HaskellUnixDaemon]<br />
<br />
[http://www.haskell.org/hawiki/HaskellUserLocations HaskellUserLocations]<br />
<br />
[http://www.haskell.org/hawiki/HaskellWebApplicationServer HaskellWebApplicationServer]<br />
<br />
[http://www.haskell.org/hawiki/HaskellWebApplications HaskellWebApplications]<br />
<br />
[http://www.haskell.org/hawiki/HaskellWikiInHaskell HaskellWikiInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/HaskellWishList HaskellWishList]<br />
<br />
[http://www.haskell.org/hawiki/HaskellWorldDomination HaskellWorldDomination]<br />
<br />
[http://www.haskell.org/hawiki/HelloWorld HelloWorld]<br />
<br />
[http://www.haskell.org/hawiki/HelpContents HelpContents]<br />
<br />
[http://www.haskell.org/hawiki/HelpForBeginners HelpForBeginners]<br />
<br />
[http://www.haskell.org/hawiki/HelpForDevelopers HelpForDevelopers]<br />
<br />
[http://www.haskell.org/hawiki/HelpIndex HelpIndex]<br />
<br />
[http://www.haskell.org/hawiki/HelpMiscellaneous/FrequentlyAskedQuestions HelpMiscellaneous/FrequentlyAskedQuestions]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnAdministration HelpOnAdministration]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnConfiguration HelpOnConfiguration]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnConfiguration/EmailSupport HelpOnConfiguration/EmailSupport]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnConfiguration/SecurityPolicy HelpOnConfiguration/SecurityPolicy]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnEditing/SubPages HelpOnEditing/SubPages]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnFormatting HelpOnFormatting]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnHeadlines HelpOnHeadlines]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnLinking HelpOnLinking]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnLists HelpOnLists]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnMacros HelpOnMacros]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnNavigation HelpOnNavigation]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnPageCreation HelpOnPageCreation]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnPageDeletion HelpOnPageDeletion]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnProcessingInstructions HelpOnProcessingInstructions]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnProcessors HelpOnProcessors]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnRules HelpOnRules]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnSkins HelpOnSkins]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnSmileys HelpOnSmileys]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnSpellCheck HelpOnSpellCheck]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnTables HelpOnTables]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnUpdating HelpOnUpdating]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnUserPreferences HelpOnUserPreferences]<br />
<br />
[http://www.haskell.org/hawiki/HelpOnXmlPages HelpOnXmlPages]<br />
<br />
[http://www.haskell.org/hawiki/HelpTemplate HelpTemplate]<br />
<br />
[http://www.haskell.org/hawiki/hIDE hIDE]<br />
<br />
[http://www.haskell.org/hawiki/hIDE/Design hIDE/Design]<br />
<br />
[http://www.haskell.org/hawiki/hIDE/Win32 hIDE/Win32]<br />
<br />
[http://www.haskell.org/hawiki/HigherOrderFunction HigherOrderFunction]<br />
<br />
[http://www.haskell.org/hawiki/HigherOrderFunctions HigherOrderFunctions]<br />
<br />
[http://www.haskell.org/hawiki/HigherOrderFunctionsToCapture HigherOrderFunctionsToCapture]<br />
<br />
[http://www.haskell.org/hawiki/HirculesIrcClient HirculesIrcClient]<br />
<br />
[http://www.haskell.org/hawiki/HomepageTemplate HomepageTemplate]<br />
<br />
[http://www.haskell.org/hawiki/HomeworkHelp HomeworkHelp]<br />
<br />
[http://www.haskell.org/hawiki/HowToReadHaskell HowToReadHaskell]<br />
<br />
[http://www.haskell.org/hawiki/HsWebForms HsWebForms]<br />
<br />
[http://www.haskell.org/hawiki/Hsc2hs Hsc2hs]<br />
<br />
[http://www.haskell.org/hawiki/IcfpContest IcfpContest]<br />
<br />
[http://www.haskell.org/hawiki/IdentityMonad IdentityMonad]<br />
<br />
[http://www.haskell.org/hawiki/ImperativeHaskell ImperativeHaskell]<br />
<br />
[http://www.haskell.org/hawiki/ImplicitParameters ImplicitParameters]<br />
<br />
[http://www.haskell.org/hawiki/ImplicitReader ImplicitReader]<br />
<br />
[http://www.haskell.org/hawiki/IncreasingSharing IncreasingSharing]<br />
<br />
[http://www.haskell.org/hawiki/IndeterminismAndNondeterminism IndeterminismAndNondeterminism]<br />
<br />
[http://www.haskell.org/hawiki/IndirectComposite IndirectComposite]<br />
<br />
[http://www.haskell.org/hawiki/InfixExpression InfixExpression]<br />
<br />
[http://www.haskell.org/hawiki/InformationHiding InformationHiding]<br />
<br />
[http://www.haskell.org/hawiki/InstallationLogs InstallationLogs]<br />
<br />
[http://www.haskell.org/hawiki/InstallationTips InstallationTips]<br />
<br />
[http://www.haskell.org/hawiki/IntegralApproximation IntegralApproximation]<br />
<br />
[http://www.haskell.org/hawiki/IntegratingHaskellWikiInHaskellOrg IntegratingHaskellWikiInHaskellOrg]<br />
<br />
[http://www.haskell.org/hawiki/InterProcess InterProcess]<br />
<br />
[http://www.haskell.org/hawiki/InterWiki InterWiki]<br />
<br />
[http://www.haskell.org/hawiki/InteractiveFictionDecompilers InteractiveFictionDecompilers]<br />
<br />
[http://www.haskell.org/hawiki/IntermediateForm IntermediateForm]<br />
<br />
[http://www.haskell.org/hawiki/IntermediateRepresentation IntermediateRepresentation]<br />
<br />
[http://www.haskell.org/hawiki/IntroductionToIO IntroductionToIO]<br />
<br />
[http://www.haskell.org/hawiki/IterationPattern IterationPattern]<br />
<br />
[http://www.haskell.org/hawiki/Jhc Jhc]<br />
<br />
[http://www.haskell.org/hawiki/JournalOfFunctionalProgramming JournalOfFunctionalProgramming]<br />
<br />
=== K to O ===<br />
[http://www.haskell.org/hawiki/Keywords Keywords]<br />
<br />
[http://www.haskell.org/hawiki/KnuthMorrisPratt KnuthMorrisPratt]<br />
<br />
[http://www.haskell.org/hawiki/LambdaDropping LambdaDropping]<br />
<br />
[http://www.haskell.org/hawiki/LearningHaskell LearningHaskell]<br />
<br />
[http://www.haskell.org/hawiki/LessFrequentlyAskedQuestions LessFrequentlyAskedQuestions]<br />
<br />
[http://www.haskell.org/hawiki/LetFloating LetFloating]<br />
<br />
[http://www.haskell.org/hawiki/LibrariesAndTools LibrariesAndTools]<br />
<br />
[http://www.haskell.org/hawiki/LibrariesExts LibrariesExts]<br />
<br />
[http://www.haskell.org/hawiki/LibrariesExts/QuickCheckExts LibrariesExts/QuickCheckExts]<br />
<br />
[http://www.haskell.org/hawiki/LibrariesTest LibrariesTest]<br />
<br />
[http://www.haskell.org/hawiki/LibraryDocsNeedingHelp LibraryDocsNeedingHelp]<br />
<br />
[http://www.haskell.org/hawiki/LibraryDocumentation LibraryDocumentation]<br />
<br />
[http://www.haskell.org/hawiki/LibraryDocumentation/CPUTime LibraryDocumentation/CPUTime]<br />
<br />
[http://www.haskell.org/hawiki/LibraryDocumentation/Ix LibraryDocumentation/Ix]<br />
<br />
[http://www.haskell.org/hawiki/LibraryDocumentation/Prelude LibraryDocumentation/Prelude]<br />
<br />
[http://www.haskell.org/hawiki/LibraryInfrastructure LibraryInfrastructure]<br />
<br />
[http://www.haskell.org/hawiki/LibraryInfrastructure/Comments LibraryInfrastructure/Comments]<br />
<br />
[http://www.haskell.org/hawiki/LibraryInfrastructure/MetaData LibraryInfrastructure/MetaData]<br />
<br />
[http://www.haskell.org/hawiki/LibraryInfrastructure/RelatedSystems LibraryInfrastructure/RelatedSystems]<br />
<br />
[http://www.haskell.org/hawiki/LibraryInfrastructureNotes LibraryInfrastructureNotes]<br />
<br />
[http://www.haskell.org/hawiki/LicensedPreludeExts LicensedPreludeExts]<br />
<br />
[http://www.haskell.org/hawiki/Lifting Lifting]<br />
<br />
[http://www.haskell.org/hawiki/ListMutation ListMutation]<br />
<br />
[http://www.haskell.org/hawiki/ListTDoneRight ListTDoneRight]<br />
<br />
[http://www.haskell.org/hawiki/ListTDoneRight/Alternative1 ListTDoneRight/Alternative1]<br />
<br />
[http://www.haskell.org/hawiki/Mandelbrot Mandelbrot]<br />
<br />
[http://www.haskell.org/hawiki/MaybeMonad MaybeMonad]<br />
<br />
[http://www.haskell.org/hawiki/MegaMonad MegaMonad]<br />
<br />
[http://www.haskell.org/hawiki/MegaMonad/PassingTuringTest MegaMonad/PassingTuringTest]<br />
<br />
[http://www.haskell.org/hawiki/MemoisingCafs MemoisingCafs]<br />
<br />
[http://www.haskell.org/hawiki/MemoizingRecursion MemoizingRecursion]<br />
<br />
[http://www.haskell.org/hawiki/MessageDispatching MessageDispatching]<br />
<br />
[http://www.haskell.org/hawiki/ModelizingInHaskell ModelizingInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/Monad Monad]<br />
<br />
[http://www.haskell.org/hawiki/MonadCont MonadCont]<br />
<br />
[http://www.haskell.org/hawiki/MonadError MonadError]<br />
<br />
[http://www.haskell.org/hawiki/MonadIdentity MonadIdentity]<br />
<br />
[http://www.haskell.org/hawiki/MonadPlus MonadPlus]<br />
<br />
[http://www.haskell.org/hawiki/MonadReader MonadReader]<br />
<br />
[http://www.haskell.org/hawiki/MonadRun MonadRun]<br />
<br />
[http://www.haskell.org/hawiki/MonadState MonadState]<br />
<br />
[http://www.haskell.org/hawiki/MonadStream MonadStream]<br />
<br />
[http://www.haskell.org/hawiki/MonadTemplateLibrary MonadTemplateLibrary]<br />
<br />
[http://www.haskell.org/hawiki/MonadTemplateLibrary/MonadRandom MonadTemplateLibrary/MonadRandom]<br />
<br />
[http://www.haskell.org/hawiki/MonadTransformer MonadTransformer]<br />
<br />
[http://www.haskell.org/hawiki/MonadTransformerPuzzle MonadTransformerPuzzle]<br />
<br />
[http://www.haskell.org/hawiki/MonadTransformers MonadTransformers]<br />
<br />
[http://www.haskell.org/hawiki/MonadUnTrans MonadUnTrans]<br />
<br />
[http://www.haskell.org/hawiki/MonadWriter MonadWriter]<br />
<br />
[http://www.haskell.org/hawiki/MonadicContinuationPassingStyle MonadicContinuationPassingStyle]<br />
<br />
[http://www.haskell.org/hawiki/MonadicStyleTransformation MonadicStyleTransformation]<br />
<br />
[http://www.haskell.org/hawiki/MonomorphismRestriction MonomorphismRestriction]<br />
<br />
[http://www.haskell.org/hawiki/NewsAndDiscussions NewsAndDiscussions]<br />
<br />
[http://www.haskell.org/hawiki/NewtypeVersusStrictData NewtypeVersusStrictData]<br />
<br />
[http://www.haskell.org/hawiki/NickMain NickMain]<br />
<br />
[http://www.haskell.org/hawiki/NoPatternGuards NoPatternGuards]<br />
<br />
[http://www.haskell.org/hawiki/NonDeterminism NonDeterminism]<br />
<br />
[http://www.haskell.org/hawiki/NonstrictFromStrict NonstrictFromStrict]<br />
<br />
[http://www.haskell.org/hawiki/NotJustMaybe NotJustMaybe]<br />
<br />
[http://www.haskell.org/hawiki/NullObject NullObject]<br />
<br />
[http://www.haskell.org/hawiki/ObjectIoLibrary ObjectIoLibrary]<br />
<br />
[http://www.haskell.org/hawiki/OpenQuestions OpenQuestions]<br />
<br />
=== P to T ===<br />
[http://www.haskell.org/hawiki/PacketClass PacketClass]<br />
<br />
[http://www.haskell.org/hawiki/ParsingForeignLanguagesInHaskell ParsingForeignLanguagesInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/ParsingInHaskell ParsingInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/PartialApplication PartialApplication]<br />
<br />
[http://www.haskell.org/hawiki/PartialEvaluation PartialEvaluation]<br />
<br />
[http://www.haskell.org/hawiki/PartialEvaluationToCaptureSeparationOfConcerns PartialEvaluationToCaptureSeparationOfConcerns]<br />
<br />
[http://www.haskell.org/hawiki/PatternMatching PatternMatching]<br />
<br />
[http://www.haskell.org/hawiki/PaulGrahamAccumulatorProblem PaulGrahamAccumulatorProblem]<br />
<br />
[http://www.haskell.org/hawiki/Perl6UsersGolfingSystem Perl6UsersGolfingSystem]<br />
<br />
[http://www.haskell.org/hawiki/PerlUsersGolfingSystem PerlUsersGolfingSystem]<br />
<br />
[http://www.haskell.org/hawiki/PermutationExample PermutationExample]<br />
<br />
[http://www.haskell.org/hawiki/PhoneNumber PhoneNumber] (Lots of code by Paulohnson - need license check)<br />
<br />
[http://www.haskell.org/hawiki/PipeliningFunctions PipeliningFunctions]<br />
<br />
[http://www.haskell.org/hawiki/PracticalHaskell PracticalHaskell]<br />
<br />
[http://www.haskell.org/hawiki/PreludeExts PreludeExts]<br />
<br />
[http://www.haskell.org/hawiki/PreludeExtsUseExamples PreludeExtsUseExamples]<br />
<br />
[http://www.haskell.org/hawiki/PreludeListFunctions PreludeListFunctions]<br />
<br />
[http://www.haskell.org/hawiki/Profiling Profiling]<br />
<br />
[http://www.haskell.org/hawiki/ProjectIdeas ProjectIdeas]<br />
<br />
[http://www.haskell.org/hawiki/Proposed_20extensions Proposed extensions]<br />
<br />
[http://www.haskell.org/hawiki/PurityAndMonads PurityAndMonads]<br />
<br />
[http://www.haskell.org/hawiki/Python4Suite Python4Suite]<br />
<br />
[http://www.haskell.org/hawiki/PythonGenerator PythonGenerator]<br />
<br />
[http://www.haskell.org/hawiki/QuickCheck QuickCheck]<br />
<br />
[http://www.haskell.org/hawiki/QuotesPage QuotesPage]<br />
<br />
[http://www.haskell.org/hawiki/QuotesPage/DuelsPage QuotesPage/DuelsPage]<br />
<br />
[http://www.haskell.org/hawiki/RankTwoPolymorphism RankTwoPolymorphism]<br />
<br />
[http://www.haskell.org/hawiki/Recursion Recursion]<br />
<br />
[http://www.haskell.org/hawiki/RegexSyntax RegexSyntax]<br />
<br />
[http://www.haskell.org/hawiki/RemoveCorrect RemoveCorrect]<br />
<br />
[http://www.haskell.org/hawiki/RpmsProject RpmsProject]<br />
<br />
[http://www.haskell.org/hawiki/RunTimeCompilation RunTimeCompilation]<br />
<br />
[http://www.haskell.org/hawiki/RuntimeModels RuntimeModels]<br />
<br />
[http://www.haskell.org/hawiki/RuntimeModuleLoading RuntimeModuleLoading]<br />
<br />
[http://www.haskell.org/hawiki/SandBox SandBox]<br />
<br />
[http://www.haskell.org/hawiki/ScanningInHaskell ScanningInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/SchwartzianTransform SchwartzianTransform]<br />
<br />
[http://www.haskell.org/hawiki/SeiteFinden SeiteFinden]<br />
<br />
[http://www.haskell.org/hawiki/SeitenGröße SeitenGröße]<br />
<br />
[http://www.haskell.org/hawiki/ShortExamples ShortExamples]<br />
<br />
[http://www.haskell.org/hawiki/ShortExamples/BFInterpreter ShortExamples/BFInterpreter]<br />
<br />
[http://www.haskell.org/hawiki/ShortExamples/Copalindromes ShortExamples/Copalindromes]<br />
<br />
[http://www.haskell.org/hawiki/ShortExamples/POPCleaner ShortExamples/POPCleaner]<br />
<br />
[http://www.haskell.org/hawiki/ShortExamples/SymbolDifferentiation ShortExamples/SymbolDifferentiation]<br />
<br />
[http://www.haskell.org/hawiki/SieveOfEratosthenes SieveOfEratosthenes]<br />
<br />
[http://www.haskell.org/hawiki/SillySignatures SillySignatures]<br />
<br />
[http://www.haskell.org/hawiki/SimulatedCaseSplitting SimulatedCaseSplitting]<br />
<br />
[http://www.haskell.org/hawiki/SimulatingDependentTypes SimulatingDependentTypes]<br />
<br />
[http://www.haskell.org/hawiki/SiteNavigation SiteNavigation]<br />
<br />
[http://www.haskell.org/hawiki/SocraticMethod SocraticMethod]<br />
<br />
[http://www.haskell.org/hawiki/SoftwareEvolution SoftwareEvolution]<br />
<br />
[http://www.haskell.org/hawiki/SpecialistDataStructures SpecialistDataStructures]<br />
<br />
[http://www.haskell.org/hawiki/SpreadSheet SpreadSheet]<br />
<br />
[http://www.haskell.org/hawiki/StackOverflow StackOverflow]<br />
<br />
[http://www.haskell.org/hawiki/StandardCollectionLibraries StandardCollectionLibraries]<br />
<br />
[http://www.haskell.org/hawiki/StandardCollectionLibraries/TODO StandardCollectionLibraries/TODO]<br />
<br />
[http://www.haskell.org/hawiki/StartSeite StartSeite]<br />
<br />
[http://www.haskell.org/hawiki/StateMonad StateMonad]<br />
<br />
[http://www.haskell.org/hawiki/StatePropagation StatePropagation]<br />
<br />
[http://www.haskell.org/hawiki/StdGen StdGen]<br />
<br />
[http://www.haskell.org/hawiki/StraFunski StraFunski]<br />
<br />
[http://www.haskell.org/hawiki/StructuredText StructuredText]<br />
<br />
[http://www.haskell.org/hawiki/StudyGroup StudyGroup]<br />
<br />
[http://www.haskell.org/hawiki/StudyGroup/GraphExamplesInHaskell StudyGroup/GraphExamplesInHaskell]<br />
<br />
[http://www.haskell.org/hawiki/StudyGroup/GraphExamplesInHaskell/WhySum3 StudyGroup/GraphExamplesInHaskell/WhySum3]<br />
<br />
[http://www.haskell.org/hawiki/StudyGroup/Talk StudyGroup/Talk]<br />
<br />
[http://www.haskell.org/hawiki/SudokuSolver SudokuSolver]<br />
<br />
[http://www.haskell.org/hawiki/SvenMoritzHallberg SvenMoritzHallberg]<br />
<br />
[http://www.haskell.org/hawiki/SystemInfo SystemInfo]<br />
<br />
[http://www.haskell.org/hawiki/splitAt splitAt]<br />
<br />
[http://www.haskell.org/hawiki/TailRecursive TailRecursive]<br />
<br />
[http://www.haskell.org/hawiki/TeamSuccGMT TeamSuccGMT]<br />
<br />
[http://www.haskell.org/hawiki/TemplateHaskell TemplateHaskell]<br />
<br />
[http://www.haskell.org/hawiki/TemplateHaskellTutorial TemplateHaskellTutorial]<br />
<br />
[http://www.haskell.org/hawiki/TextCtrl TextCtrl]<br />
<br />
[http://www.haskell.org/hawiki/ThatAnnoyingIOType ThatAnnoyingIOType]<br />
<br />
[http://www.haskell.org/hawiki/ThatAnnoyingIoType ThatAnnoyingIoType]<br />
<br />
[http://www.haskell.org/hawiki/TheGallery TheGallery]<br />
<br />
[http://www.haskell.org/hawiki/TheZipper TheZipper]<br />
<br />
[http://www.haskell.org/hawiki/TheZipper/Zipper TheZipper/Zipper]<br />
<br />
[http://www.haskell.org/hawiki/TheZipper/ZipperG TheZipper/ZipperG]<br />
<br />
[http://www.haskell.org/hawiki/TimeLibrary TimeLibrary]<br />
<br />
[http://www.haskell.org/hawiki/TipsAndTricks TipsAndTricks]<br />
<br />
[http://www.haskell.org/hawiki/TitleIndex TitleIndex]<br />
<br />
[http://www.haskell.org/hawiki/TrexStyleRecords TrexStyleRecords]<br />
<br />
[http://www.haskell.org/hawiki/TyingTheKnot TyingTheKnot]<br />
<br />
[http://www.haskell.org/hawiki/TypeClass TypeClass]<br />
<br />
[http://www.haskell.org/hawiki/TypeClassConstraint TypeClassConstraint]<br />
<br />
[http://www.haskell.org/hawiki/TypeInference TypeInference]<br />
<br />
[http://www.haskell.org/hawiki/TypeclassWrapper TypeclassWrapper]<br />
<br />
[http://www.haskell.org/hawiki/TypesOnShellLevel TypesOnShellLevel]<br />
<br />
=== U to Z===<br />
[http://www.haskell.org/hawiki/UnZip UnZip]<br />
<br />
[http://www.haskell.org/hawiki/UndecidableInstances UndecidableInstances]<br />
<br />
[http://www.haskell.org/hawiki/UndecidableProblem UndecidableProblem]<br />
<br />
[http://www.haskell.org/hawiki/UnderConstruction UnderConstruction]<br />
<br />
[http://www.haskell.org/hawiki/UnderestimatedTypeClasses UnderestimatedTypeClasses]<br />
<br />
[http://www.haskell.org/hawiki/UnderstandingArrows UnderstandingArrows]<br />
<br />
[http://www.haskell.org/hawiki/UnicodeHaskellSource UnicodeHaskellSource]<br />
<br />
[http://www.haskell.org/hawiki/UnicodeInputOutput UnicodeInputOutput]<br />
<br />
[http://www.haskell.org/hawiki/UnicodeIssues UnicodeIssues]<br />
<br />
[http://www.haskell.org/hawiki/UnicodePrelude UnicodePrelude]<br />
<br />
[http://www.haskell.org/hawiki/UnitObject UnitObject]<br />
<br />
[http://www.haskell.org/hawiki/UnitTesting UnitTesting]<br />
<br />
[http://www.haskell.org/hawiki/UpdateInPlace UpdateInPlace]<br />
<br />
[http://www.haskell.org/hawiki/UserPreferences UserPreferences]<br />
<br />
[http://www.haskell.org/hawiki/UsingHaskellWikiMaterial UsingHaskellWikiMaterial]<br />
<br />
[http://www.haskell.org/hawiki/UsingIo UsingIo]<br />
<br />
[http://www.haskell.org/hawiki/UsingLibraries UsingLibraries]<br />
<br />
[http://www.haskell.org/hawiki/UsingMonadTransformers UsingMonadTransformers]<br />
<br />
[http://www.haskell.org/hawiki/UsingMonads UsingMonads]<br />
<br />
[http://www.haskell.org/hawiki/UsingRecords UsingRecords]<br />
<br />
[http://www.haskell.org/hawiki/VersusQuotesPage VersusQuotesPage]<br />
<br />
[http://www.haskell.org/hawiki/VerwaisteSeiten VerwaisteSeiten]<br />
<br />
[http://www.haskell.org/hawiki/Views Views]<br />
<br />
[http://www.haskell.org/hawiki/Vim Vim]<br />
<br />
[http://www.haskell.org/hawiki/WaSh WaSh]<br />
<br />
[http://www.haskell.org/hawiki/WayOfTheFuture WayOfTheFuture]<br />
<br />
[http://www.haskell.org/hawiki/WebAppsFramework WebAppsFramework]<br />
<br />
[http://www.haskell.org/hawiki/Weroom Weroom]<br />
<br />
[http://www.haskell.org/hawiki/WhatDoesThatSymbolMean WhatDoesThatSymbolMean]<br />
<br />
[http://www.haskell.org/hawiki/WhatIsThePrelude WhatIsThePrelude]<br />
<br />
[http://www.haskell.org/hawiki/WhatIsaFold WhatIsaFold]<br />
<br />
[http://www.haskell.org/hawiki/WhileLoop WhileLoop]<br />
<br />
[http://www.haskell.org/hawiki/WhyFunctionalProgrammingMatters WhyFunctionalProgrammingMatters]<br />
<br />
[http://www.haskell.org/hawiki/WhyWikiWorks WhyWikiWorks]<br />
<br />
[http://www.haskell.org/hawiki/WikiHomePage WikiHomePage]<br />
<br />
[http://www.haskell.org/hawiki/WikiName WikiName]<br />
<br />
[http://www.haskell.org/hawiki/WikiSandBox WikiSandBox]<br />
<br />
[http://www.haskell.org/hawiki/WikiSyntax WikiSyntax]<br />
<br />
[http://www.haskell.org/hawiki/WikiUsers WikiUsers]<br />
<br />
[http://www.haskell.org/hawiki/WikiWiki WikiWiki]<br />
<br />
[http://www.haskell.org/hawiki/WikiWikiSandbox WikiWikiSandbox]<br />
<br />
[http://www.haskell.org/hawiki/WikiWikiWeb WikiWikiWeb]<br />
<br />
[http://www.haskell.org/hawiki/WinHugs WinHugs]<br />
<br />
[http://www.haskell.org/hawiki/WishList WishList]<br />
<br />
[http://www.haskell.org/hawiki/WordIndex WordIndex]<br />
<br />
[http://www.haskell.org/hawiki/WortIndex WortIndex]<br />
<br />
[http://www.haskell.org/hawiki/WritingCryptDiscordian WritingCryptDiscordian]<br />
<br />
[http://www.haskell.org/hawiki/XsltVersion XsltVersion]<br />
<br />
[http://www.haskell.org/hawiki/YetAnotherHaskellTutorial YetAnotherHaskellTutorial]<br />
<br />
[http://www.haskell.org/hawiki/YetAnotherStudyGuide YetAnotherStudyGuide]<br />
<br />
<br />
<br />
== Monad Reader ==<br />
<br />
Shapr? Want to move these?<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader TheMonadReader]<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader/IssueOne TheMonadReader/IssueOne]<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader/IssueOne/FeedBack TheMonadReader/IssueOne/FeedBack]<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader/IssueOne/FeedBack/Gtk2Hs TheMonadReader/IssueOne/FeedBack/Gtk2Hs]<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader/IssueOne/FeedBack/PseudoCode TheMonadReader/IssueOne/FeedBack/PseudoCode]<br />
<br />
[http://www.haskell.org/hawiki/TheMonadReader/IssueOne/FeedBack/PugsProject TheMonadReader/IssueOne/FeedBack/PugsProject]<br />
<br />
== Cabal pages ==<br />
<br />
[http://www.haskell.org/hawiki/Cabal Cabal]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/AggregatePackages Cabal/AggregatePackages]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/Bugs Cabal/Bugs]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/ConditionalCodeAndDependencies Cabal/ConditionalCodeAndDependencies]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/Design Cabal/Design]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/MultiPackageDistributables Cabal/MultiPackageDistributables]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/TODO Cabal/TODO]<br />
<br />
[http://www.haskell.org/hawiki/Cabal/VirtualizationRequirements Cabal/VirtualizationRequirements]<br />
<br />
[http://www.haskell.org/hawiki/CabalGet CabalGet]<br />
<br />
== Pages in German ==<br />
<br />
[http://www.haskell.org/hawiki/AktuelleÄnderungen AktuelleÄnderungen]<br />
<br />
[http://www.haskell.org/hawiki/AufgegebeneSeiten AufgegebeneSeiten]<br />
<br />
[http://www.haskell.org/hawiki/BenutzerEinstellungen BenutzerEinstellungen]<br />
<br />
<br />
[http://www.haskell.org/hawiki/HilfeAllgemein HilfeAllgemein]<br />
<br />
[http://www.haskell.org/hawiki/HilfeAllgemein/FragenUndAntworten HilfeAllgemein/FragenUndAntworten]<br />
<br />
[http://www.haskell.org/hawiki/HilfeFürAnfänger HilfeFürAnfänger]<br />
<br />
[http://www.haskell.org/hawiki/HilfeFürEntwickler HilfeFürEntwickler]<br />
<br />
[http://www.haskell.org/hawiki/HilfeIndex HilfeIndex]<br />
<br />
[http://www.haskell.org/hawiki/HilfeInhalt HilfeInhalt]<br />
<br />
[http://www.haskell.org/hawiki/HilfeTemplate HilfeTemplate]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuAktionen HilfeZuAktionen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuAktionen/DateiAnhänge HilfeZuAktionen/DateiAnhänge]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuBenutzerEinstellungen HilfeZuBenutzerEinstellungen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuLayouts HilfeZuLayouts]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuListen HilfeZuListen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuMakros HilfeZuMakros]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuSmileys HilfeZuSmileys]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuTabellen HilfeZuTabellen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuTrennlinien HilfeZuTrennlinien]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuVerarbeitungsAnweisungen HilfeZuVerarbeitungsAnweisungen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuVerweisen HilfeZuVerweisen]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuXmlSeiten HilfeZuXmlSeiten]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZumEditieren HilfeZumEditieren]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZumEditieren/UnterSeiten HilfeZumEditieren/UnterSeiten]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZumFormatieren HilfeZumFormatieren]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZumUpdaten HilfeZumUpdaten]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurAdministration HilfeZurAdministration]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurInstallation HilfeZurInstallation]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurInstallation/ApacheAufUnix HilfeZurInstallation/ApacheAufUnix]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurInstallation/ApacheAufWin32 HilfeZurInstallation/ApacheAufWin32]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurInstallation/BasisInstallation HilfeZurInstallation/BasisInstallation]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurInstallation/FehlerBehebung HilfeZurInstallation/FehlerBehebung]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurKonfiguration HilfeZurKonfiguration]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurNavigation HilfeZurNavigation]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurRechtschreibprüfung HilfeZurRechtschreibprüfung]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurSeitenErzeugung HilfeZurSeitenErzeugung]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZurSeitenLöschung HilfeZurSeitenLöschung]<br />
<br />
[http://www.haskell.org/hawiki/HilfeZuÜberschriften HilfeZuÜberschriften]<br />
<br />
<br />
== Hawiki Infrastructure pages ==<br />
<br />
These pages can just disappear too.<br />
<br />
[http://www.haskell.org/hawiki/CategoryCodeSnippet CategoryCodeSnippet]<br />
<br />
[http://www.haskell.org/hawiki/CategoryCommunity CategoryCommunity]<br />
<br />
[http://www.haskell.org/hawiki/CategoryHaskellImplementations CategoryHaskellImplementations]<br />
<br />
[http://www.haskell.org/hawiki/CategoryHomepage CategoryHomepage]<br />
<br />
[http://www.haskell.org/hawiki/CategoryMonad CategoryMonad]<br />
<br />
[http://www.haskell.org/hawiki/CategoryCategory CategoryCategory]<br />
<br />
[http://www.haskell.org/hawiki/CategoryTools CategoryTools]<br />
<br />
[http://www.haskell.org/hawiki/CategoryTutorial CategoryTutorial]<br />
<br />
[http://www.haskell.org/hawiki/CategoryApplication CategoryApplication]<br />
<br />
[http://www.haskell.org/hawiki/AdminGroup AdminGroup]<br />
<br />
[http://www.haskell.org/hawiki/BadContent BadContent]<br />
<br />
[http://www.haskell.org/hawiki/WhyWikiWorks WhyWikiWorks]<br />
<br />
[http://www.haskell.org/hawiki/WikiHomePage WikiHomePage]<br />
<br />
[http://www.haskell.org/hawiki/WikiName WikiName]<br />
<br />
[http://www.haskell.org/hawiki/WikiSandBox WikiSandBox]<br />
<br />
[http://www.haskell.org/hawiki/WikiSyntax WikiSyntax]<br />
<br />
[http://www.haskell.org/hawiki/WikiUsers WikiUsers]<br />
<br />
[http://www.haskell.org/hawiki/WikiWiki WikiWiki]<br />
<br />
[http://www.haskell.org/hawiki/WikiWikiSandbox WikiWikiSandbox]<br />
<br />
[http://www.haskell.org/hawiki/WikiWikiWeb WikiWikiWeb]<br />
<br />
== User pages ==<br />
<br />
These pages may just disappear. Users can recreate them on the new wiki<br />
<br />
[http://www.haskell.org/hawiki/AaronDenney AaronDenney] [http://www.haskell.org/hawiki/AbeEgnor AbeEgnor] [http://www.haskell.org/hawiki/AlastairReid AlastairReid] [http://www.haskell.org/hawiki/AlbertReiner AlbertReiner] [http://www.haskell.org/hawiki/AlexanderWilliams AlexanderWilliams] [http://www.haskell.org/hawiki/AllenWoolfrey AllenWoolfrey] [http://www.haskell.org/hawiki/AlsonKemp AlsonKemp] [http://www.haskell.org/hawiki/AndersCarlsson AndersCarlsson] [http://www.haskell.org/hawiki/AndersHöckersten AndersHöckersten] [http://www.haskell.org/hawiki/AndrePang AndrePang] [http://www.haskell.org/hawiki/AndrewBromage AndrewBromage] [http://www.haskell.org/hawiki/AndreySidorenko AndreySidorenko] [http://www.haskell.org/hawiki/AndréPang AndréPang] [http://www.haskell.org/hawiki/AndyGeorges AndyGeorges] [http://www.haskell.org/hawiki/AndyGill AndyGill] [http://www.haskell.org/hawiki/AntonioRegidorGarcia AntonioRegidorGarcia] [http://www.haskell.org/hawiki/AnttiJuhaniKaijanaho AnttiJuhaniKaijanaho] [http://www.haskell.org/hawiki/AudreyTang AudreyTang] [http://www.haskell.org/hawiki/AutrijusTang AutrijusTang] [http://www.haskell.org/hawiki/BastiaanZapf BastiaanZapf] [http://www.haskell.org/hawiki/BernardPope BernardPope] [http://www.haskell.org/hawiki/BjarkeDahlEbert BjarkeDahlEbert] [http://www.haskell.org/hawiki/BjornBringert BjornBringert] [http://www.haskell.org/hawiki/BorislavManolov BorislavManolov] [http://www.haskell.org/hawiki/BrandonMoore BrandonMoore] [http://www.haskell.org/hawiki/BrianEdwards BrianEdwards] [http://www.haskell.org/hawiki/BruceWilliams BruceWilliams] [http://www.haskell.org/hawiki/BryanMurphy BryanMurphy] [http://www.haskell.org/hawiki/BrynKeller BrynKeller] [http://www.haskell.org/hawiki/BulatZiganshin BulatZiganshin] [http://www.haskell.org/hawiki/CaleGibbard CaleGibbard] [http://www.haskell.org/hawiki/CaleGibbard/BSDLicense CaleGibbard/BSDLicense] [http://www.haskell.org/hawiki/ChrisAngus ChrisAngus] [http://www.haskell.org/hawiki/ChrisMilton ChrisMilton] [http://www.haskell.org/hawiki/ChristophePoucet ChristophePoucet] [http://www.haskell.org/hawiki/ChristopherHendrie ChristopherHendrie] [http://www.haskell.org/hawiki/ColinDeVilbiss ColinDeVilbiss] [http://www.haskell.org/hawiki/ConalElliott ConalElliott] [http://www.haskell.org/hawiki/CraigDickson CraigDickson] [http://www.haskell.org/hawiki/CraigLennox CraigLennox] [http://www.haskell.org/hawiki/DaveMenendez DaveMenendez] [http://www.haskell.org/hawiki/DavidHimmelstrup DavidHimmelstrup] [http://www.haskell.org/hawiki/DeanHerington DeanHerington] [http://www.haskell.org/hawiki/DerekElkins DerekElkins] [http://www.haskell.org/hawiki/DiegoNavarro DiegoNavarro] [http://www.haskell.org/hawiki/DimitryGolubovsky DimitryGolubovsky] [http://www.haskell.org/hawiki/DinkoTenev DinkoTenev] [http://www.haskell.org/hawiki/DmitryAstapov DmitryAstapov] [http://www.haskell.org/hawiki/DylanThurston DylanThurston] [http://www.haskell.org/hawiki/EinarKarttunen EinarKarttunen] [http://www.haskell.org/hawiki/EndreyMark EndreyMark] [http://www.haskell.org/hawiki/FrankAtanassow FrankAtanassow] [http://www.haskell.org/hawiki/FrankChristoph FrankChristoph] [http://www.haskell.org/hawiki/FrederikEaton FrederikEaton] [http://www.haskell.org/hawiki/GaneshSittampalam GaneshSittampalam] [http://www.haskell.org/hawiki/GaneshSittampalam/MoinEditorBackup GaneshSittampalam/MoinEditorBackup] [http://www.haskell.org/hawiki/GerardHuet GerardHuet] [http://www.haskell.org/hawiki/GordonMatzigkeit GordonMatzigkeit] [http://www.haskell.org/hawiki/GraemeJefferis GraemeJefferis] [http://www.haskell.org/hawiki/GrahamKlyne GrahamKlyne] [http://www.haskell.org/hawiki/HannahSchroeter HannahSchroeter] [http://www.haskell.org/hawiki/IsaacJones IsaacJones] [http://www.haskell.org/hawiki/JackWaugh JackWaugh] [http://www.haskell.org/hawiki/JamesGray JamesGray] [http://www.haskell.org/hawiki/JanDeWit JanDeWit] [http://www.haskell.org/hawiki/JaredJennings JaredJennings] [http://www.haskell.org/hawiki/JensPetersen JensPetersen] [http://www.haskell.org/hawiki/JesperLouisAndersen JesperLouisAndersen] [http://www.haskell.org/hawiki/JesseRudolph JesseRudolph] [http://www.haskell.org/hawiki/JesseRudolph/SequenceLibrary JesseRudolph/SequenceLibrary] [http://www.haskell.org/hawiki/JohanBaltie JohanBaltie] [http://www.haskell.org/hawiki/JohannesAhlmann JohannesAhlmann] [http://www.haskell.org/hawiki/JohnHeron JohnHeron] [http://www.haskell.org/hawiki/JohnHughes JohnHughes] [http://www.haskell.org/hawiki/JohnMeacham JohnMeacham] [http://www.haskell.org/hawiki/JohnTromp JohnTromp] [http://www.haskell.org/hawiki/JoseAntonioOrtega JoseAntonioOrtega] [http://www.haskell.org/hawiki/JudeNagurney JudeNagurney] [http://www.haskell.org/hawiki/KeithWansbrough KeithWansbrough] [http://www.haskell.org/hawiki/KennethHoste KennethHoste] [http://www.haskell.org/hawiki/KetilMalde KetilMalde] [http://www.haskell.org/hawiki/LarsOlson LarsOlson] [http://www.haskell.org/hawiki/LennartKolmodin LennartKolmodin] [http://www.haskell.org/hawiki/LudvigStrigeus LudvigStrigeus] [http://www.haskell.org/hawiki/LuisAraujo LuisAraujo] <br />
[http://www.haskell.org/hawiki/LiyangHu LiyangHu] [http://www.haskell.org/hawiki/LyndonTremblay LyndonTremblay] [http://www.haskell.org/hawiki/MahlenMorris MahlenMorris] [http://www.haskell.org/hawiki/ManuelChakravarty ManuelChakravarty] [http://www.haskell.org/hawiki/MarcoBakera MarcoBakera] [http://www.haskell.org/hawiki/MarkCarroll MarkCarroll] [http://www.haskell.org/hawiki/MarkWotton MarkWotton] [http://www.haskell.org/hawiki/MarkoSchuetz MarkoSchuetz] [http://www.haskell.org/hawiki/MartinNorbäck MartinNorbäck] [http://www.haskell.org/hawiki/MartinSjögren MartinSjögren] [http://www.haskell.org/hawiki/MatthewWalton MatthewWalton] [http://www.haskell.org/hawiki/MichaelRichter MichaelRichter] [http://www.haskell.org/hawiki/MikaelBrockman MikaelBrockman] [http://www.haskell.org/hawiki/MikeBeedle MikeBeedle] [http://www.haskell.org/hawiki/NoelWinstanley NoelWinstanley] [http://www.haskell.org/hawiki/OhadKammar OhadKammar] [http://www.haskell.org/hawiki/PeterSimons PeterSimons] [http://www.haskell.org/hawiki/PhilippaCowderoy PhilippaCowderoy] [http://www.haskell.org/hawiki/PhilippaCowderoy/TestPage PhilippaCowderoy/TestPage] [http://www.haskell.org/hawiki/Pishcotec Pishcotec] [http://www.haskell.org/hawiki/Qiyang Qiyang] [http://www.haskell.org/hawiki/Riastradh Riastradh] [http://www.haskell.org/hawiki/RichardTibbetts RichardTibbetts] [http://www.haskell.org/hawiki/RonLegere RonLegere] [http://www.haskell.org/hawiki/ScottTurner ScottTurner] [http://www.haskell.org/hawiki/SebastianSylvan SebastianSylvan] [http://www.haskell.org/hawiki/ShaeErisson ShaeErisson] [http://www.haskell.org/hawiki/SimonFoster SimonFoster] [http://www.haskell.org/hawiki/SimonJanes SimonJanes] [http://www.haskell.org/hawiki/SimonMarlow SimonMarlow] [http://www.haskell.org/hawiki/SpencerJanssen SpencerJanssen] [http://www.haskell.org/hawiki/StefanHeinzmann StefanHeinzmann] [http://www.haskell.org/hawiki/StefanHoldermans StefanHoldermans] [http://www.haskell.org/hawiki/StefanLjungstrand StefanLjungstrand] [http://www.haskell.org/hawiki/SteveDunham SteveDunham] [http://www.haskell.org/hawiki/SteveElkins SteveElkins] [http://www.haskell.org/hawiki/TomCooper TomCooper] [http://www.haskell.org/hawiki/TomMoertel TomMoertel] [http://www.haskell.org/hawiki/TomPledger TomPledger] [http://www.haskell.org/hawiki/VolkerStolz VolkerStolz] [http://www.haskell.org/hawiki/WadeCunningham WadeCunningham] [http://www.haskell.org/hawiki/WardCunningham WardCunningham] [http://www.haskell.org/hawiki/WegWeiser WegWeiser] [http://www.haskell.org/hawiki/WolfgangThaller WolfgangThaller] [http://www.haskell.org/hawiki/ZufallsSeite ZufallsSeite] [http://www.haskell.org/hawiki/shelarcy shelarcy]</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Talk:Gallery&diff=3841Talk:Gallery2006-04-24T18:30:28Z<p>Derek Elkins: </p>
<hr />
<div>I wonder if this should be a new Category, Category:Code, for example,<br />
so that pages can get indexed for us. -- Don<br />
<br />
Most likely. Or, failing that, something like it will be needed. While I like [[ExampleCode]] (I was the one that started the [http://haskell.org/hawiki/CodeOnTheWiki CodeOnTheWiki] page), not everything will fit there. Even many of the links on [http://haskell.org/hawiki/CodeOnTheWiki CodeOnTheWiki] do not seem to fit on the [[ExampleCode]] page. -- Derek Elkins</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Summer_of_Code/Project_suggestions&diff=3840Summer of Code/Project suggestions2006-04-24T18:23:00Z<p>Derek Elkins: I assume you meant lua</p>
<hr />
<div>Haskell projects for Google's Summer of Code.<br />
<br />
This page is for [[Summer of Code: People | mentors]] to add their ideas and to say which projects they'd be happy to supervise. It's also ok for other people to add their own ideas that are not yet claimed by a mentor. If you do this, could you please notify an admin person so that they can try and find a mentor for that project idea, because in the end we can only deal with project ideas that do have people prepared to mentor them. <br />
<br />
Students should not claim projects here, they must use the normal Google Summer of Code application process. See the [http://code.google.com/soc/studentfaq.html student FAQ] for details.<br />
<br />
== Cabal ==<br />
<br />
=== Cabal-get/HackageDB ===<br />
Cabal-get is an automatic installer for Cabal libraries.<br />
The goal is to distribute the program with [http://haskell.org/cabal Cabal], but to achieve this we need to cut almost all of its dependencies. This project should be fairly easy (the code base of cabal-get is only 1K loc).<br />
<br />
Mentor: Lemmih (lemmih@gmail.com)<br />
<br />
=== Distributed compilation ===<br />
<br />
A-la distcc, the distributed compilation of Haskell modules.<br />
<br />
== GHC ==<br />
<br />
=== GhcPlugins ===<br />
Write a new plugin system using the new ghc-api. Enough of the groundwork has been laid out now that someone with a few months and some background could finish up the work.<br />
<br />
GhcPlugins will replace the plugin system currently used in [http://haskell.org/hide hIDE].<br />
<br />
Mentor: Lemmih (lemmih@gmail.com)<br />
<br />
=== Implement various debugging tools in GHC ===<br />
* Dynamic breakpoints.<br />
* Generic object viewer.<br />
* Simple CCS for providing stack traces on exceptions and breakpoints.<br />
<br />
Mentor: Lemmih (lemmih@gmail.com)<br />
<br />
=== Handle recursive modules in GHC ===<br />
<br />
=== Incremental Garbage Collector for GHC ===<br />
<br />
Implementing the incremental garbage collection algorithm described in the paper [http://research.microsoft.com/~simonpj/Papers/inc-gc.htm Non-stop Haskell] in GHC.<br />
<br />
=== Parsers for various programming languages ===<br />
<br />
Populate the [http://haskell.org/ghc/docs/latest/html/libraries/index.html Language] hierarchy of modules with new parsers for many languages, at the moment it does only contain Language.Haskell.<br />
<br />
Mentor: Shae Matijs Erisson (shapr@scannedinavian.com)<br />
<br />
=== Data.ByteString ===<br />
<br />
Extend the [http://www.cse.unsw.edu.au/~dons/fps.html Data.ByteString]<br />
interface to arbitrary (Storable a) arrays. Data.ByteString provides a<br />
high performance api to arrays of bytes. Generalise this to arbitrary<br />
vectors of Storable a values, winning fame and glory in the process.<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
=== Unicode layer over Data.ByteString ===<br />
<br />
Extend the [http://www.cse.unsw.edu.au/~dons/fps.html Data.ByteString]<br />
interface to support Unicode.<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
=== Improve performance of numerical code ===<br />
<br />
GHC's performance for double and float intensive code is not as good as<br />
it could be. Find out why and improve it. Requires GHC backend hacking.<br />
Must be very Haskell literate or have knowledge of code generators.<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
=== Port the Clean high performance string code ===<br />
<br />
Clean does very well for low level string benchmarks. Find out what<br />
they do, and port it to [http://www.cse.unsw.edu.au/~dons/fps.html Data.ByteString]<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
== Graphics ==<br />
<br />
=== Fix HsSDL (Haskell [http://libsdl.org libSDL] bindings) on Windows and MacOS ===<br />
<br />
=== Gtk / Graphics / GNOME related projects ===<br />
<br />
I'd be happy to accept projects in this area. Last year I was unofficial mentor to Paolo who did the [http://www.cairographics.org/ cairo] bindings. (Feel free to add more ideas here or I might do as I think of them.)<br />
<br />
Mentor: Duncan Coutts<br />
<br />
It would be cool to see a library using ideas from [http://www.sandr.dds.nl/FunctionalForms/index.html FunctionalForms] in Gtk2Hs.<br />
<br />
=== Darcs Gtk+ GUI ===<br />
<br />
Design and implement a GUI front-end using Gtk2Hs for Darcs.<br />
<br />
Mentor: No-one.<br />
<br />
=== Embed ghci/ghci-api in ion ===<br />
<br />
[http://modeemi.cs.tut.fi/~tuomov/ion/ ion] is a cool window manager<br />
written by Tuomo Valkonen, a Haskell hacker. It is currently extensible<br />
in [http://www.lua.org/ lua], but a very interesting project would be to work out how to<br />
dynamically extend it in Haskell, perhaps using ideas from<br />
[http://www.cse.unsw.edu.au/~dons/yi.html Yi].<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
== Web development ==<br />
<br />
=== Continuation based DSL on top of HAppS ===<br />
<br />
Do you have a vision how to do better than WASH? Integrate continuation based interaction with client or use something like Functional Forms for the interaction. How to best to interact with XML etc. Other HAppS related projects<br />
also possible.<br />
<br />
Mentor: Einar Karttunen (musasabi)<br />
<br />
== Editing ==<br />
<br />
=== Port ghc-api's eval mechanism to Yi ===<br />
<br />
Yi is an editor written and extensible in Haskell. Construct a binding<br />
to ghc-api such that new expressions may be evaluated at runtime in the<br />
editor, accessing the editors internal structures in a type safe way,<br />
dynamically. elisp for Haskell!<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au) and Lemmih (lemmih@gmail.com).<br />
<br />
=== Yi projects ===<br />
<br />
Syntax Highlighting, Plugins. It's quite a peculiar kind of application. Its design is based on [http://www.cse.unsw.edu.au/~dons/papers/PSSC04.html type-safe dynamically loadable modules] and it is [http://www.cse.unsw.edu.au/~dons/papers/PSSC04.html more dynamic than Emacs]!<br />
<br />
Mentor: Shae Matijs Erisson (shapr@scannedinavian.com)<br />
<br />
=== Generic Hide Hacking ===<br />
* Rewrite plugins for the new plugin-system.<br />
* Integration with [[Lambdabot]], access to plugins through Hide.<br />
* Other?<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au), Lemmih (lemmih@gmail.com)<br />
<br />
== Bindings ==<br />
<br />
=== D-BUS Binding ===<br />
<br />
Haskell bindings to the [http://www.freedesktop.org/wiki/Software/dbus D-BUS] message bug system, a simple way for applications to talk to one another. <br />
<br />
Mentor: Duncan Coutts<br />
<br />
=== Matlab Binding ===<br />
<br />
Matlab is an excellent tool for quick imperative numerical programming.<br />
However, it would be much nicer if anyone wrote bindings such<br />
that it could be mixed with Haskell.<br />
<br />
Mentor: Johan Henriksson (Mahogny, johen@student.chalmers.se)<br />
<br />
== Games ==<br />
<br />
=== Frag hacking ===<br />
<br />
[[Frag]] is a 3d first person shootup game written in Haskell,<br />
using OpenGL. It can be greatly extended in all sorts of ways. If<br />
you're in to gaming, have a look at this.<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
=== Students' ideas / Games ===<br />
<br />
I'm ready to take on anyone willing to write a useful application or game (preferably a program) given that it is of reasonable size (upper limitaton).<br />
<br />
Mentor: Johan Henriksson (Mahogny, johen@student.chalmers.se)<br />
<br />
== Bioinformatics ==<br />
<br />
=== Bioinformatics tools ===<br />
<br />
1. Further develop RBR, a tool for masking repeats. This can include<br />
a) optimize (using FastPackedString and/or a new internal data structure); b) extend functionality.<br />
<br />
2. Develop a tool for annotation/classification of sequences. This would involve computation on and visualization of graphs (experience with the latter would be really great).<br />
<br />
Prior bioinformatics knowledge is not a requirement. Please contact me for details.<br />
<br />
Mentor: Ketil ([mailto:ketil@ii.uib.no ketil@ii.uib.no])<br />
<br />
== Concurrency / Network ==<br />
<br />
=== Concurrent disk-based data structures ===<br />
<br />
Implement B+tree or a variant supporting concurrent updates using STM,<br />
serialize updates into a write ahead log and provide for serialization.<br />
Bind the whole thing with a nice HaskellDB like API. Variations on<br />
the theme possible.<br />
<br />
Mentor: Einar Karttunen<br />
<br />
=== Haskellnet ===<br />
<br />
We have got cgi, ftp, http, and irc. Get them into shape in the hierarchical libraries as well as adding a number of other protocols, like nntp, smtp and pop3, imap4, ... much like the [http://ocamlnet.sourceforge.net/doc/goals/goals.html Ocamlnet project].<br />
<br />
Mentor: Shae Matijs Erisson (shapr@scannedinavian.com)<br />
<br />
== UNIX ==<br />
<br />
=== A Haskell shell ===<br />
<br />
Concise syntax and higher order functions would make a Haskell shell<br />
very useful. This project would aim to produce a real world shell <br />
written in Haskell, and using an embedded domain specific language to<br />
encode common operations.<br />
<br />
Mentor: Don Stewart (dons@cse.unsw.edu.au)<br />
<br />
== Databases ==<br />
<br />
=== HaskellDB ===<br />
<br />
==== Port HaskellDB to HList ====<br />
<br />
HaskellDB currently uses its own record system, which (I believe) is less powerful than HList. The project is to port HaskellDB to use HList instead, making any necessary changes to the interface to make this possible and to fit HList better.<br />
<br />
Mentor: Björn Bringert (bringert@cs.chalmers.se)<br />
<br />
==== Implement back-end dependent SQL generation in HaskellDB ====<br />
<br />
Currently HaskellDB uses the same SQL generator for all database systems. Unfortunately different database systems support different SQL dialects. The project is to make it possible to use different SQL generators for different back-ends, and implement generators for common database systems such as for example MySQL, PostgreSQL and SQLite. The project could also include adding support for back-end specific SQL extensions (such as various string and date functions, non-standard field types etc.) to the HaskellDB query language.<br />
<br />
Mentor: Björn Bringert (bringert@cs.chalmers.se)</div>Derek Elkinshttps://wiki.haskell.org/index.php?title=Phantom_type&diff=2203Phantom type2006-02-06T18:01:46Z<p>Derek Elkins: </p>
<hr />
<div>A '''phantom type''' is a [[type]] used only to construct other types; its values are never used. Phantom types are used in [[type arithmetic]], for example.<br />
<br />
An extension to Haskell 98 supported by [[GHC]] allows you to define datatypes without any constructors (and therefore no values other than [[bottom]]):<br />
<br />
data MyType<br />
<br />
This lets the compiler recognize phantom types and ensure they aren't used improperly.<br />
<br />
----<br />
<br />
The term "phantom type" already has an established use. A simple case is described (somewhat messily) in [[http://haskell.org/hawiki/PhantomTypes]]. [[http://www.google.com/search?hl=en&q=%22Phantom+types%22 This]] Google search lists many other uses of the term in that vein.<br />
[[Category:Idioms]]</div>Derek Elkins