Re: [Haskell-cafe] ANNOUNCE: hxournal-0.5.0.0 - A pen notetaking program written in haskell
To anyone who is interested, I just uploaded a new release of hxournal 0.6 which has pdf annotation functionality. (It's still at very early stage now though. You can think this as a tech preview release) The following is the message I posted on hxournal google group. ( http://groups.google.com/group/hxournal ) All small release announcements will be posted there. Thanks. best, IW -- Dear hxournal Users, I uploaded the new version of hxournal with pdf annotation functionality to hackage so that one can easily test the new version. The new version is accompanied with new releases of xournal-render and xournal-parser and with new package xournal-types and xournal-builder, which are data type declaration package for xournal and xournal file constructing library using blaze-builder. For installation, you just need to type cabal install hxournal This hxournal version needs poppler-0.12.* which is a part of gtk2hs. I found that the installation of poppler package is a little difficult in some system. So you may encounter some problem in installation. Later, I will make a compilation option to choose whether one will use poppler or not. Happy hxournaling then! best regards, Ian-Woo Kim On Fri, Dec 16, 2011 at 7:51 AM, Ivan Perez ivanperezdoming...@gmail.com wrote: Thanks :) It's working now. I tried it with XInput and without it. Lines seem smoother when XInput is activated. On 16 December 2011 11:33, Ian-Woo Kim ianwoo...@gmail.com wrote: Hi, all, I just uploaded hxournal-0.5.1 which is implemented with .hxournal config file, Use X Input menu enabled, and a fix for compilation problem of gdkconfig.h by Custom build during cabal configure using pkg-config --cflags gtk+-2.0 Please try the new version by cabal update cabal install hxournal I have made a google group of hxournal : hxour...@googlegroups.com Any issues on hxournal will be welcome and discussed there. Currently, I branched 0.5.1 version for stabilization and now started to focus on pdf background rendering (which is most relevant for my purpose) in the master branch. Thank you for your interest and reports. best, On Thu, Dec 15, 2011 at 4:33 PM, Edward Z. Yang ezy...@mit.edu wrote: When I attempt to build on Ubuntu, I get: ezyang@javelin:~$ cabal install hxournal Resolving dependencies... Configuring hxournal-0.5.0.0... Preprocessing library hxournal-0.5.0.0... In file included from /usr/include/gtk-2.0/gdk/gdkscreen.h:32:0, from /usr/include/gtk-2.0/gdk/gdkapplaunchcontext.h:31, from /usr/include/gtk-2.0/gdk/gdk.h:32, from /usr/include/gtk-2.0/gtk/gtk.h:32, from Device.hsc:3: /usr/include/gtk-2.0/gdk/gdktypes.h:55:23: fatal error: gdkconfig.h: No such file or directory compilation terminated. compiling dist/build/Application/HXournal/Device_hsc_make.c failed (exit code 1) command was: /usr/bin/gcc -c dist/build/Application/HXournal/Device_hsc_make.c -o dist/build/Application/HXournal/Device_hsc_make.o -fno-stack-protector -fno-stack-protector -Wl,--hash-style=both,--no-copy-dt-needed-entries,--as-needed -D__GLASGOW_HASKELL__=700 -Dlinux_BUILD_OS -Dlinux_HOST_OS -Di386_BUILD_ARCH -Di386_HOST_ARCH -Icsrc -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/libdrm -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/lib/ghc-7.0.3/process-1.0.1.5/include -I/usr/lib/ghc-7.0.3/directory-1.1.0.0/include -I/usr/lib/ghc-7.0.3/old-time-1.0.0.6/include -I/usr/lib/ghc-7.0.3/unix-2.4.2.0/include -I/usr/lib/ghc-7.0.3/time-1.2.0.3/include -I/usr/lib/ghc-7.0.3/bytestring-0.9.1.10/include -I/usr/lib/ghc-7.0.3/base-4.3.1.0/include -I/usr/lib/ghc-7.0.3/include -I/usr/lib/ghc-7.0.3/include/ cabal: Error: some packages failed to install: hxournal-0.5.0.0 failed during the building phase. The exception was: ExitFailure 1 This may be of interest: ezyang@javelin:~$ locate gdkconfig.h /home/ezyang/Dev/gtk+/gdk/gdkconfig.h.win32 /usr/include/gtk-3.0/gdk/gdkconfig.h /usr/lib/i386-linux-gnu/gtk-2.0/include/gdkconfig.h Edward Excerpts from Edward Z. Yang's message of Mon Dec 12 20:10:19 -0500 2011: Very fancy! I am a big fan of Xournal, so I will have to take this for a spin.
Re: [Haskell-cafe] ANNOUNCE: Anansi 0.4.2 (literate programming pre-processor)
On Tue, Dec 13, 2011 at 12:36:44PM -0800, John Millikin wrote: On Tue, Dec 13, 2011 at 03:39, Magnus Therning mag...@therning.org wrote: 1. What to call files? I understand (C)WEB suggests using .w, and that noweb uses .nw, what should I call anansi files? I usually use .anansi, but it doesn't matter. You can use whatever extensions you like, or even none at all. I'll stick to .anansi as well then, it's rather descriptive :-) 2. Combining anansi and pandoc works quite well for HTML, but it fails miserably when trying to use the generated LaTeX: markdown2pdf: ! LaTeX Error: Command \guillemotleft unavailable in encoding OT1. Is there any good way to get around that? The LaTeX loom is designed to output basic markup that can be turned into a PDF with minimum fuss. It probably won't work as-is for more advanced cases, such as when a user wants to use custom templates, or has to inter-operate with pseudo-LaTeX parsers like Pandoc. I was probably unclear, I *really* would like to use the markdown loom and then pass the weave through pandoc to be able to create html/latex from the same source. So I suspect the problem I ran into is more related to pandoc than anansi, but I was hoping that someone among the anansi users had run into and solved it already :-) You could try copying the LaTeX loom into your own code, modifying it to generate the custom output format you want, and then running it as a #!runhaskell script. I might try that, but then use the markdown loom as the basis instead. It would be nice to have a specific pandoc loom that makes use of its extensions to markdown, where that makes sense. 3. Is there any editor support for anansi, syntax highlihgting etc? Not that I know of. Note that Anansi's syntax itself is very minimal, so what you need is an editor that can support formatting a file using multiple syntaxes. I don't know enough about editor modification to figure out which editors support such a feature, or how to enable it. It's rather easy to do in vim, e.g. by setting the filetype to something line 'markdown.haskell'. I haven't tried putting together three filetypes, but I suspect it just works :-) If I get around to putting together an anansi syntax file for vim I'll make sure to share it. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: mag...@therning.org jabber: mag...@therning.org twitter: magthe http://therning.org/magnus Perl is another example of filling a tiny, short-term need, and then being a real problem in the longer term. -- Alan Kay pgpiZL3X6TwAu.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] How hard is it to start a web startup using Haskell?
Hi all, The question 'How hard is it to start a technical startup with Haskell?' happened a couple of times on this list. Sometimes it was in the form 'How hard is to find Haskell programmers?' or 'Are there any Haskell jobs?'. I'd like to provide one data point as an answer: http://www.reddit.com/r/haskell/comments/ngbbp/haskell_only_esigning_startup_closes_second_angel/ Full disclosure: I'm one of two that founded this startup. How are others doing businesses using Haskell doing these days? -- Gracjan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How hard is it to start a web startup using Haskell?
The question 'How hard is it to start a technical startup with Haskell?' happened a couple of times on this list. Sometimes it was in the form 'How hard is to find Haskell programmers?' or 'Are there any Haskell jobs?'. I'd like to provide one data point as an answer: http://www.reddit.com/r/haskell/comments/ngbbp/haskell_only_esigning_startup_closes_second_angel/ Hi Gracjan, here is Bryan O' Sullivan's Running a Startup on Haskell in case you haven't seen it: http://www.infoq.com/presentations/Running-a-Startup-on-Haskell ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How hard is it to start a web startup using Haskell?
On Sun, Dec 18, 2011 at 6:57 PM, Gracjan Polak gracjanpo...@gmail.com wrote: Hi all, The question 'How hard is it to start a technical startup with Haskell?' happened a couple of times on this list. Sometimes it was in the form 'How hard is to find Haskell programmers?' or 'Are there any Haskell jobs?'. I'd like to provide one data point as an answer: http://www.reddit.com/r/haskell/comments/ngbbp/haskell_only_esigning_startup_closes_second_angel/ Full disclosure: I'm one of two that founded this startup. How are others doing businesses using Haskell doing these days? I don't run a startup myself, but I know of at least three startups using Haskell for web development (through Yesod), and my company is basing its new web products on Yesod as well. I think there are plenty of highly qualified Haskell programmers out there, especially if you're willing to let someone work remotely. Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How hard is it to start a web startup using Haskell?
Bryan O' Sullivans's company and Scrive may not be relevant examples, as they employ respectively people like, well... ^^ Bryan O'Sullivan and Magnus Carlsson (the Haskeller, not the singer). So you can expect such people to do wonders. But for instance I personnaly have one or two ideas of web developement (and I'd love to carry them out using Yesod), but since I've simply been using Haskell for 2~3 years (and only as a hobby) and since the only guy I personnaly know who is the closest to a Haskeller is a friend who is beginning to read RWH. 2011/12/18 Carlos López Camey c.lo...@kmels.net The question 'How hard is it to start a technical startup with Haskell?' happened a couple of times on this list. Sometimes it was in the form 'How hard is to find Haskell programmers?' or 'Are there any Haskell jobs?'. I'd like to provide one data point as an answer: http://www.reddit.com/r/haskell/comments/ngbbp/haskell_only_esigning_startup_closes_second_angel/ Hi Gracjan, here is Bryan O' Sullivan's Running a Startup on Haskell in case you haven't seen it: http://www.infoq.com/presentations/Running-a-Startup-on-Haskell ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Adding state to a library
I have a library of functions that all take cfg parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Adding state to a library
My apologies. My last message was sent prematurely. I have a library of functions that all take a config parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = getConfig = \cfg - liftIO $ withLibrary cfg libraryF a b c d notice that I need stateF and libraryF lines, each with n parameters. Upgrading my library like this is rather tedious. I would prefer to just write something like stateF = upgrade libraryF but I can find no way to define the function upgrade in Haskell. This must be a fairly common problem. Is there a simple solution? On Sun, Dec 18, 2011 at 10:20 PM, Kevin Jardine kevinjard...@gmail.comwrote: I have a library of functions that all take cfg parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Adding state to a library
On 18 December 2011 22:26, Kevin Jardine kevinjard...@gmail.com wrote: I have a library of functions that all take a config parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. If you're not modifying the configuration, a reader monad transformer is probably enough: http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/html/Control-Monad-Trans-Reader.html#t:ReaderT You probably want to define your own monad transformer for your library: newtype MyMonad m a = M {unM :: ReaderT Config m a} deriving (Functor, Applicative, Monad, MonadTrans, MonadIO) getConfig :: MyMonad m Config getConfig = M ask I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg This can now be defined as: withLibrary :: Config - MyMonad m a - m a withLibrary cfg m = runReaderT (unM m) cfg stateF a b c d = getConfig = \cfg - liftIO $ withLibrary cfg libraryF a b c d notice that I need stateF and libraryF lines, each with n parameters. Upgrading my library like this is rather tedious. I would prefer to just write something like stateF = upgrade libraryF but I can find no way to define the function upgrade in Haskell. This must be a fairly common problem. Is there a simple solution? What do you mean by upgrading? Cheers, Bas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Announce: The Haskell Platform 2011.4
Hi guys, We're pleased to announce the release of the Haskell Platform: a single, standard Haskell distribution for everyone. Haskell Platform 2011.4 is fully supported on NixOS http://nixos.org/. Take care, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Anansi 0.4.2 (literate programming pre-processor)
On Sun, Dec 18, 2011 at 01:05:06PM +0100, Magnus Therning wrote: On Tue, Dec 13, 2011 at 12:36:44PM -0800, John Millikin wrote: On Tue, Dec 13, 2011 at 03:39, Magnus Therning mag...@therning.org wrote: 1. What to call files? I understand (C)WEB suggests using .w, and that noweb uses .nw, what should I call anansi files? I usually use .anansi, but it doesn't matter. You can use whatever extensions you like, or even none at all. I'll stick to .anansi as well then, it's rather descriptive :-) 2. Combining anansi and pandoc works quite well for HTML, but it fails miserably when trying to use the generated LaTeX: markdown2pdf: ! LaTeX Error: Command \guillemotleft unavailable in encoding OT1. Is there any good way to get around that? The LaTeX loom is designed to output basic markup that can be turned into a PDF with minimum fuss. It probably won't work as-is for more advanced cases, such as when a user wants to use custom templates, or has to inter-operate with pseudo-LaTeX parsers like Pandoc. I was probably unclear, I *really* would like to use the markdown loom and then pass the weave through pandoc to be able to create html/latex from the same source. So I suspect the problem I ran into is more related to pandoc than anansi, but I was hoping that someone among the anansi users had run into and solved it already :-) I just thought I'd mention that I've solved this particular issue now. All that was needed was to make sure that \usepackage{aeguill} was added to the generated LaTeX. Personally I did that by putting the line in a file and then use the -H argument to `markdown2pdf` which pandoc provides. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: mag...@therning.org jabber: mag...@therning.org twitter: magthe http://therning.org/magnus Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. -- Alan Kay pgpFJGRBrVTBr.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Adding state to a library
By upgrading, I meant move a function from an IO monad with a config parameter to a state monad without one. On Dec 18, 10:52 pm, Bas van Dijk v.dijk@gmail.com wrote: On 18 December 2011 22:26, Kevin Jardine kevinjard...@gmail.com wrote: I have a library of functions that all take a config parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. If you're not modifying the configuration, a reader monad transformer is probably enough: http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/... You probably want to define your own monad transformer for your library: newtype MyMonad m a = M {unM :: ReaderT Config m a} deriving (Functor, Applicative, Monad, MonadTrans, MonadIO) getConfig :: MyMonad m Config getConfig = M ask I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg This can now be defined as: withLibrary :: Config - MyMonad m a - m a withLibrary cfg m = runReaderT (unM m) cfg stateF a b c d = getConfig = \cfg - liftIO $ withLibrary cfg libraryF a b c d notice that I need stateF and libraryF lines, each with n parameters. Upgrading my library like this is rather tedious. I would prefer to just write something like stateF = upgrade libraryF but I can find no way to define the function upgrade in Haskell. This must be a fairly common problem. Is there a simple solution? What do you mean by upgrading? Cheers, Bas ___ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checker for haskell-src-exts (was: Typechecking Using GHC API)
On 17 December 2011 05:39, Gregory Crosswhite gcrosswh...@gmail.com wrote: On Dec 17, 2011, at 9:58 AM, Thomas Schilling wrote: Wll... I've gotten a little bit of a different perspective on this since working at a company with very high code quality standards (at least for new code). There is practically no observable code review happening. I'm sure Dimitrios and Simon PJ review most of each other's code every now and then, but overall there is very little code review happening (and no formal, recorded code review whatsoever). Cleaning up the GHC code base is a huge task -- it uses lots of dirty tricks (global variables, hash tables, unique generation is non-deterministic, ...) which often complicate efforts tremendously (I tried). The lack of a unit tests doesn't help (just rewriting code so that it can be tested would help quite a bit). So in other words, would it be helpful it we recruited GHC janitors? That is, similar to how we have the Trac which gives people bug reports to pick out and work on, would it make sense to have a Trac or some other process which gives people chunks of code to clean up and/or make easier to test? (I am of course inspired in suggesting this by the Linux kernel janitors, though it doesn't look like the project has survived, and maybe that portends ill for trying to do the same for GHC...) I'm not sure that would work too well. GHC is a bit daunting to start with (it gets better after a while) and just cleaning up after other people is little fun. I would be more interested in setting up a process that enables a clean code base (and gradually cleans up existing shortcomings). Of course, I'd prefer to do rather than talk, so I'm not pushing this at this time. At the moment, I think we should: 1. Find a plan to get rid of the existing bigger design issues, namely: the use of global variables for static flags (may require extensive refactorings throughout the codebase), the use of nondeterministic uniques for symbols (may cost performance) 2. Build up a unit test suite (may include QuickCheck properties). The idea is that if our code needs to be tested from within Haskell (and not the just the command line) then that encourages a design that can be used better as a library. It may also catch some bugs earlier and make it easier to change some things. (Note: the high-level design of GHC is indeed very modular, but the implementation isn't so much.) 3. Set up a code review system. Every commit should have to go through code review -- even by core contributors. Even experienced developers don't produce perfect code all the time. Currently, we have some post-commit review. A possible code review system for Git is Gerrit. Of course, the GHC developers would need to get on board with this. As I said, I currently don't have the time to pursue this any further, but I'm planning to apply this to my projects as much as possible. / Thomas -- Push the envelope. Watch it bend. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Thu, Dec 15, 2011 at 9:13 AM, Gregory Crosswhite gcrosswh...@gmail.comwrote: To quote Ross Paterson's proposals: instance Alternative [] where ... some [] = [] some (x:xs) = repeat (repeat x) many [] = [[]] many (x:xs) = repeat (repeat x) Isn't this instance conflating the ZipList notion and the nondeterministic list notion? • some v = (:) $ v * many v • many v = some v | pure [] Is there a motivation for writing the second law like this and not like many v = pure [] | some v other than parsers should try longest match first? Because apart from that, I find the version with flipped arguments to | more natural (base case first). Incidentally, it would lead to terminating definitions of 'some' and 'many' for lists: ghci take 5 . map (take 5) $ some [1,2] [[1],[1,1],[1,1,1],[1,1,1,1],[1,1,1,1,1]] ghci take 5 . map (take 5) $ many [1,2] [[],[1],[1,1],[1,1,1],[1,1,1,1]] Sebastian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On 17/12/2011, at 3:35 PM, Matthew Farkas-Dyck wrote: On 15/12/2011, Gregory Crosswhite gcrosswh...@gmail.com wrote: 1) Documentation really needs to be improved 2) some/many cannot be physically separated from Alternative, but there *might* be an advantage to creating a subclass for them anyway purely for the sake of conveying more information about a type to users 3) Maybe and [] are sensible instances of Alternative, even if many/some often enters an infinite loop. 4) It is possible to provide special instance of many/some that satisfy the equations of many/some, with the slight disadvantage that these solutions are no longer the least solutions. Based on all of this, at this moment in time it seems to me that the most sensible way forward is to fix the documentation, tweak the definition of Alternative to no longer require the least solutions of the equations, and then to adopt the new instances for Maybe and []. Thoughts? (1) If we do (4), then the documentation ought to be adequate as-is. No. Not by a country mile. It's better than non-existent. It's better than misleading. But it's not even on the same *continent* as adequate. A lot of Haskell packages have pretty much the same level of documentation. And I didn't pay one single cent for it, so I can't scream too loudly. But let's not kid ourselves. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Sun, Dec 18, 2011 at 20:42, Richard O'Keefe o...@cs.otago.ac.nz wrote: No. Not by a country mile. It's better than non-existent. It's better than misleading. But it's not even on the same *continent* as adequate. +1 -- brandon s allbery allber...@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 12:39 PM, Brandon Allbery wrote: On Sun, Dec 18, 2011 at 20:42, Richard O'Keefe o...@cs.otago.ac.nz wrote: No. Not by a country mile. It's better than non-existent. It's better than misleading. But it's not even on the same *continent* as adequate. +1 So what do you all think about my own suggestion for the documentation? The following is the same as what I've posted before, but with some tweaks such as swapping the last two paragraphs. The Monoid instance for Maybe has the property that, for all x and y, (Just x) wins when combined (on either side) with Nothing values, and when (Just x) is combined with (Just y) then the result is (Just (x `mappend` y)). Note that the behavior of the Monoid instance of Maybe is *different* from the behavior of the MonadPlus and Alternative instance of Maybe. For the latter two typeclasses, the behavior is that when (Just x) is combined with (Just y) the x and y values themselves are not combined but rather y is discarded so (Just x) simply wins; put another way, for all x and z, we have that (Just x) `mappend` z is *always* equal to (Just x), regardless of whether z is equal to Nothing or whether it is equal to (Just y) for some y. For this reason, unlike the instance for Monoid, the instances for these MonadPlus and Alternative place no additional constraints on the type lifted into Maybe. Incidentally, for the more mathematically inclined, you may think of this as being equivalent to the standard practice of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. I welcome any feedback that you all have to offer. If some iteration of the above is considered an improvement, then I would be happy to submit a patch using whatever process someone is kind enough to point me towards. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On 19/12/2011, at 3:44 PM, Gregory Crosswhite wrote: So what do you all think about my own suggestion for the documentation? It is an improvement. Documentation for a library module needs to start by telling people what it is for. For a particular function, someone needs to know very quickly is this what I am looking for? is this the kind of thing I _should_ have been looking for? One important thing about the Monoid instance for Maybe is that There is more than one way to turn Maybe into a Monoid. One way treats Maybe a as a truncated [a] and does not depend on any properties of a, it takes mappend (Just x) _ = Just x The other requires a itself to be a Monoid, and lift's a's operations to Maybe a: mappend (Just x) (Just y) = mappend x y The latter, more interesting, case is the one implemented here. (In the same way, bounded integers like Int can be viewed as Monoids in at least 4 ways, only two of which are predefined in Data.Monoid. mempty = minBound mappend = max mempty = maxBound mappend = min are the other two. In fact these apply to anything that is Bounded and Ord.) The point is not that your proposed documentation doesn't say that, but it doesn't say that the MonadPlus reading is a *LEGITIMATE* way to view Maybe as a Monoid, which happens not to have been the one chosen; also that this possibility that the Monoid instance you WANT might not be the one you GET is to me the first thing you need to understand about it. Yes, there is a blanket warning about this, but it specifically mentions Num. Whenever it is possible for a reasonable person to want a Monoid instance and get one that is not the instance s/he wanted, it's worth highlighting in the docs. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Sun, Dec 18, 2011 at 6:44 PM, Gregory Crosswhite gcrosswh...@gmail.comwrote: On Dec 19, 2011, at 12:39 PM, Brandon Allbery wrote: On Sun, Dec 18, 2011 at 20:42, Richard O'Keefe o...@cs.otago.ac.nz wrote: No. Not by a country mile. It's better than non-existent. It's better than misleading. But it's not even on the same *continent* as adequate. +1 So what do you all think about my own suggestion for the documentation? The following is the same as what I've posted before, but with some tweaks such as swapping the last two paragraphs. The Monoid instance for Maybe has the property that, for all x and y, (Just x) wins when combined (on either side) with Nothing values, and when (Just x) is combined with (Just y) then the result is (Just (x `mappend` y)). Note that the behavior of the Monoid instance of Maybe is *different* from the behavior of the MonadPlus and Alternative instance of Maybe. For the latter two typeclasses, the behavior is that when (Just x) is combined with (Just y) the x and y values themselves are not combined but rather y is discarded so (Just x) simply wins; put another way, for all x and z, we have that (Just x) `mappend` z is *always* equal to (Just x), regardless of whether z is equal to Nothing or whether it is equal to (Just y) for some y. For this reason, unlike the instance for Monoid, the instances for these MonadPlus and Alternative place no additional constraints on the type lifted into Maybe. Incidentally, for the more mathematically inclined, you may think of this as being equivalent to the standard practice of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. I welcome any feedback that you all have to offer. If some iteration of the above is considered an improvement, then I would be happy to submit a patch using whatever process someone is kind enough to point me towards. :-) The incidental comment is significantly more clear than an English description. As somebody else has said in these threads, the problem is that syntactically equivalent but semantically distinct types have been collapsed into Maybe. That complicates the reading of the source code, since it is much harder to figure out which interpretation is intended, and so which theorems we get from the types. In other words, they are not free theorems (since those are true in any interpretation). We have to work for them. I would rather see commutative diagrams (or what amounts to the same, usage examples) that describe the behavior than a plain English description. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:03 PM, Alexander Solla wrote: The incidental comment is significantly more clear than an English description. That is only true for someone who has already seen a sentence like that one before and so can immediately pick up what it is getting at. :-) In particular, if one has never heard of a semigroup then the sentence is not very helpful. I would rather see commutative diagrams (or what amounts to the same, usage examples) that describe the behavior than a plain English description. I find it amusing that anyone would consider commutative diagram to be the same thing as usage examples for anyone other than a mathematician. :-) Nonetheless, I see your point that examples may be clearer than English, so how about: This instance satisfies the property that, for all x any y: (1) Nothing `mappend` Nothing = Nothing (2) Just x `mappend` Nothing = Just x (3) Nothing `mappend` Just y = Just y (4) Just x `mappend` Just y = Just (x `mappend` y) (Warning: Note that rule (4) for this instance is different from the case of the MonadPlus/Alternative instances where the Just y value is discarded so that Just x `mplus` Just y = Just x | Just y = Just x.) Formally, this instance performs the standard procedure of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:01 PM, Richard O'Keefe wrote: On 19/12/2011, at 3:44 PM, Gregory Crosswhite wrote: So what do you all think about my own suggestion for the documentation? It is an improvement. Documentation for a library module needs to start by telling people what it is for. For a particular function, someone needs to know very quickly is this what I am looking for? is this the kind of thing I _should_ have been looking for? I agree, though really much of that kind of information should be in the Monoid typeclass rather than in the Maybe instance in particular. The point is not that your proposed documentation doesn't say that, but it doesn't say that the MonadPlus reading is a *LEGITIMATE* way to view Maybe as a Monoid, which happens not to have been the one chosen; also that this possibility that the Monoid instance you WANT might not be the one you GET is to me the first thing you need to understand about it. Yes, there is a blanket warning about this, but it specifically mentions Num. Whenever it is possible for a reasonable person to want a Monoid instance and get one that is not the instance s/he wanted, it's worth highlighting in the docs. I understand what you are getting at here, but the reason why think that the word warning needs to appear somewhere is to get users' attention long enough to let them know that this instance might break their expectations since it is inconsistent with MonadPlus and Alternative. Nonetheless, I agree that it is a good idea to let users know that the alternative behavior might be the most useful one in their own case, so how about the following (including changes listed in an earlier e-mail), which I will call Version 5: This instance satisfies the property that, for all x any y: (1) Nothing `mappend` Nothing = Nothing (2) Just x `mappend` Nothing = Just x (3) Nothing `mappend` Just y = Just y (4) Just x `mappend` Just y = Just (x `mappend` y) Put in formal terms, this instance performs the standard procedure of turning an arbitrary semigroup into a monoid by simply adding a new element to the semigroup to serve as the identity element, where in this case the identity element is the Nothing value of Maybe; unfortunately, since the base libraries do not come with a Semigroup typeclass, this process is expressed in code as lifting from the Monoid typeclass. CAVEAT: Note that rule (4) here is different from the case of the MonadPlus/Alternative instances where the Just y value is discarded so that Just x `mplus` Just y = Just x | Just y = Just x; if this is alternative behavior is what you were looking for, then try those typeclasses instead. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] PEPM12: Second Call For Participation
ACM SIGPLAN 2012 Workshop on Partial Evaluation and Program Manipulation http://www.program-transformation.org/PEPM12 January 23-24, 2012. Philadelphia, PA, USA (co-located with POPL'12) Second Call For Participation Program is now available http://www.program-transformation.org/PEPM12/Program Online registration is open at https://regmaster3.com/2012conf/POPL12/register.php Early registration deadline is December 24, 2011 The PEPM Symposium/Workshop series brings together researchers and practitioners working in the broad area of program transformation, which spans from refactoring, partial evaluation, supercompilation, fusion and other metaprogramming to model-driven development, program analyses including termination, inductive programming, program generation and applications of machine learning and probabilistic search. PEPM focuses on techniques, supporting theory, tools, and applications of the analysis and manipulation of programs. In addition to the presentations of regular research papers, the PEPM program includes tool demonstrations and `short paper' presentations of exciting if not fully polished research. PEPM has established a Best Paper award. The winner will be announced at the workshop. INVITED TALKS Compiling Math to High Performance Code Markus Pueschel (ETH Zuerich, Switzerland) http://www.inf.ethz.ch/~markusp/index.html Specification and verification of meta-programs Martin Berger (University of Sussex, UK) http://www.informatics.sussex.ac.uk/users/mfb21/ VENUE The conference is co-located with POPL and will be held at the Sheraton Society Hill Hotel in Philadelphia's historic district. For hotel rate details and booking please see the POPL webpage: http://www.cse.psu.edu/popl/12/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 1:01 PM, Richard O'Keefe wrote: Documentation for a library module needs to start by telling people what it is for. For a particular function, someone needs to know very quickly is this what I am looking for? is this the kind of thing I _should_ have been looking for? As I said before, some of this information really belongs in the Monoid typeclass itself, so here is my attempt at adding more information in this vein to the Monoid typeclass: The Monoid typeclass provides a standard interface for specifying how pairs of values of a given type can be combined to form new values of that type, as well well as an identity value for that type that when combined with any value x produces x. The Monoid class typically appears in higher-order functions that produce a list of values that need to be summarized into a single result, such as in Data.Foldable.foldMap function or the Writer monad. Formally, an instance of Monoid provides a binary associative operator with an identity element; to do this one must specify (at a minimum) the methods mempty and mappend such that they obey following properties: (*) mempty is the identity: mempty `mappend` x = x `mappend` mempty = x (*) mappend is associative: x `mappend` (y `mappend` z) = (x `mappend` y) `mappend` z Although not strictly necessary, for reasons of performance the Monoid typeclass also includes the method mconcat which combines all the elements in a list, i.e. it is a method which obeys the property (*) mconcat = foldr mappend mempty The above is the default definition of mconcat if no other is supplied, but for some times users may wish to override it when it can be performed more efficiently. Regardless, the minimal complete definition for an instance of the Monoid typeclass is mempty and mappend. For many types there are multiple equally sensible ways to combine pairs of values; for example, for the Int type one could use either addition or multiplication. In such cases where there is no single natural way to combine values, we often (though not always) define newtype wrappers for these types so that we can make it explicit which operation we are using. In the case of the Int type, for example, we define the Sum and Product newtypes and make these instances of Monoid using the corresponding mathematical operator. This additional information unfortunately makes the documentation more verbose, but the hope was to try to explain as much as possible the whys and whens of the Monoid class (to a non-mathematician audience) in addition to the whats, since as you point out often the most important part of the documentation is where it explains why something exists and when you would need it. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On 19/12/2011, at 5:46 PM, Gregory Crosswhite wrote: [improved Monoid documentation] I would go so far as to point out that mappend is a generalisation of Data.List.sum, Data.List.product, Data.List.and, and Data.List.or, where the initial value and combining rule are implied by the type. This additional information unfortunately makes the documentation more verbose, One man's more verbose is another man's less cryptic. I really don't like the emphasis on Num, as if it was a bizarre feature of Num that there's more than one Monoid reading for it. This is a *common* property of data types. For example, Sets can be seen as monoids with empty and union; and Sets with a universe can also be seen as monoids with universe and intersection. The more I think about it, the less idea I have _what_ to expect for _any_ instance of Monoid. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 3:49 PM, Richard O'Keefe wrote: On 19/12/2011, at 5:46 PM, Gregory Crosswhite wrote: [improved Monoid documentation] Thank you. :-) I would go so far as to point out that mappend is a generalisation of Data.List.sum, Data.List.product, Data.List.and, and Data.List.or, where the initial value and combining rule are implied by the type. Inspired by the idea behind your suggestion, I modified the documentation as follows: The Monoid typeclass provides a standard interface for specifying how pairs of values of a given type can be combined to form new values of that type, as well as an identity value for that type that when combined with any value x produces x. The Monoid class typically appears in higher-order functions that produce a list of values that need to be summarized into a single result, such as in Data.Foldable.foldMap function or the Writer monad. Formally, an instance of Monoid provides a binary associative operator with an identity element; to do this one must specify (at a minimum) the methods mempty and mappend such that they obey following properties: (*) mempty is the identity: mempty `mappend` x = x `mappend` mempty = x (*) mappend is associative: x `mappend` (y `mappend` z) = (x `mappend` y) `mappend` z Note that this structure is very generic; it includes addition with the identity element 0 (i.e. mappend = (+), mempty = 0), multiplication with the identity element 1 (i.e. mappend = (*), mempty = 1), list concatenation with the identity element [] (i.e. mappend = (++), mempty = []), logical and with the identity element True (i.e., mappend = (), mempty = True), logical or with the identity element False (i.e., mappend = (||), mempty = False), etc. Unfortunately, sometimes this very generality results in there being multiple equally sensible ways to define a Monoid instance for a type. For example, for numeric values addition and multiplication work equally well, and for boolean values logical and and logical or work equally well. In such cases, it is a good idea to define newtype wrappers for these types so that we can make it explicit which operation we are using. In the case of the Int type, for example, we define the Sum and Product newtypes and make these instances of Monoid using the corresponding mathematical operator; see also Any, All, First, and Last for other examples of this. Although not strictly necessary, for reasons of performance the Monoid typeclass also includes the method mconcat which combines all the elements in a list, i.e. it is a method which obeys the property (*) mconcat = foldr mappend mempty The above is the default definition of mconcat if no other is supplied, but for some times users may wish to override it when it can be performed more efficiently. Regardless, the minimal complete definition for an instance of the Monoid typeclass is mempty and mappend. This additional information unfortunately makes the documentation more verbose, One man's more verbose is another man's less cryptic. Don't get me wrong, I completely agree with you that adding more words for the sake of making a subject less cryptic is a net win. :-) There are two dangers that lurk, however. First, there needs to be lots of that makes it easy for people to skim through and pick out the specific information that they want to find out about, and in particular the information that is most important/most urgently needed needs to be placed first so that it is the first thing that reader sees. Second, if you take too long to explain a point then you risk having your reader get fatigued so that all that effort you put in to make things clear just ends up getting going in one eye and out the other. :-) I really don't like the emphasis on Num, as if it was a bizarre feature of Num that there's more than one Monoid reading for it. This is a *common* property of data types. For example, Sets can be seen as monoids with empty and union; and Sets with a universe can also be seen as monoids with universe and intersection. In the revised version above, added Booleans as another example. The more I think about it, the less idea I have _what_ to expect for _any_ instance of Monoid. This is an inherent weakness of typeclasses, and why languages like Agda use record systems where instance declarations are records that you can either pass in explicitly or import explicitly to use implicitly within a particular scope. I think, though, that for many types, though, there really is a sort of most intuitive/most natural Monoid operation. For lists and sequences, for example, I think that the most intuitive operation is concatenation, rather than say taking the intersection of the elements of the two arguments. Likewise when you are accumulating over a bunch of sets of
Re: [Haskell-cafe] [Alternative] summary of my understanding so far
On Dec 19, 2011, at 4:45 PM, Gregory Crosswhite wrote: First, there needs to be lots of [STRUCTURE] that makes it easy for people to skim through and pick out the specific information that they want to find out about [...] Grr! I have no idea why that word got dropped out, since it was kinda important... writing too many words at once puts my brain in a fog. :-) Also, just to clarify I don't necessarily mean structure as in explicit headlines so much as any kind of structure --- including implicit structure from paragraph breaks and careful choice of presentation and ordering --- that makes it easy to pick up on how a text is broken into logical parts, what each part is roughly about, and how the parts are related. Cheers, Greg___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe