https://wiki.haskell.org/api.php?action=feedcontributions&user=Twey&feedformat=atomHaskellWiki - User contributions [en]2024-03-28T16:55:09ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Functor&diff=58691Functor2014-08-23T17:25:08Z<p>Twey: Updated module.</p>
<hr />
<div>{{Standard class|Functor|module=Data.Functor|module-doc=Data.Functor|package=base}}<br />
The '''Functor''' class is defined like this:<br />
<br />
class Functor f where<br />
fmap :: (a -> b) -> f a -> f b<br />
<br />
It is available in the Prelude, but defined in Data.Functor.<br />
<br />
All instances of Functor should obey:<br />
<br />
fmap id = id<br />
fmap (p . q) = (fmap p) . (fmap q)<br />
<br />
<br />
== More reading == <br />
<br />
* [http://www.haskellforall.com/2012/09/the-functor-design-pattern.html The functor design pattern]<br />
<br />
<br />
<br />
[[Category:Functor|*]]</div>Tweyhttps://wiki.haskell.org/index.php?title=Yi/FAQ&diff=57312Yi/FAQ2013-12-14T18:58:49Z<p>Twey: /* How to Configure Yi */</p>
<hr />
<div>=== Installation ===<br />
<br />
*How do I install Yi?<br />
:Get it from Hackage. Configure, compile and install Yi as you would do for any other Cabal package. See also above-mentioned (2.3 Platform Support).<br />
<br />
*Setup configure fails with <br />
Setup.hs: Package yi-0.4 can't be built on this system.<br />
:It means that you have no UI package available. You need VTY or GTK2hs installed. Get them from Hackage.<br />
<br />
*cabal install yi fails with dependency errors, e.g.:<br />
$ cabal install yi<br />
Resolving dependencies...<br />
cabal.exe: dependencies conflict: ghc-6.8.3 requires bytestring ==0.9.0.1.1<br />
however<br />
bytestring-0.9.0.1.1 was excluded because bytestring-0.9.0.1 was selected<br />
instead<br />
bytestring-0.9.0.1.1 was excluded because yi-0.3 requires bytestring =0.9.0.1<br />
:Try removing all your old yi packages, and do<br />
cabal update<br />
before attempting to install.<br />
<br />
*cabal install -fghcAPI fails<br />
:If you want GHC API special capabilities, you have to download, configure, build and copy separately:<br />
cd yi<br />
cabal configure -fghcAPI<br />
cabal build<br />
cabal copy<br />
<br />
* Compilation fails with a message about <tt>alex</tt> not being available?<br />
: Currently, Cabal doesn't track programs, just libraries, so it won't warn you if you are missing Alex (as many people are). The solution here is to just <tt>cabal install alex</tt> first. (Yi uses Alex to generate code for parsing stuff with syntax, like Haskell source.)<br />
<br />
* I can't install <tt>yi-gtk</tt> or <tt>yi-vty</tt>! It wants <tt>sourceview</tt> or something.<br />
: As the Hackage descriptions say, yi-gtk and yi-vty are ''only'' for versions of older than Yi 0.3. You really should be running the latest development (Darcs) or stable (Hackage) versions of Yi, so ''don't'' try to install these two packages. Yi supports VTY and Gtk2hs directly in the <tt>yi</tt> package now.<br />
*On Mac OS X if you get an error message similar to this:<br />
yi: can't load .so/.DLL for: gthread-2.0 (dlopen(libgthread-2.0.dylib, 10): image not found)<br />
<br />
:then your dynamic library search path variable is probably not set correctly. You can set it (in Bash) using:<br />
<br />
export DYLD_LIBRARY_PATH=/opt/local/lib<br />
<br />
:(Adjust the specific path to your system. You can find the right location using <tt>locate libgthread</tt>)<br />
<br />
*On Mac OS 10.6 (Snow Leopard) if you get the following error:<br />
Loading package cairo-0.11.1 ... <command line>: can't load .so/.DLL for: pixman-1 (dlopen(/opt/local/lib/libpixman-1.dylib, 9): no suitable image found. Did find:<br />
/opt/local/lib/libpixman-1.dylib: mach-o, but wrong architecture)<br />
cabal: Error: some packages failed to install:<br />
yi-0.6.2.4 failed during the building phase. The exception was:<br />
ExitFailure 1<br />
<br />
:then the problem is that GHC currently only supports linking against i386 libraries, and your ports are compiled for x86_64. To fix, recompile your ports with the +universal variant like so:<br />
<br />
port install installed +universal<br />
<br />
* Compilation fails with errors about template-haskell or data-accessor:<br />
Add constraints about which release of those libraries to use.<br />
$ cabal install yi --constraint="data-accessor < 0.2.1" --constraint="template-haskell < 2.4"<br />
<br />
=== Default key bindings ===<br />
<br />
==== CUA key bindings ====<br />
<br />
===== File operations =====<br />
{|<br />
| Ctrl-o<br />
| Open file.<br />
|-<br />
| Ctrl-s<br />
| Save the current file.<br />
|-<br />
| Ctrl-q<br />
| Quit the editor.<br />
|}<br />
<br />
===== Cursor/selection movement =====<br />
{|<br />
| &rarr;<br />
| Move cursor forward one character.<br />
|-<br />
| &larr;<br />
| Move cursor back one character.<br />
|-<br />
| &darr;<br />
| Move cursor down one line.<br />
|-<br />
| &uarr;<br />
| Move cursor down one line.<br />
|-<br />
| Shift+&rarr;<br />
| Extend selection forward one character.<br />
|-<br />
| Shift+&larr;<br />
| Extend selection back one character.<br />
|-<br />
| Shift+&darr;<br />
| Extend selection down one line.<br />
|-<br />
| Shift+&uarr;<br />
| Extend selection up one line.<br />
|-<br />
| Ctrl-&rarr;<br />
| Move cursor forward one word.<br />
|-<br />
| Ctrl-&larr;<br />
| Move cursor back one word.<br />
|-<br />
| Home<br />
| Move cursor to beginning of line.<br />
|-<br />
| End<br />
| Move cursor to end of line.<br />
|-<br />
| Ctrl-Home<br />
| Move cursor to beginning of document.<br />
|-<br />
| Ctrl-End<br />
| Move cursor to end of document.<br />
|}<br />
<br />
===== Miscellaneous operations =====<br />
<br />
{|<br />
| Ctrl-f<br />
| Incremental search.<br />
|-<br />
| Ctrl-x<br />
| Cut the selected area and save it to the clipboard<br />
|-<br />
| Ctrl-c<br />
| Copy the selected area to the clipboard<br />
|-<br />
| Ctrl-v<br />
| Paste contents of clipboard at cursor.<br />
|-<br />
| Ctrl-z<br />
| Undo last operation.<br />
|-<br />
| Ctrl-y<br />
| Redo last operation.<br />
|}<br />
<br />
==== Vim key bindings ====<br />
==== Emacs key bindings ====<br />
<br />
C = Control<br />
<br />
M = Meta = Alt|Esc<br />
<br />
===== Basics =====<br />
{|<br />
|C-x C-f<br />
|"Find" file i.e. open/create a file in buffer<br />
|-<br />
|C-x C-s<br />
|Save the file<br />
|-<br />
|C-x C-w<br />
|Write the text to an alternate name<br />
|-<br />
|C-x i<br />
|Insert file at cursor position<br />
|-<br />
|C-x b<br />
|Create/switch buffers<br />
|-<br />
|C-x C-b<br />
|Show buffer list<br />
|-<br />
|C-x k<br />
|Kill buffer<br />
|-<br />
|C-z<br />
|Suspend Yi<br />
|-<br />
|C-x C-c<br />
|Close down Yi<br />
|}<br />
<br />
===== Basic movement =====<br />
<br />
{|<br />
|C-f<br />
|Forward char<br />
|-<br />
|C-b<br />
|Backward char<br />
|-<br />
|C-p<br />
|Previous line<br />
|-<br />
|C-n<br />
|Next line<br />
|-<br />
|M-f<br />
|Forward one word<br />
|-<br />
|M-b<br />
|Backward one word<br />
|-<br />
|C-a<br />
|Beginning of line<br />
|-<br />
|C-e<br />
|End of line<br />
|-<br />
|C-v<br />
|One page up<br />
|-<br />
|M-v<br />
|Scroll down one page<br />
|-<br />
|M-<<br />
|Beginning of text<br />
|-<br />
|M-><br />
|End of text<br />
|}<br />
<br />
===== Editing =====<br />
<br />
{|<br />
|M-n<br />
|Repeat the following command n times<br />
|-<br />
|C-u<br />
|Repeat the following command 4 times<br />
|-<br />
|C-d<br />
|Delete a char<br />
|-<br />
|M-d<br />
|Delete word<br />
|-<br />
|M-Del<br />
|Delete word backwards<br />
|-<br />
|C-k<br />
|Kill line<br />
|-<br />
|C-Space<br />
|Set beginning mark (for region marking for example)<br />
|-<br />
|C-W<br />
|"Kill" (delete) the marked region region<br />
|-<br />
|M-W<br />
|Copy the marked region<br />
|-<br />
|C-y<br />
|"Yank" (paste) the copied/killed region/line<br />
|-<br />
|M-y<br />
|Yank earlier text (cycle through kill buffer)<br />
|-<br />
|C-x C-x<br />
|Exchange cursor and mark<br />
|-<br />
|C-t<br />
|Transpose two chars<br />
|-<br />
|M-t<br />
|Transpose two words<br />
|-<br />
|M-u<br />
|Make letters uppercase in word from cursor position to end<br />
|-<br />
|M-c<br />
|Simply make first letter in word uppercase<br />
|-<br />
|M-l<br />
|Opposite to M-u<br />
|}<br />
<br />
===== Important =====<br />
<br />
{|<br />
|C-g<br />
|Quit the running/entered command<br />
|-<br />
|C-x u<br />
|Undo previous action<br />
|-<br />
|M-/<br />
|Undo previous action<br />
|}<br />
<br />
===== Search/Replace =====<br />
<br />
{|<br />
|C-s<br />
|Search forward<br />
|-<br />
|C-r<br />
|Search backward<br />
|-<br />
|M-%<br />
|Query replace<br />
|-<br />
|Space or y<br />
|Replace this occurrence<br />
|-<br />
|Del or n<br />
|Don't replace<br />
|-<br />
|!<br />
|Replace all following occurrences<br />
|-<br />
|ENTER or q<br />
|Quit replace<br />
|}<br />
<br />
===== Window-Commands =====<br />
<br />
{|<br />
|C-x 2<br />
|Split window vertically<br />
|-<br />
|C-x o<br />
|Change to other window<br />
|-<br />
|C-x 0<br />
|Delete window<br />
|-<br />
|C-x 1<br />
|Close all windows except the one the cursors in<br />
|}<br />
<br />
===== DIRectory EDitor (dired) =====<br />
<br />
{|<br />
|C-x d<br />
|Start up dired<br />
|-<br />
|C (large C)<br />
|Copy<br />
|-<br />
|d<br />
|Mark for erase<br />
|-<br />
|D<br />
|Delete right away<br />
|-<br />
|e or f<br />
|Open file or directory<br />
|-<br />
|g<br />
|Re-read directory structure from file<br />
|-<br />
|m<br />
|Mark with *<br />
|-<br />
|n<br />
|Move to next line<br />
|-<br />
|q<br />
|Quit dired<br />
|-<br />
|R<br />
|Rename file<br />
|-<br />
|u<br />
|Remove mark<br />
|-<br />
|x<br />
|Delete files marked with D<br />
|-<br />
| +<br />
|Create directory<br />
|}<br />
<br />
===== Programming =====<br />
<br />
{|<br />
|M-m<br />
|Move to first (non-space) char in this line<br />
|-<br />
|M-^<br />
|Attach this line to previous<br />
|-<br />
|M-;<br />
|Formatize and indent comment<br />
|-<br />
<br />
===== C, C++ and Java Modes =====<br />
<br />
{|<br />
|M-a<br />
|Beginning of statement<br />
|-<br />
|M-e<br />
|End of statement<br />
|-<br />
|C-c C-c<br />
|Comment out marked area<br />
|}<br />
<br />
=== Development ===<br />
<br />
*How do I install Yi for development?<br />
:Fork the repository on GitHub, then clone your version to your machine. Push to your repo on GitHub, and then make merge requests.<br />
<br />
*What are some of the dependancies?<br />
:There is a rather long list of dependencies for Yi, check the yi.cabal file for a list.<br />
<br />
::If you are on Mac OS X and are using MacPorts, then these will not be included in the GHC in that distribution. Many of the dependancies are in MacPorts (for example: ghc, ghc-devel, alex, and gtk2hs). However, you may have some trouble building with Cabal-1.5.2, since it is a development version of Cabal. To work around these issues, you might have to add the line "Build-Type: Simple" to the .cabal files in the above required packages.<br />
<br />
=== Configuration ===<br />
<br />
==== How to Configure Yi ====<br />
<br />
You can find configuration file examples in the 'examples/' directory, or online at [http://code.haskell.org/yi/examples/ http://code.haskell.org/yi/examples/].<br />
<br />
A good way to start is to copy yi.hs in your $XDG_CONFIG_HOME/yi directory (create it if needed), and hack as needed.<br />
<br />
=== Usage ===<br />
==== GError on startup ====<br />
I get the error message "yi.exe: <<System.Glib.GError.GError>>" when I try to run yi.<br />
<br />
Sometimes this is a result of yi not being able to find the contents of the art directory when trying to start in graphical mode (e.g. Gtk or Pango). Check that the install has be done correctly or use the VTY mode (<tt>$ yi -f vty</tt>).<br />
<br />
For more detail on the error, modify main in Yi/Main.hs to catch GError:<br />
<pre><br />
Right finalCfg -> do catchGError (do<br />
when (debugMode finalCfg) $ initDebug ".yi.dbg" <br />
startEditor finalCfg state) (\(GError dom code msg) -> fail msg)<br />
</pre><br />
<br />
Note that more recent versions of Yi (e.g. from the darcs repo) no longer simply display the anonymous GError but instead provide a more detailed error message (making the above code snippet unnecessary).<br />
<br />
[[Category:FAQ]]</div>Tweyhttps://wiki.haskell.org/index.php?title=Monad_laws&diff=45168Monad laws2012-04-05T17:56:16Z<p>Twey: Forgot a line.</p>
<hr />
<div>All instances of the [[Monad]] typeclass should obey the three '''monad laws''':<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell>return a >>= f</haskell><br />
| ≡<br />
| <haskell>f a</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell>m >>= return</haskell><br />
| ≡<br />
| <haskell>m</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell>(m >>= f) >>= g</haskell><br />
| ≡<br />
| <haskell>m >>= (\x -> f x >>= g)</haskell><br />
|}<br />
<br />
Here, ''p'' ≡ ''q'' simply means that you can replace ''p'' with ''q'' and vice-versa, and the behaviour of your program will not change: ''p'' and ''q'' are equivalent.<br />
<br />
== What is the practical meaning of the monad laws? ==<br />
<br />
Let us re-write the laws in do-notation:<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell><br />
do<br />
x' <- return x<br />
f x'<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
f x<br />
</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell><br />
do<br />
x <- m<br />
return x<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
m<br />
</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell><br />
do<br />
y <- do<br />
x <- m<br />
f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
do<br />
y <- f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
y <- f x<br />
g y<br />
</haskell><br />
|}<br />
<br />
In this notation the laws appear as plain common-sense transformations of imperative programs.<br />
<br />
== But why should monads obey these laws? ==<br />
<br />
When we see a program written in a form on the left-hand side, we expect it to do<br />
the same thing as the corresponding right-hand side; and vice versa. And in<br />
practice, people do write like the lengthier left-hand side once in a while.<br />
First example: beginners tend to write<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
line <- getLine<br />
return line<br />
</haskell><br />
<br />
and it would really throw off both beginners and veterans if that did<br />
not act like (by right identity)<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
getLine<br />
</haskell><br />
<br />
Second example: Next, you go ahead to use skip_and_get:<br />
<br />
<haskell><br />
main = do<br />
answer <- skip_and_get<br />
putStrLn answer<br />
</haskell><br />
<br />
The most popular way of comprehending this program is by inlining<br />
(whether the compiler does or not is an orthogonal issue):<br />
<br />
<haskell><br />
main = do<br />
answer <- do<br />
unused <- getLine<br />
getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
and applying associativity so you can pretend it is<br />
<br />
<haskell><br />
main = do<br />
unused <- getLine<br />
answer <- getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
The associativity law is amazingly pervasive: you have always assumed it, and you<br />
have never noticed it.<br />
<br />
Whether compilers exploit the laws or not, you still want the laws for<br />
your own sake, just so you can avoid pulling your hair for<br />
counter-intuitive program behaviour that brittlely depends on how many<br />
redundant "return"s you insert or how you nest your do-blocks.<br />
<br />
== But it doesn't look exactly like an "associative law"... ==<br />
<br />
Not in this form, no. To see precisely why they're called "identity laws" and an "associative law", you have to change your notation slightly.<br />
<br />
The monad composition operator (also known as the Kleisli composition operator) is defined in Control.Monad:<br />
<br />
<haskell><br />
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c<br />
(m >=> n) x = do<br />
y <- m x<br />
n y<br />
</haskell><br />
<br />
Using this operator, the three laws can be expressed like this:<br />
<br />
{|<br />
| '''Left identity:'''<br />
| <haskell> return >=> g </haskell><br />
| ≡<br />
| <haskell> g </haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell> f >=> return </haskell><br />
| ≡<br />
| <haskell> f </haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell> (f >=> g) >=> h </haskell><br />
| ≡<br />
| <haskell> f >=> (g >=> h) </haskell><br />
|}<br />
<br />
It's now easy to see that monad composition is an associative operator with left and right identities.<br />
<br />
This is a very important way to express the three monad laws, because they are precisely the laws that are required for monads to form a mathematical [[Category theory|category]]. So the monad laws can be summarised in convenient Haiku form:<br />
<br />
:Monad axioms:<br />
:Kleisli composition forms<br />
:a category.<br />
<br />
[[Category:Standard_classes]]<br />
[[Category:Monad]]</div>Tweyhttps://wiki.haskell.org/index.php?title=Monad_laws&diff=45166Monad laws2012-04-05T17:52:31Z<p>Twey: Made layout more prominent.</p>
<hr />
<div>All instances of the [[Monad]] typeclass should obey the three '''monad laws''':<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell>return a >>= f</haskell><br />
| ≡<br />
| <haskell>f a</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell>m >>= return</haskell><br />
| ≡<br />
| <haskell>m</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell>(m >>= (\x -> f x)) >>= g</haskell><br />
| ≡<br />
| <haskell>m >>= (\x -> f x >>= g)</haskell><br />
|}<br />
<br />
Here, ''p'' ≡ ''q'' simply means that you can replace ''p'' with ''q'' and vice-versa, and the behaviour of your program will not change: ''p'' and ''q'' are equivalent.<br />
<br />
== What is the practical meaning of the monad laws? ==<br />
<br />
Let us re-write the laws in do-notation:<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell><br />
do<br />
x' <- return x<br />
f x'<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
f x<br />
</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell><br />
do<br />
x <- m<br />
return x<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
m<br />
</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell><br />
do<br />
y <- do<br />
x <- m<br />
f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
do<br />
y <- f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
y <- f x<br />
g y<br />
</haskell><br />
|}<br />
<br />
In this notation the laws appear as plain common-sense transformations of imperative programs.<br />
<br />
== But why should monads obey these laws? ==<br />
<br />
When we see a program written in a form on the left-hand side, we expect it to do<br />
the same thing as the corresponding right-hand side; and vice versa. And in<br />
practice, people do write like the lengthier left-hand side once in a while.<br />
First example: beginners tend to write<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
line <- getLine<br />
return line<br />
</haskell><br />
<br />
and it would really throw off both beginners and veterans if that did<br />
not act like (by right identity)<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
getLine<br />
</haskell><br />
<br />
Second example: Next, you go ahead to use skip_and_get:<br />
<br />
<haskell><br />
main = do<br />
answer <- skip_and_get<br />
putStrLn answer<br />
</haskell><br />
<br />
The most popular way of comprehending this program is by inlining<br />
(whether the compiler does or not is an orthogonal issue):<br />
<br />
<haskell><br />
main = do<br />
answer <- do<br />
unused <- getLine<br />
getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
and applying associativity so you can pretend it is<br />
<br />
<haskell><br />
main = do<br />
unused <- getLine<br />
answer <- getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
The associativity law is amazingly pervasive: you have always assumed it, and you<br />
have never noticed it.<br />
<br />
Whether compilers exploit the laws or not, you still want the laws for<br />
your own sake, just so you can avoid pulling your hair for<br />
counter-intuitive program behaviour that brittlely depends on how many<br />
redundant "return"s you insert or how you nest your do-blocks.<br />
<br />
== But it doesn't look exactly like an "associative law"... ==<br />
<br />
Not in this form, no. To see precisely why they're called "identity laws" and an "associative law", you have to change your notation slightly.<br />
<br />
The monad composition operator (also known as the Kleisli composition operator) is defined in Control.Monad:<br />
<br />
<haskell><br />
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c<br />
(m >=> n) x = do<br />
y <- m x<br />
n y<br />
</haskell><br />
<br />
Using this operator, the three laws can be expressed like this:<br />
<br />
{|<br />
| '''Left identity:'''<br />
| <haskell> return >=> g </haskell><br />
| ≡<br />
| <haskell> g </haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell> f >=> return </haskell><br />
| ≡<br />
| <haskell> f </haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell> (f >=> g) >=> h </haskell><br />
| ≡<br />
| <haskell> f >=> (g >=> h) </haskell><br />
|}<br />
<br />
It's now easy to see that monad composition is an associative operator with left and right identities.<br />
<br />
This is a very important way to express the three monad laws, because they are precisely the laws that are required for monads to form a mathematical [[Category theory|category]]. So the monad laws can be summarised in convenient Haiku form:<br />
<br />
:Monad axioms:<br />
:Kleisli composition forms<br />
:a category.<br />
<br />
[[Category:Standard_classes]]<br />
[[Category:Monad]]</div>Tweyhttps://wiki.haskell.org/index.php?title=Monad_laws&diff=45163Monad laws2012-04-05T17:36:08Z<p>Twey: Colons for consistency.</p>
<hr />
<div>All instances of the [[Monad]] typeclass should obey the three '''monad laws''':<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell>return a >>= f</haskell><br />
| ≡<br />
| <haskell>f a</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell>m >>= return</haskell><br />
| ≡<br />
| <haskell>m</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell>(m >>= (\x -> f x)) >>= g</haskell><br />
| ≡<br />
| <haskell>m >>= (\x -> f x >>= g)</haskell><br />
|}<br />
<br />
Here, ''p'' ≡ ''q'' simply means that you can replace ''p'' with ''q'' and vice-versa, and the behaviour of your program will not change: ''p'' and ''q'' are equivalent.<br />
<br />
== What is the practical meaning of the monad laws? ==<br />
<br />
Let us re-write the laws in do-notation:<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell><br />
do<br />
x' <- return x<br />
f x'<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
f x<br />
</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell><br />
do<br />
x <- m<br />
return x<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
m<br />
</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell><br />
do<br />
y <- do<br />
x <- m<br />
f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
do<br />
y <- f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
y <- f x<br />
g y<br />
</haskell><br />
|}<br />
<br />
In this notation the laws appear as plain common-sense transformations of imperative programs.<br />
<br />
== But why should monads obey these laws? ==<br />
<br />
When we see a program written in a form on the left-hand side, we expect it to do<br />
the same thing as the corresponding right-hand side; and vice versa. And in<br />
practice, people do write like the lengthier left-hand side once in a while.<br />
First example: beginners tend to write<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
line <- getLine<br />
return line<br />
</haskell><br />
<br />
and it would really throw off both beginners and veterans if that did<br />
not act like (by law #2)<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
getLine<br />
</haskell><br />
<br />
Second example: Next, you go ahead to use skip_and_get:<br />
<br />
<haskell><br />
main = do<br />
answer <- skip_and_get<br />
putStrLn answer<br />
</haskell><br />
<br />
The most popular way of comprehending this program is by inlining<br />
(whether the compiler does or not is an orthogonal issue):<br />
<br />
<haskell><br />
main = do<br />
answer <- do<br />
unused <- getLine<br />
getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
and applying law #3 so you can pretend it is<br />
<br />
<haskell><br />
main = do<br />
unused <- getLine<br />
answer <- getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
Law #3 is amazingly pervasive: you have always assumed it, and you<br />
have never noticed it.<br />
<br />
Whether compilers exploit the laws or not, you still want the laws for<br />
your own sake, just so you can avoid pulling your hair for<br />
counter-intuitive program behaviour that brittlely depends on how many<br />
redundant "return"s you insert or how you nest your do-blocks.<br />
<br />
== But it doesn't look exactly like an "associative law"... ==<br />
<br />
Not in this form, no. To see precisely why they're called "identity laws" and an "associative law", you have to change your notation slightly.<br />
<br />
The monad composition operator (also known as the Kleisli composition operator) is defined in Control.Monad:<br />
<br />
<haskell><br />
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c<br />
(m >=> n) x = do<br />
y <- m x<br />
n y<br />
</haskell><br />
<br />
Using this operator, the three laws can be expressed like this:<br />
<br />
{|<br />
| '''Left identity:'''<br />
| <haskell> return >=> g </haskell><br />
| ≡<br />
| <haskell> g </haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell> f >=> return </haskell><br />
| ≡<br />
| <haskell> f </haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell> (f >=> g) >=> h </haskell><br />
| ≡<br />
| <haskell> f >=> (g >=> h) </haskell><br />
|}<br />
<br />
It's now easy to see that monad composition is an associative operator with left and right identities.<br />
<br />
This is a very important way to express the three monad laws, because they are precisely the laws that are required for monads to form a mathematical [[Category theory|category]]. So the monad laws can be summarised in convenient Haiku form:<br />
<br />
:Monad axioms:<br />
:Kleisli composition forms<br />
:a category.<br />
<br />
[[Category:Standard_classes]]<br />
[[Category:Monad]]</div>Tweyhttps://wiki.haskell.org/index.php?title=Monad_laws&diff=45162Monad laws2012-04-05T17:35:31Z<p>Twey: Take non-Haskell outside Haskell tags, give code layout</p>
<hr />
<div>All instances of the [[Monad]] typeclass should obey the three '''monad laws''':<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell>return a >>= f</haskell><br />
| ≡<br />
| <haskell>f a</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell>m >>= return</haskell><br />
| ≡<br />
| <haskell>m</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell>(m >>= (\x -> f x)) >>= g</haskell><br />
| ≡<br />
| <haskell>m >>= (\x -> f x >>= g)</haskell><br />
|}<br />
<br />
Here, ''p'' ≡ ''q'' simply means that you can replace ''p'' with ''q'' and vice-versa, and the behaviour of your program will not change: ''p'' and ''q'' are equivalent.<br />
<br />
== What is the practical meaning of the monad laws? ==<br />
<br />
Let us re-write the laws in do-notation:<br />
<br />
{|<br />
|-<br />
| '''Left identity:'''<br />
| <haskell><br />
do<br />
x' <- return x<br />
f x'<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
f x<br />
</haskell><br />
|-<br />
| '''Right identity:'''<br />
| <haskell><br />
do<br />
x <- m<br />
return x<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
m<br />
</haskell><br />
|-<br />
| '''Associativity:'''<br />
| <haskell><br />
do<br />
y <- do<br />
x <- m<br />
f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
do<br />
y <- f x<br />
g y<br />
</haskell><br />
| ≡<br />
| <haskell><br />
do<br />
x <- m<br />
y <- f x<br />
g y<br />
</haskell><br />
|}<br />
<br />
In this notation the laws appear as plain common-sense transformations of imperative programs.<br />
<br />
== But why should monads obey these laws? ==<br />
<br />
When we see a program written in a form on the left-hand side, we expect it to do<br />
the same thing as the corresponding right-hand side; and vice versa. And in<br />
practice, people do write like the lengthier left-hand side once in a while.<br />
First example: beginners tend to write<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
line <- getLine<br />
return line<br />
</haskell><br />
<br />
and it would really throw off both beginners and veterans if that did<br />
not act like (by law #2)<br />
<br />
<haskell><br />
skip_and_get = do<br />
unused <- getLine<br />
getLine<br />
</haskell><br />
<br />
Second example: Next, you go ahead to use skip_and_get:<br />
<br />
<haskell><br />
main = do<br />
answer <- skip_and_get<br />
putStrLn answer<br />
</haskell><br />
<br />
The most popular way of comprehending this program is by inlining<br />
(whether the compiler does or not is an orthogonal issue):<br />
<br />
<haskell><br />
main = do<br />
answer <- do<br />
unused <- getLine<br />
getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
and applying law #3 so you can pretend it is<br />
<br />
<haskell><br />
main = do<br />
unused <- getLine<br />
answer <- getLine<br />
putStrLn answer<br />
</haskell><br />
<br />
Law #3 is amazingly pervasive: you have always assumed it, and you<br />
have never noticed it.<br />
<br />
Whether compilers exploit the laws or not, you still want the laws for<br />
your own sake, just so you can avoid pulling your hair for<br />
counter-intuitive program behaviour that brittlely depends on how many<br />
redundant "return"s you insert or how you nest your do-blocks.<br />
<br />
== But it doesn't look exactly like an "associative law"... ==<br />
<br />
Not in this form, no. To see precisely why they're called "identity laws" and an "associative law", you have to change your notation slightly.<br />
<br />
The monad composition operator (also known as the Kleisli composition operator) is defined in Control.Monad:<br />
<br />
<haskell><br />
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c<br />
(m >=> n) x = do<br />
y <- m x<br />
n y<br />
</haskell><br />
<br />
Using this operator, the three laws can be expressed like this:<br />
<br />
{|<br />
| '''Left identity'''<br />
| <haskell> return >=> g </haskell><br />
| ≡<br />
| <haskell> g </haskell><br />
|-<br />
| '''Right identity'''<br />
| <haskell> f >=> return </haskell><br />
| ≡<br />
| <haskell> f </haskell><br />
|-<br />
| '''Associativity'''<br />
| <haskell> (f >=> g) >=> h </haskell><br />
| ≡<br />
| <haskell> f >=> (g >=> h) </haskell><br />
|}<br />
<br />
It's now easy to see that monad composition is an associative operator with left and right identities.<br />
<br />
This is a very important way to express the three monad laws, because they are precisely the laws that are required for monads to form a mathematical [[Category theory|category]]. So the monad laws can be summarised in convenient Haiku form:<br />
<br />
:Monad axioms:<br />
:Kleisli composition forms<br />
:a category.<br />
<br />
[[Category:Standard_classes]]<br />
[[Category:Monad]]</div>Tweyhttps://wiki.haskell.org/index.php?title=User:Benmachine/New_network_package&diff=40584User:Benmachine/New network package2011-06-21T22:12:55Z<p>Twey: /* New ideas */</p>
<hr />
<div>== Origin ==<br />
<br />
This concept originally arose as "fix up the network package" to address the following perceived flaws:<br />
<br />
* [https://github.com/haskell/network/issues/8 Timeout socket options are unusable] because setSockOpt takes an Int but they want a struct timeval. This can't be worked around because the underlying C import is not exposed and anyway is imported with the wrong type.<br />
* Only <tt>Network.URI</tt> uses <tt>parsec</tt>, and most users of <tt>network</tt> probably don't use that module, so the extra dependency is probably unnecessary.<br />
* [https://github.com/haskell/network/issues/10 The strange behaviour of UnixSocket with connectTo and accept] leads me to believe that perhaps the address datatypes aren't well thought-out, as the API design allows for nonsensical requests to be made.<br />
* The API is conditionally exposed based on what symbols are or are not defined on the compilation platform: in a sense this is good because unavailable APIs are caught at compile time, but the error message you get in this case is awkward and has led to [https://github.com/haskell/network/issues/7 spurious bug reports] and confusion. It also doesn't seem possible to account for these API differences without yourself using CPP, which seems clumsy to me.<br />
* The PortNumber newtype defines a Num instance despite the fact that it really doesn't often make sense to subtract ports. It doesn't define a Read instance.<br />
<br />
The last few points especially started to suggest that a change to the existing package would probably be quite sweeping and API-breaking, so the idea mutated into "design a new network package minus the above flaws", since that was likely to be less troublesome for upgraders.<br />
<br />
== New ideas ==<br />
<br />
* Essentially a three-tiered API:<br />
** the lowest-level FFI interface to the C API, exposing foreign imports and datatypes directly, along with their Storable instances, etc.<br />
** something akin to the current Network package, that is organised to be equivalent in expressivity to the FFI interface but using more idiomatic types and signatures, and taking care of all the marshalling under the hood.<br />
** nicer Haskell wrappers around the above that capture common or encouraged usage patterns. For example, many socket options only need to be set once, when the socket is created, so we might just add a <tt>[SocketOption]</tt> (or whatever) parameter to the socket creation function. This makes things less stateful and neater. Depending on how far we want to extend this idea, we could potentially make it a separate package so that we can take advantage of a wider range of dependencies (e.g. iteratee, safer-file-handles, etc.)<br />
* Socket options:<br />
** Instead of dispatching on a SocketOption ADT, use multiple functions: instead of <hask>setSocketOption sock Debug 1</hask> we have <hask>setSocketDebug sock True</hask> or something similar.<br />
** Or how about a class-based approach?<br />
<haskell><br />
-- retrieves the Fd from the Socket and calls the foreign import<br />
setSockOptWrapper :: Socket<br />
-> CInt -- ^ level<br />
-> CInt -- ^ option name<br />
-> Ptr a -- ^ option value<br />
-> CSockLen -- ^ option size<br />
-> IO ()<br />
<br />
class SocketOption a where<br />
setSocketOption :: Socket -> a -> IO ()<br />
getSocketOption :: Socket -> IO a<br />
<br />
newtype SocketDebug = SocketDebug Bool<br />
<br />
ptrSizeOf :: Storable a => Ptr a -> Int<br />
ptrSizeOf p = sizeOf ((undefined :: Ptr a -> a) p)<br />
<br />
instance SocketOption SocketDebug where<br />
setSocketOption s (SocketDebug b) =<br />
with opt $ \ptr -><br />
setSockOptWrapper s<br />
(#const IPPROTO_TCP)<br />
(#const SO_DEBUG)<br />
(ptr :: Ptr CInt)<br />
sizeOf opt<br />
where<br />
opt :: CInt<br />
opt = if b then 1 else 0<br />
getSocketOption s = alloca $ \vp -> alloca $ \sz -> do<br />
poke sz (ptrSizeOf vp)<br />
getSockOptWrapper s<br />
(#const IPPROTO_TCP)<br />
(#const SO_DEBUG)<br />
(vp :: Ptr CInt)<br />
sz<br />
fmap (SocketDebug . (/= 0)) $ peek vp<br />
<br />
-- And maybe…<br />
<br />
data SocketOption = forall so. SocketOption so => SocketOption so<br />
<br />
setSocketOptions :: [SocketOption] -> Socket -> IO ()<br />
withSocketOptions :: [SocketOption] -> Socket -> (Socket -> IO r) -> IO r<br />
<br />
-- with safer-file-handles we could make this region-y<br />
withSocket :: Family -> SocketType -> ProtocolNumber -> [SocketOption]<br />
-> (Socket -> IO r) -> IO r<br />
<br />
-- the idea is that the type, and therefore class instance, is inferred from use of the newtype constructor:<br />
twiddleDebug :: Socket -> IO ()<br />
twiddleDebug s = do<br />
SocketDebug b <- getSocketOption s<br />
putStrLn $ "Socket debug is: " ++ show b<br />
setSocketOption s $ SocketDebug True<br />
</haskell><br />
<br />
** Both of these are more extensible with "pseudo-options" than the ADT approach, which is nice. The latter may aid encapsulation of the Socket type:<br />
<Twey> The obvious [advantage] is that SocketOption is then an open class<br />
<Twey> So you can add e.g. platform-specific options in other packages<br />
<benmachine> ...you could just write more functions? :P<br />
<Twey> Say the SocketOption class contains methods to transform it to the ints C <br />
uses<br />
<Twey> Not without knowing the internal details of the Socket type<br />
<benmachine> ah but the C API uses void*<br />
<Twey> void*, whatever<br />
<benmachine> the point being that how you translate things to void* might depend <br />
a little on which socket option it is<br />
<Twey> Yeah<br />
<benmachine> and hence can't necessarily be done in a uniform way<br />
<Twey> Which is why it's in the class<br />
<benmachine> you mean in the instance methods?<br />
<Twey> Yes<br />
<benmachine> so you're suggesting that there's a function which takes a socket <br />
and a void* and does the FFI call<br />
<benmachine> and the class instances take care of accepting an Integer and <br />
turning it into a void*<br />
<Twey> Not necessarily an Integer<br />
<Twey> Whatever argument(s) they accept<br />
<benmachine> sure<br />
<benmachine> just an example<br />
<Twey> *nod*<br />
* String and ByteString need to be given equal consideration. Whether this is done by module boundaries (as in <tt>Network.Socket.ByteString</tt>) or a type-class approach is still under discussion.<br />
** Why does String need equal consideration? It's only a legacy option.<br />
*** At least equal? :) but strings are actually quite convenient to pattern match on and stuff.<br />
**** Only for prefixes, and that case works fine with view patterns.<br />
** I think that it encourages people to think about encoding and stuff if we use a concrete ByteString type everywhere. But maybe we want to let people not think about encoding sometimes? We don't want encoding-boilerplate all over the place.<br />
*** How about abstracting Socket into a typeclass and having separate instances for encoded/raw sockets?<br />
*** Or, having a filter mechanism in the Socket type<br />
*** Or, exposing a Handle somehow and letting the clever new GHC7 IO stuff take care of it.<br />
<br />
== See also ==<br />
<br />
[http://hackage.haskell.org/package/network-fancy network-fancy on Hackage]</div>Tweyhttps://wiki.haskell.org/index.php?title=User:Benmachine/New_network_package&diff=40574User:Benmachine/New network package2011-06-21T06:45:12Z<p>Twey: /* New ideas */</p>
<hr />
<div>== Origin ==<br />
<br />
This concept originally arose as "fix up the network package" to address the following perceived flaws:<br />
<br />
* [https://github.com/haskell/network/issues/8 Timeout socket options are unusable] because setSockOpt takes an Int but they want a struct timeval. This can't be worked around because the underlying C import is not exposed and anyway is imported with the wrong type.<br />
* Only <tt>Network.URI</tt> uses <tt>parsec</tt>, and most users of <tt>network</tt> probably don't use that module, so the extra dependency is probably unnecessary.<br />
* [https://github.com/haskell/network/issues/10 The strange behaviour of UnixSocket with connectTo and accept] leads me to believe that perhaps the address datatypes aren't well thought-out, as the API design allows for nonsensical requests to be made.<br />
* The API is conditionally exposed based on what symbols are or are not defined on the compilation platform: in a sense this is good because unavailable APIs are caught at compile time, but the error message you get in this case is awkward and has led to [https://github.com/haskell/network/issues/7 spurious bug reports] and confusion. It also doesn't seem possible to account for these API differences without yourself using CPP, which seems clumsy to me.<br />
* The PortNumber newtype defines a Num instance despite the fact that it really doesn't often make sense to subtract ports. It doesn't define a Read instance.<br />
<br />
The last few points especially started to suggest that a change to the existing package would probably be quite sweeping and API-breaking, so the idea mutated into "design a new network package minus the above flaws", since that was likely to be less troublesome for upgraders.<br />
<br />
== New ideas ==<br />
<br />
* Essentially a three-tiered API:<br />
** the lowest-level FFI interface to the C API, exposing foreign imports and datatypes directly, along with their Storable instances, etc.<br />
** something akin to the current Network package, that is organised to be equivalent in expressivity to the FFI interface but using more idiomatic types and signatures, and taking care of all the marshalling under the hood.<br />
** nicer Haskell wrappers around the above that capture common or encouraged usage patterns. For example, many socket options only need to be set once, when the socket is created, so we might just add a <tt>[SocketOption]</tt> (or whatever) parameter to the socket creation function. This makes things less stateful and neater. Depending on how far we want to extend this idea, we could potentially make it a separate package so that we can take advantage of a wider range of dependencies (e.g. iteratee, safer-file-handles, etc.)<br />
* Socket options:<br />
** Instead of dispatching on a SocketOption ADT, use multiple functions: instead of <hask>setSocketOption sock Debug 1</hask> we have <hask>setSocketDebug sock True</hask> or something similar.<br />
** Or how about a class-based approach?<br />
<haskell><br />
type SockOptName = CInt<br />
type SockOptLevel = CInt -- or maybe an Enum<br />
type SockOptValue = VoidPtr<br />
type SockOptLen = CSockLen -- don't know what this is<br />
type SockOpt = (SockOptValue, SockOptLen)<br />
<br />
<br />
class SocketOption a where<br />
optionLevel :: a -> SockOptLevel<br />
optionName :: a -> SockOptName<br />
toSockOpt :: a -> SockOpt<br />
fromSockOpt :: SockOpt -> a<br />
<br />
<br />
newtype SocketDebug = SocketDebug Bool<br />
<br />
instance SocketOption SocketDebug where<br />
optionLevel _ = (#const IPPROTO_TCP)<br />
optionName _ = (#const SO_DEBUG)<br />
optionValue (SocketDebug v) = (toVoidPtr v, sizeof v)<br />
-- whatever that means<br />
fromSockOpt (v, len) = SocketDebug $ fromVoidPtr len v<br />
<br />
<br />
setSocketOption :: SocketOption so => so -> Socket -> IO ()<br />
getSocketOption :: SocketOption so => Socket -> IO so<br />
<br />
-- And maybe…<br />
<br />
newtype SocketOption = forall so. SocketOption so => SocketOption so<br />
<br />
setSocketOptions :: [SocketOption] -> Socket -> IO ()<br />
withSocketOptions :: [SocketOption] -> Socket -> (Socket -> IO r) -> IO r<br />
<br />
-- the idea is that the type, and therefore class instance, is inferred from use of the newtype constructor:<br />
twiddleDebug :: Socket -> IO ()<br />
twiddleDebug s = do<br />
SocketDebug b <- getSocketOption s<br />
putStrLn $ "Socket debug is: " ++ show b<br />
setSocketOption s $ SocketDebug True<br />
</haskell><br />
<br />
** Both of these are more extensible with "pseudo-options" than the ADT approach, which is nice. The latter may aid encapsulation of the Socket type:<br />
<Twey> Say the SocketOption class contains methods to transform it to the ints C <br />
uses<br />
<Twey> Not without knowing the internal details of the Socket type<br />
<benmachine> ah but the C API uses void*<br />
<Twey> void*, whatever<br />
<benmachine> the point being that how you translate things to void* might depend <br />
a little on which socket option it is<br />
<Twey> Yeah<br />
<benmachine> and hence can't necessarily be done in a uniform way<br />
<Twey> Which is why it's in the class<br />
<benmachine> you mean in the instance methods?<br />
<Twey> Yes<br />
<benmachine> so you're suggesting that there's a function which takes a socket <br />
and a void* and does the FFI call<br />
<benmachine> and the class instances take care of accepting an Integer and <br />
turning it into a void*<br />
<Twey> Not necessarily an Integer<br />
<Twey> Whatever argument(s) they accept<br />
<benmachine> sure<br />
<benmachine> just an example<br />
<Twey> *nod*<br />
* String and ByteString need to be given equal consideration. Whether this is done by module boundaries (as in <tt>Network.Socket.ByteString</tt>) or a type-class approach is still under discussion.<br />
** Why does String need equal consideration? It's only a legacy option.<br />
*** At least equal? :) but strings are actually quite convenient to pattern match on and stuff.<br />
** I think that it encourages people to think about encoding and stuff if we use a concrete ByteString type everywhere. But maybe we want to let people not think about encoding sometimes? We don't want encoding-boilerplate all over the place.<br />
*** How about abstracting Socket into a typeclass and having separate instances for encoded/raw sockets?<br />
*** Or, having a filter mechanism in the Socket type<br />
*** Or, exposing a Handle somehow and letting the clever new GHC7 IO stuff take care of it.<br />
<br />
== See also ==<br />
<br />
[http://hackage.haskell.org/package/network-fancy network-fancy on Hackage]</div>Tweyhttps://wiki.haskell.org/index.php?title=User:Benmachine/New_network_package&diff=40573User:Benmachine/New network package2011-06-21T06:44:30Z<p>Twey: /* New ideas */</p>
<hr />
<div>== Origin ==<br />
<br />
This concept originally arose as "fix up the network package" to address the following perceived flaws:<br />
<br />
* [https://github.com/haskell/network/issues/8 Timeout socket options are unusable] because setSockOpt takes an Int but they want a struct timeval. This can't be worked around because the underlying C import is not exposed and anyway is imported with the wrong type.<br />
* Only <tt>Network.URI</tt> uses <tt>parsec</tt>, and most users of <tt>network</tt> probably don't use that module, so the extra dependency is probably unnecessary.<br />
* [https://github.com/haskell/network/issues/10 The strange behaviour of UnixSocket with connectTo and accept] leads me to believe that perhaps the address datatypes aren't well thought-out, as the API design allows for nonsensical requests to be made.<br />
* The API is conditionally exposed based on what symbols are or are not defined on the compilation platform: in a sense this is good because unavailable APIs are caught at compile time, but the error message you get in this case is awkward and has led to [https://github.com/haskell/network/issues/7 spurious bug reports] and confusion. It also doesn't seem possible to account for these API differences without yourself using CPP, which seems clumsy to me.<br />
* The PortNumber newtype defines a Num instance despite the fact that it really doesn't often make sense to subtract ports. It doesn't define a Read instance.<br />
<br />
The last few points especially started to suggest that a change to the existing package would probably be quite sweeping and API-breaking, so the idea mutated into "design a new network package minus the above flaws", since that was likely to be less troublesome for upgraders.<br />
<br />
== New ideas ==<br />
<br />
* Essentially a three-tiered API:<br />
** the lowest-level FFI interface to the C API, exposing foreign imports and datatypes directly, along with their Storable instances, etc.<br />
** something akin to the current Network package, that is organised to be equivalent in expressivity to the FFI interface but using more idiomatic types and signatures, and taking care of all the marshalling under the hood.<br />
** nicer Haskell wrappers around the above that capture common or encouraged usage patterns. For example, many socket options only need to be set once, when the socket is created, so we might just add a <tt>[SocketOption]</tt> (or whatever) parameter to the socket creation function. This makes things less stateful and neater. Depending on how far we want to extend this idea, we could potentially make it a separate package so that we can take advantage of a wider range of dependencies (e.g. iteratee, safer-file-handles, etc.)<br />
* Socket options:<br />
** Instead of dispatching on a SocketOption ADT, use multiple functions: instead of <hask>setSocketOption sock Debug 1</hask> we have <hask>setSocketDebug sock True</hask> or something similar.<br />
** Or how about a class-based approach?<br />
<haskell><br />
type SockOptName = CInt<br />
type SockOptLevel = CInt -- or maybe an Enum<br />
type SockOptValue = VoidPtr<br />
type SockOptLen = CSockLen -- don't know what this is<br />
type SockOpt = (SockOptValue, SockOptLen)<br />
<br />
<br />
class SocketOption a where<br />
optionLevel :: a -> SockOptLevel<br />
optionName :: a -> SockOptName<br />
toSockOpt :: a -> SockOpt<br />
fromSockOpt :: SockOpt -> a<br />
<br />
<br />
newtype SocketDebug = SocketDebug Bool<br />
<br />
instance SocketOption SocketDebug where<br />
optionLevel _ = (#const IPPROTO_TCP)<br />
optionName _ = (#const SO_DEBUG)<br />
optionValue (SocketDebug v) = (toVoidPtr v,<br />
sizeof v)<br />
-- whatever that means<br />
fromSockOpt (v, len) = SocketDebug $ fromVoidPtr len v<br />
<br />
<br />
setSocketOption :: SocketOption so => so -> Socket -> IO ()<br />
getSocketOption :: SocketOption so => Socket -> IO so<br />
<br />
-- And maybe…<br />
<br />
newtype SocketOption = forall so. SocketOption so => SocketOption so<br />
<br />
setSocketOptions :: [SocketOption] -> Socket -> IO ()<br />
withSocketOptions :: [SocketOption] -> Socket -> (Socket -> IO r) -> IO r<br />
<br />
-- the idea is that the type, and therefore class instance, is inferred from use of the newtype constructor:<br />
twiddleDebug :: Socket -> IO ()<br />
twiddleDebug s = do<br />
SocketDebug b <- getSocketOption s<br />
putStrLn $ "Socket debug is: " ++ show b<br />
setSocketOption s $ SocketDebug True<br />
</haskell><br />
<br />
** Both of these are more extensible with "pseudo-options" than the ADT approach, which is nice. The latter may aid encapsulation of the Socket type:<br />
<Twey> Say the SocketOption class contains methods to transform it to the ints C <br />
uses<br />
<Twey> Not without knowing the internal details of the Socket type<br />
<benmachine> ah but the C API uses void*<br />
<Twey> void*, whatever<br />
<benmachine> the point being that how you translate things to void* might depend <br />
a little on which socket option it is<br />
<Twey> Yeah<br />
<benmachine> and hence can't necessarily be done in a uniform way<br />
<Twey> Which is why it's in the class<br />
<benmachine> you mean in the instance methods?<br />
<Twey> Yes<br />
<benmachine> so you're suggesting that there's a function which takes a socket <br />
and a void* and does the FFI call<br />
<benmachine> and the class instances take care of accepting an Integer and <br />
turning it into a void*<br />
<Twey> Not necessarily an Integer<br />
<Twey> Whatever argument(s) they accept<br />
<benmachine> sure<br />
<benmachine> just an example<br />
<Twey> *nod*<br />
* String and ByteString need to be given equal consideration. Whether this is done by module boundaries (as in <tt>Network.Socket.ByteString</tt>) or a type-class approach is still under discussion.<br />
** Why does String need equal consideration? It's only a legacy option.<br />
*** At least equal? :) but strings are actually quite convenient to pattern match on and stuff.<br />
** I think that it encourages people to think about encoding and stuff if we use a concrete ByteString type everywhere. But maybe we want to let people not think about encoding sometimes? We don't want encoding-boilerplate all over the place.<br />
*** How about abstracting Socket into a typeclass and having separate instances for encoded/raw sockets?<br />
*** Or, having a filter mechanism in the Socket type<br />
*** Or, exposing a Handle somehow and letting the clever new GHC7 IO stuff take care of it.<br />
<br />
== See also ==<br />
<br />
[http://hackage.haskell.org/package/network-fancy network-fancy on Hackage]</div>Tweyhttps://wiki.haskell.org/index.php?title=User:Benmachine/New_network_package&diff=40572User:Benmachine/New network package2011-06-21T06:42:42Z<p>Twey: /* New ideas */</p>
<hr />
<div>== Origin ==<br />
<br />
This concept originally arose as "fix up the network package" to address the following perceived flaws:<br />
<br />
* [https://github.com/haskell/network/issues/8 Timeout socket options are unusable] because setSockOpt takes an Int but they want a struct timeval. This can't be worked around because the underlying C import is not exposed and anyway is imported with the wrong type.<br />
* Only <tt>Network.URI</tt> uses <tt>parsec</tt>, and most users of <tt>network</tt> probably don't use that module, so the extra dependency is probably unnecessary.<br />
* [https://github.com/haskell/network/issues/10 The strange behaviour of UnixSocket with connectTo and accept] leads me to believe that perhaps the address datatypes aren't well thought-out, as the API design allows for nonsensical requests to be made.<br />
* The API is conditionally exposed based on what symbols are or are not defined on the compilation platform: in a sense this is good because unavailable APIs are caught at compile time, but the error message you get in this case is awkward and has led to [https://github.com/haskell/network/issues/7 spurious bug reports] and confusion. It also doesn't seem possible to account for these API differences without yourself using CPP, which seems clumsy to me.<br />
* The PortNumber newtype defines a Num instance despite the fact that it really doesn't often make sense to subtract ports. It doesn't define a Read instance.<br />
<br />
The last few points especially started to suggest that a change to the existing package would probably be quite sweeping and API-breaking, so the idea mutated into "design a new network package minus the above flaws", since that was likely to be less troublesome for upgraders.<br />
<br />
== New ideas ==<br />
<br />
* Essentially a three-tiered API:<br />
** the lowest-level FFI interface to the C API, exposing foreign imports and datatypes directly, along with their Storable instances, etc.<br />
** something akin to the current Network package, that is organised to be equivalent in expressivity to the FFI interface but using more idiomatic types and signatures, and taking care of all the marshalling under the hood.<br />
** nicer Haskell wrappers around the above that capture common or encouraged usage patterns. For example, many socket options only need to be set once, when the socket is created, so we might just add a <tt>[SocketOption]</tt> (or whatever) parameter to the socket creation function. This makes things less stateful and neater. Depending on how far we want to extend this idea, we could potentially make it a separate package so that we can take advantage of a wider range of dependencies (e.g. iteratee, safer-file-handles, etc.)<br />
* Socket options:<br />
** Instead of dispatching on a SocketOption ADT, use multiple functions: instead of <hask>setSocketOption sock Debug 1</hask> we have <hask>setSocketDebug sock True</hask> or something similar.<br />
** Or how about a class-based approach?<br />
<haskell><br />
type SockOptName = CInt<br />
type SockOptLevel = CInt -- or maybe an Enum<br />
type SockOptValue = VoidPtr<br />
type SockOptLen = CSockLen -- don't know what this is<br />
type SockOpt = (SockOptValue, SockOptLen)<br />
<br />
<br />
class SocketOption a where<br />
optionLevel :: a -> SockOptLevel<br />
optionName :: a -> SockOptName<br />
optionValue :: a -> SockOptValue<br />
fromSockOpt :: SockOpt -> a<br />
<br />
<br />
newtype SocketDebug = SocketDebug Bool<br />
<br />
instance SocketOption SocketDebug where<br />
optionLevel _ = (#const IPPROTO_TCP)<br />
optionName _ = (#const SO_DEBUG)<br />
optionValue (SocketDebug v) = (toVoidPtr v,<br />
sizeof v)<br />
-- whatever that means<br />
fromSockOpt (v, len) = SocketDebug $ fromVoidPtr len v<br />
<br />
<br />
setSocketOption :: SocketOption so => so -> Socket -> IO ()<br />
getSocketOption :: SocketOption so => Socket -> IO so<br />
<br />
-- And maybe…<br />
<br />
newtype SocketOption = forall so. SocketOption so => SocketOption so<br />
<br />
setSocketOptions :: [SocketOption] -> Socket -> IO ()<br />
withSocketOptions :: [SocketOption] -> Socket -> (Socket -> IO r) -> IO r<br />
<br />
-- the idea is that the type, and therefore class instance, is inferred from use of the newtype constructor:<br />
twiddleDebug :: Socket -> IO ()<br />
twiddleDebug s = do<br />
SocketDebug b <- getSocketOption s<br />
putStrLn $ "Socket debug is: " ++ show b<br />
setSocketOption s $ SocketDebug True<br />
</haskell><br />
<br />
** Both of these are more extensible with "pseudo-options" than the ADT approach, which is nice. The latter may aid encapsulation of the Socket type:<br />
<Twey> Say the SocketOption class contains methods to transform it to the ints C <br />
uses<br />
<Twey> Not without knowing the internal details of the Socket type<br />
<benmachine> ah but the C API uses void*<br />
<Twey> void*, whatever<br />
<benmachine> the point being that how you translate things to void* might depend <br />
a little on which socket option it is<br />
<Twey> Yeah<br />
<benmachine> and hence can't necessarily be done in a uniform way<br />
<Twey> Which is why it's in the class<br />
<benmachine> you mean in the instance methods?<br />
<Twey> Yes<br />
<benmachine> so you're suggesting that there's a function which takes a socket <br />
and a void* and does the FFI call<br />
<benmachine> and the class instances take care of accepting an Integer and <br />
turning it into a void*<br />
<Twey> Not necessarily an Integer<br />
<Twey> Whatever argument(s) they accept<br />
<benmachine> sure<br />
<benmachine> just an example<br />
<Twey> *nod*<br />
* String and ByteString need to be given equal consideration. Whether this is done by module boundaries (as in <tt>Network.Socket.ByteString</tt>) or a type-class approach is still under discussion.<br />
** Why does String need equal consideration? It's only a legacy option.<br />
*** At least equal? :) but strings are actually quite convenient to pattern match on and stuff.<br />
** I think that it encourages people to think about encoding and stuff if we use a concrete ByteString type everywhere. But maybe we want to let people not think about encoding sometimes? We don't want encoding-boilerplate all over the place.<br />
*** How about abstracting Socket into a typeclass and having separate instances for encoded/raw sockets?<br />
*** Or, having a filter mechanism in the Socket type<br />
*** Or, exposing a Handle somehow and letting the clever new GHC7 IO stuff take care of it.<br />
<br />
== See also ==<br />
<br />
[http://hackage.haskell.org/package/network-fancy network-fancy on Hackage]</div>Tweyhttps://wiki.haskell.org/index.php?title=User:Benmachine/New_network_package&diff=40562User:Benmachine/New network package2011-06-20T20:23:38Z<p>Twey: Abstract actual calling out of the class, which should just do translation; add a couple of ideas.</p>
<hr />
<div>== Origin ==<br />
<br />
This concept originally arose as "fix up the network package" to address the following perceived flaws:<br />
<br />
* [https://github.com/haskell/network/issues/8 Timeout socket options are unusable] because setSockOpt takes an Int but they want a struct timeval. This can't be worked around because the underlying C import is not exposed and anyway is imported with the wrong type.<br />
* Only <tt>Network.URI</tt> uses <tt>parsec</tt>, and most users of <tt>network</tt> probably don't use that module, so the extra dependency is probably unnecessary.<br />
* [https://github.com/haskell/network/issues/10 The strange behaviour of UnixSocket with connectTo and accept] leads me to believe that perhaps the address datatypes aren't well thought-out, as the API design allows for nonsensical requests to be made.<br />
* The API is conditionally exposed based on what symbols are or are not defined on the compilation platform: in a sense this is good because unavailable APIs are caught at compile time, but the error message you get in this case is awkward and has led to [https://github.com/haskell/network/issues/7 spurious bug reports] and confusion. It also doesn't seem possible to account for these API differences without yourself using CPP, which seems clumsy to me.<br />
* The PortNumber newtype defines a Num instance despite the fact that it really doesn't often make sense to subtract ports. It doesn't define a Read instance.<br />
<br />
The last few points especially started to suggest that a change to the existing package would probably be quite sweeping and API-breaking, so the idea mutated into "design a new network package minus the above flaws", since that was likely to be less troublesome for upgraders.<br />
<br />
== New ideas ==<br />
<br />
* Essentially a three-tiered API:<br />
** the lowest-level FFI interface to the C API, exposing foreign imports and datatypes directly, along with their Storable instances, etc.<br />
** something akin to the current Network package, that is organised to be equivalent in expressivity to the FFI interface but using more idiomatic types and signatures, and taking care of all the marshalling under the hood.<br />
** nicer Haskell wrappers around the above that capture common or encouraged usage patterns. For example, many socket options only need to be set once, when the socket is created, so we might just add a <tt>[SocketOption]</tt> (or whatever) parameter to the socket creation function. This makes things less stateful and neater. Depending on how far we want to extend this idea, we could potentially make it a separate package so that we can take advantage of a wider range of dependencies (e.g. iteratee, safer-file-handles, etc.)<br />
* Socket options:<br />
** Instead of dispatching on a SocketOption ADT, use multiple functions: instead of <hask>setSocketOption sock Debug 1</hask> we have <hask>setSocketDebug sock True</hask> or something similar.<br />
** Or how about a class-based approach?<br />
<haskell><br />
type SockOptName = CInt<br />
type SockOptLevel = CInt -- or maybe an Enum<br />
type SockOptValue = VoidPtr<br />
type SockOptLen = CSockLen -- don't know what this is<br />
type SockOpt = (SockOptValue, SockOptLen)<br />
<br />
<br />
class SocketOption a where<br />
optionLevel :: a -> SockOptLevel<br />
optionName :: a -> SockOptName<br />
optionValue :: a -> SockOptValue<br />
fromSockOpt :: SockOpt -> a<br />
<br />
<br />
newtype SocketDebug = SocketDebug Bool<br />
<br />
instance SocketOption (SocketDebug a) where<br />
optionLevel _ = (#const IPPROTO_TCP)<br />
optionName _ = (#const SO_DEBUG)<br />
optionValue (SocketDebug v) = (toVoidPtr v,<br />
sizeof v)<br />
-- whatever that means<br />
fromSockOpt (v, len) = SocketDebug $ fromVoidPtr len v<br />
<br />
<br />
setSocketOption :: SocketOption so => so -> Socket -> IO ()<br />
getSocketOption :: SocketOption so => Socket -> IO so<br />
<br />
-- And maybe…<br />
<br />
newtype SocketOption = forall so. SocketOption so => SocketOption so<br />
<br />
setSocketOptions :: [SocketOption] -> Socket -> IO ()<br />
withSocketOptions :: [SocketOption] -> Socket -> (Socket -> IO r) -> IO r<br />
<br />
-- the idea is that the type, and therefore class instance, is inferred from use of the newtype constructor:<br />
twiddleDebug :: Socket -> IO ()<br />
twiddleDebug s = do<br />
SocketDebug b <- getSocketOption s<br />
putStrLn $ "Socket debug is: " ++ show b<br />
setSocketOption s $ SocketDebug True<br />
</haskell><br />
<br />
** Both of these are more extensible with "pseudo-options" than the ADT approach, which is nice. The latter may aid encapsulation of the Socket type:<br />
<Twey> Say the SocketOption class contains methods to transform it to the ints C <br />
uses<br />
<Twey> Not without knowing the internal details of the Socket type<br />
<benmachine> ah but the C API uses void*<br />
<Twey> void*, whatever<br />
<benmachine> the point being that how you translate things to void* might depend <br />
a little on which socket option it is<br />
<Twey> Yeah<br />
<benmachine> and hence can't necessarily be done in a uniform way<br />
<Twey> Which is why it's in the class<br />
<benmachine> you mean in the instance methods?<br />
<Twey> Yes<br />
<benmachine> so you're suggesting that there's a function which takes a socket <br />
and a void* and does the FFI call<br />
<benmachine> and the class instances take care of accepting an Integer and <br />
turning it into a void*<br />
<Twey> Not necessarily an Integer<br />
<Twey> Whatever argument(s) they accept<br />
<benmachine> sure<br />
<benmachine> just an example<br />
<Twey> *nod*<br />
* String and ByteString need to be given equal consideration. Whether this is done by module boundaries (as in <tt>Network.Socket.ByteString</tt>) or a type-class approach is still under discussion.<br />
** Why does String need equal consideration? It's only a legacy option.<br />
** I think that it encourages people to think about encoding and stuff if we use a concrete ByteString type everywhere. But maybe we want to let people not think about encoding sometimes? We don't want encoding-boilerplate all over the place.<br />
*** How about abstracting Socket into a typeclass and having separate instances for encoded/raw sockets?<br />
*** Or, having a filter mechanism in the Socket type<br />
*** Or, exposing a Handle somehow and letting the clever new GHC7 IO stuff take care of it.<br />
<br />
== See also ==<br />
<br />
[http://hackage.haskell.org/package/network-fancy network-fancy on Hackage]</div>Tweyhttps://wiki.haskell.org/index.php?title=CamHac&diff=40369CamHac2011-06-04T14:36:52Z<p>Twey: /* Projects */</p>
<hr />
<div>Haskell Hackaton in Cambridge, UK, '''August 12-14, 2011'''<br />
<br />
== About ==<br />
<br />
Come and spend a weekend in Cambridge hacking Haskell code in great surroundings with fantastic company! Haskell Hackathons are a tradition where everyone is welcome; we get together, work on projects with others or just do your own thing, the overall goal being to improve the Haskell ecosystem.<br />
<br />
CamHac will be held from 12-14 August 2011, at [http://www.homertonconference.com/ Homerton College] in Cambridge. As with previous Hackathons, all are welcome -- you do not have to be a Haskell guru. All you need is a basic knowledge of Haskell, a willingness to learn, and a project you're excited to help with (or a project of your own to work on).<br />
<br />
There will be lots of hacking, good food, and, of course, fun! <br />
<br />
* Organiser: [mailto:marlowsd@gmail.com Simon Marlow] (<tt>JaffaCake</tt> on IRC)<br />
* Mailing list: [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org]<br />
* IRC channel: #ghc on FreeNode<br />
<br />
Many thanks to [http://research.microsoft.com/en-us/labs/cambridge/default.aspx Microsoft Research Cambridge] for agreeing to sponsor the event.<br />
<br />
== Registration ==<br />
<br />
'''Registration deadline''': Friday 15th July 2011<br />
<br />
Registration is free. To register, please email [mailto:msrcevnt@microsoft.com msrcevnt@microsoft.com] stating that you would like to register for the "Haskell Hackathon", with the following information<br />
<br />
Full name:<br />
Which days you are attending on:<br />
day 1: yes/no<br />
day 2: yes/no<br />
day 3: yes/no<br />
Dietary requirements:<br />
<br />
The venue is '''limited to 50 (edit: now 72!) people''', and registration is first-come first-served, so register quickly to reserve your place! (but only register if you definitely intend to come, and please let us know if you find you cannot make it for any reason after you have registered, so we can re-allocate your place).<br />
<br />
Some people will probably want to travel on Friday morning and join us later on that day - that's absolutely fine.<br />
<br />
== Venue ==<br />
<br />
We're in the [http://www.homertonconference.com/Leah-Manning.html Leah Manning Room] of [http://www.homertonconference.com/ Homerton Conference Centre]. It is about [http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 15 minutes walk from the train station], and Cambridge town centre is about 30 minutes walk.<br />
<br />
'''Times''': we have the room booked all day for the three days, and we'll probably start around 10am and finish around 6pm. Exact time details to be confirmed later. <br />
<br />
There will be WiFi access.<br />
<br />
There will be a projector for giving talks/demos. We will probably reserve a part of the time for talks and demos.<br />
<br />
== Food ==<br />
<br />
Tea and coffee will be supplied. We will have to go out to find lunch, but there are various places to eat and buy food at the [http://www.cambridge-x.co.uk Cambridge Leisure Park] a few minutes walk towards Cambridge town centre. In the evening we will probably head towards the town where there are plenty of good restaurants.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Cambridge ===<br />
<br />
==== By Plane ====<br />
<br />
* [http://www.stanstedairport.com/ Stansted Airport]: Stansted is the nearest of the London-area airports to Cambridge. It is mostly served by flights to and from mainland Europe, Ireland, and elsewhere in the UK. <br />
<br />
* [http://www.heathrowairport.com/ Heathrow Airport]: Heathrow is the principal London-area airport and one of the busiest in Europe with a wide range of national, European, and international services. <br />
<br />
* [http://www.gatwickairport.com/ Gatwick Airport]: Gatwick is the second "London" airport with a wide range of national, European and international services. <br />
<br />
* Other airports: [http://www.london-luton.co.uk/ Luton Airport], [http://www.norwichairport.co.uk/ Norwich airport], and [http://www.southendairport.com/ Southend airport] are other regional airports in the East Anglia region. If you use these, car or taxi is the best option for travel to Cambridge. <br />
<br />
==== Trains from London ====<br />
<br />
London has two train lines into Cambridge, London Kings Cross and London Liverpool Street. There is a regular service on both lines and duration is under an hour on the direct trains. Go to [http://www.nationalrail.co.uk National Rail] to check train times<br />
<br />
=== Getting to the venue ===<br />
<br />
[http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 Walk from the train station] (about 15 minutes)<br />
<br />
[http://www.homertonconference.com/How-to-find-us.html How to find the venue]<br />
<br />
'''Local Taxis''': Panther Taxis 01223 715715<br />
<br />
=== Accommodation ===<br />
<br />
[http://www.visitcambridge.org/VisitCambridge/WhereToStay.aspx VisitCambridge: Where to Stay in Cambridge]<br />
<br />
The nearest hotels to the venue seem to be:<br />
<br />
* [http://www2.travelodge.co.uk/ Travelodge] (Cambridge Central) is just a few minutes walk from the venue. It is currently charging £65.80 per night for 11-14 August.<br />
* [http://www.helenhotel.co.uk/index.htm Helen Hotel]<br />
* [http://www.bandbincambridgeshire.co.uk/ Bridge Guest House]<br />
* [http://www.cheapguesthouses.com/ Fairways Guest House]<br />
* [http://www.abbeyfieldguesthouse.com/ Abbeyfield Guest House]<br />
* [http://rockviewguesthouse.co.uk/default.aspx Rock View Guest House]<br />
* [http://alingtonhouse.com/default.aspx Alington House Guest House]<br />
* [http://www.yha.org.uk/find-accommodation/east-of-england/hostels/cambridge/index.aspx Cambridge Youth Hostel]<br />
* [http://www.cambridgerooms.co.uk/ Stay in Cambridge Colleges]<br />
<br />
If you contact any of the above and find they're booked up, please remove them from the list.<br />
<br />
Microsoft Research recommends the following hotels to visitors, these are closer to the city centre but are probably a lot more expensive than those above:<br />
<br />
* [http://www.hilton.co.uk/cambridgegardenhouse Double Tree by Hilton Garden House Cambridge]<br />
* [http://www.ichotelsgroup.com/h/d/cp/1/en/hotel/cbguk Crowne Plaza Cambridge]<br />
* [http://www.devere.co.uk/our-locations/university-arms.html De Vere University Arms]<br />
<br />
== Projects ==<br />
<br />
Use this space to list projects you are interested in working on, and add your name to projects you are interested in helping with.<br />
<br />
* General hacking away at Snap Framework (exact goals TBD), perhaps adding/improving documentation/tutorials at the same time. (Jurriën Stutterheim, Twey)<br />
* Darcs<br />
* Something games/3d related? (Stephen L)<br />
* Designing/proposing/implementing a richer or more 'haskelly' API for the network package (Ben Millwood, Twey)<br />
* Writing a library that implements the ideas of [http://web.cecs.pdx.edu/~mpj/thih/ Typing Haskell In Haskell] to type-check, say, a haskell-src-exts AST (Ben Millwood)<br />
<br />
== Attendees ==<br />
<br />
# Simon Marlow<br />
# Jurriën Stutterheim<br />
# Neil Mitchell<br />
# Jasper Van der Jeugt<br />
# Max Bolingbroke<br />
# Ben Millwood<br />
# Roman Leshchinskiy<br />
# Gregory Collins<br />
# Martijn van Steenbergen<br />
# Sjoerd Visscher<br />
# Sebastiaan Visser<br />
# Tom Lokhorst<br />
# Erik Hesselink<br />
# Jeff Foster<br />
# Sebastian Korten<br />
# Alessandro Vermeulen<br />
# Vlad Hanciuta<br />
# Ganesh Sittampalam<br />
# Eric Kow<br />
# Alexander Njemz<br />
# Mikolaj Konarski<br />
# Ian Lynagh<br />
# Andres Löh<br />
# Jeroen Janssen<br />
# Nicolas Wu<br />
# Duncan Coutts<br />
# Dominic Orchard<br />
# Jacek Generowicz<br />
# Owen Stephens<br />
# Benedict Eastaugh<br />
# Stephen Lavelle<br />
# Sam Martin<br />
# Alex Horsman<br />
# Andy Georges<br />
# Niklas Larsson<br />
# Raeez Lorgat<br />
# Maryna Strelchuk<br />
# Vincent Hanquez<br />
# Chris Done<br />
# Tomas Petricek<br />
# Thomas Schilling<br />
# Dragos Ionita<br />
# Simon Meier<br />
# Will Thompson<br />
# Sergii Strelchuk<br />
# Lennart Kolmodin<br />
# Philippa Cowderoy<br />
# Steven Keuchel<br />
# Michal Terepeta<br />
# Maciek Makowski<br />
# Johannes Weiß<br />
# Alejandro Serrano<br />
# Mike McClurg<br />
# Stefan Wehr<br />
# David Leuschner<br />
# James ‘Twey’ Kay<br />
* Add your name here, once registered...</div>Tweyhttps://wiki.haskell.org/index.php?title=CamHac&diff=40368CamHac2011-06-04T14:35:29Z<p>Twey: /* Attendees */</p>
<hr />
<div>Haskell Hackaton in Cambridge, UK, '''August 12-14, 2011'''<br />
<br />
== About ==<br />
<br />
Come and spend a weekend in Cambridge hacking Haskell code in great surroundings with fantastic company! Haskell Hackathons are a tradition where everyone is welcome; we get together, work on projects with others or just do your own thing, the overall goal being to improve the Haskell ecosystem.<br />
<br />
CamHac will be held from 12-14 August 2011, at [http://www.homertonconference.com/ Homerton College] in Cambridge. As with previous Hackathons, all are welcome -- you do not have to be a Haskell guru. All you need is a basic knowledge of Haskell, a willingness to learn, and a project you're excited to help with (or a project of your own to work on).<br />
<br />
There will be lots of hacking, good food, and, of course, fun! <br />
<br />
* Organiser: [mailto:marlowsd@gmail.com Simon Marlow] (<tt>JaffaCake</tt> on IRC)<br />
* Mailing list: [http://www.haskell.org/mailman/listinfo/hackathon hackathon@haskell.org]<br />
* IRC channel: #ghc on FreeNode<br />
<br />
Many thanks to [http://research.microsoft.com/en-us/labs/cambridge/default.aspx Microsoft Research Cambridge] for agreeing to sponsor the event.<br />
<br />
== Registration ==<br />
<br />
'''Registration deadline''': Friday 15th July 2011<br />
<br />
Registration is free. To register, please email [mailto:msrcevnt@microsoft.com msrcevnt@microsoft.com] stating that you would like to register for the "Haskell Hackathon", with the following information<br />
<br />
Full name:<br />
Which days you are attending on:<br />
day 1: yes/no<br />
day 2: yes/no<br />
day 3: yes/no<br />
Dietary requirements:<br />
<br />
The venue is '''limited to 50 (edit: now 72!) people''', and registration is first-come first-served, so register quickly to reserve your place! (but only register if you definitely intend to come, and please let us know if you find you cannot make it for any reason after you have registered, so we can re-allocate your place).<br />
<br />
Some people will probably want to travel on Friday morning and join us later on that day - that's absolutely fine.<br />
<br />
== Venue ==<br />
<br />
We're in the [http://www.homertonconference.com/Leah-Manning.html Leah Manning Room] of [http://www.homertonconference.com/ Homerton Conference Centre]. It is about [http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 15 minutes walk from the train station], and Cambridge town centre is about 30 minutes walk.<br />
<br />
'''Times''': we have the room booked all day for the three days, and we'll probably start around 10am and finish around 6pm. Exact time details to be confirmed later. <br />
<br />
There will be WiFi access.<br />
<br />
There will be a projector for giving talks/demos. We will probably reserve a part of the time for talks and demos.<br />
<br />
== Food ==<br />
<br />
Tea and coffee will be supplied. We will have to go out to find lunch, but there are various places to eat and buy food at the [http://www.cambridge-x.co.uk Cambridge Leisure Park] a few minutes walk towards Cambridge town centre. In the evening we will probably head towards the town where there are plenty of good restaurants.<br />
<br />
== Local arrangements ==<br />
<br />
=== Getting to Cambridge ===<br />
<br />
==== By Plane ====<br />
<br />
* [http://www.stanstedairport.com/ Stansted Airport]: Stansted is the nearest of the London-area airports to Cambridge. It is mostly served by flights to and from mainland Europe, Ireland, and elsewhere in the UK. <br />
<br />
* [http://www.heathrowairport.com/ Heathrow Airport]: Heathrow is the principal London-area airport and one of the busiest in Europe with a wide range of national, European, and international services. <br />
<br />
* [http://www.gatwickairport.com/ Gatwick Airport]: Gatwick is the second "London" airport with a wide range of national, European and international services. <br />
<br />
* Other airports: [http://www.london-luton.co.uk/ Luton Airport], [http://www.norwichairport.co.uk/ Norwich airport], and [http://www.southendairport.com/ Southend airport] are other regional airports in the East Anglia region. If you use these, car or taxi is the best option for travel to Cambridge. <br />
<br />
==== Trains from London ====<br />
<br />
London has two train lines into Cambridge, London Kings Cross and London Liverpool Street. There is a regular service on both lines and duration is under an hour on the direct trains. Go to [http://www.nationalrail.co.uk National Rail] to check train times<br />
<br />
=== Getting to the venue ===<br />
<br />
[http://www.google.co.uk/maps?f=d&source=s_d&saddr=United+Kingdom+(Cambridge,+Railway+Station+(Stop+B))&daddr=CB2+8PH&hl=en&geocode=FehrHAMdjhUCACHpLU_p7S-CNg%3BFc5LHAMdNhMCACmn-uB8eXrYRzFlrDhff7fJ9A&mra=iwd&dirflg=w&sll=52.190667,0.134583&sspn=0.021547,0.040598&ie=UTF8&z=16 Walk from the train station] (about 15 minutes)<br />
<br />
[http://www.homertonconference.com/How-to-find-us.html How to find the venue]<br />
<br />
'''Local Taxis''': Panther Taxis 01223 715715<br />
<br />
=== Accommodation ===<br />
<br />
[http://www.visitcambridge.org/VisitCambridge/WhereToStay.aspx VisitCambridge: Where to Stay in Cambridge]<br />
<br />
The nearest hotels to the venue seem to be:<br />
<br />
* [http://www2.travelodge.co.uk/ Travelodge] (Cambridge Central) is just a few minutes walk from the venue. It is currently charging £65.80 per night for 11-14 August.<br />
* [http://www.helenhotel.co.uk/index.htm Helen Hotel]<br />
* [http://www.bandbincambridgeshire.co.uk/ Bridge Guest House]<br />
* [http://www.cheapguesthouses.com/ Fairways Guest House]<br />
* [http://www.abbeyfieldguesthouse.com/ Abbeyfield Guest House]<br />
* [http://rockviewguesthouse.co.uk/default.aspx Rock View Guest House]<br />
* [http://alingtonhouse.com/default.aspx Alington House Guest House]<br />
* [http://www.yha.org.uk/find-accommodation/east-of-england/hostels/cambridge/index.aspx Cambridge Youth Hostel]<br />
* [http://www.cambridgerooms.co.uk/ Stay in Cambridge Colleges]<br />
<br />
If you contact any of the above and find they're booked up, please remove them from the list.<br />
<br />
Microsoft Research recommends the following hotels to visitors, these are closer to the city centre but are probably a lot more expensive than those above:<br />
<br />
* [http://www.hilton.co.uk/cambridgegardenhouse Double Tree by Hilton Garden House Cambridge]<br />
* [http://www.ichotelsgroup.com/h/d/cp/1/en/hotel/cbguk Crowne Plaza Cambridge]<br />
* [http://www.devere.co.uk/our-locations/university-arms.html De Vere University Arms]<br />
<br />
== Projects ==<br />
<br />
Use this space to list projects you are interested in working on, and add your name to projects you are interested in helping with.<br />
<br />
* General hacking away at Snap Framework (exact goals TBD), perhaps adding/improving documentation/tutorials at the same time. (Jurriën Stutterheim)<br />
* Darcs<br />
* Something games/3d related? (Stephen L)<br />
* Designing/proposing/implementing a richer or more 'haskelly' API for the network package (Ben Millwood)<br />
* Writing a library that implements the ideas of [http://web.cecs.pdx.edu/~mpj/thih/ Typing Haskell In Haskell] to type-check, say, a haskell-src-exts AST (Ben Millwood)<br />
<br />
== Attendees ==<br />
<br />
# Simon Marlow<br />
# Jurriën Stutterheim<br />
# Neil Mitchell<br />
# Jasper Van der Jeugt<br />
# Max Bolingbroke<br />
# Ben Millwood<br />
# Roman Leshchinskiy<br />
# Gregory Collins<br />
# Martijn van Steenbergen<br />
# Sjoerd Visscher<br />
# Sebastiaan Visser<br />
# Tom Lokhorst<br />
# Erik Hesselink<br />
# Jeff Foster<br />
# Sebastian Korten<br />
# Alessandro Vermeulen<br />
# Vlad Hanciuta<br />
# Ganesh Sittampalam<br />
# Eric Kow<br />
# Alexander Njemz<br />
# Mikolaj Konarski<br />
# Ian Lynagh<br />
# Andres Löh<br />
# Jeroen Janssen<br />
# Nicolas Wu<br />
# Duncan Coutts<br />
# Dominic Orchard<br />
# Jacek Generowicz<br />
# Owen Stephens<br />
# Benedict Eastaugh<br />
# Stephen Lavelle<br />
# Sam Martin<br />
# Alex Horsman<br />
# Andy Georges<br />
# Niklas Larsson<br />
# Raeez Lorgat<br />
# Maryna Strelchuk<br />
# Vincent Hanquez<br />
# Chris Done<br />
# Tomas Petricek<br />
# Thomas Schilling<br />
# Dragos Ionita<br />
# Simon Meier<br />
# Will Thompson<br />
# Sergii Strelchuk<br />
# Lennart Kolmodin<br />
# Philippa Cowderoy<br />
# Steven Keuchel<br />
# Michal Terepeta<br />
# Maciek Makowski<br />
# Johannes Weiß<br />
# Alejandro Serrano<br />
# Mike McClurg<br />
# Stefan Wehr<br />
# David Leuschner<br />
# James ‘Twey’ Kay<br />
* Add your name here, once registered...</div>Twey