[Haskell-cafe] ANN: lambdabot-4.3

2013-05-19 Thread James Cook
As discussed a couple months ago, I have assumed maintainership of Lambdabot 
and a a new release has been brewing for a while.  It has now been Hackaged as 
lambdabot-4.3.  

There are quite a few changes in this release, mainly internal.  Plugins 
written for older versions will require some fairly straightforward rewriting - 
the plugin interface is now based on a record rather than a type class, and 
makes use of some simple monad transformers to stabilize the API a bit in the 
face of future changes.  There are many things I'd like to do to continue 
modernizing it, the most significant of which being that I'd like to overhaul 
the state storage system and break it down into smaller packages.

Therefore, plugin-writers should consider this a bit of a stepping-stone 
release - in the not too distant future, another release will probably break 
the plugin API again.  If you have open-source plugins, please let me know and 
I'll feed you patches to keep up with any changes coming down the pipeline.

The most significant changes from the user's perspective are probably the 
expanded command line interface (try --help) and the changes to the eval 
plugin.  Eval now uses Safe Haskell, and accepts a much wider array of 
user-supplied code - the @let command now accepts module imports, type 
declarations, class declarations, and instances, and will add clauses to 
existing function definitions when applicable.

I apologize in advance that the documentation is still mostly in a state of 
non-existence.  If anyone runs into issues, please report them to me.  I can be 
reached through the following channels:

- github issues[1]
- e-mail, at this address
- #haskell (I'm mokus there) - I'm not often present, but pretty much always 
connected and will see and eventually respond to PRIVMSGs.

[1] https://github.com/mokus0/lambdabot/issues
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] package show needs QuickCheck2.6?

2013-03-20 Thread James Cook
The mueval build issue should be taken care of in a patch I just sent the 
maintainer which removes 'show' as a dependency.  I believe the 'show' package 
itself is currently in a maintainer-less state, but I don't mind taking it 
over.  It makes sense to do so since I am also taking over lambdabot, which 
used to contain show in the same source tree.

If there are no objections, I'll do so and probably remove the QuickCheck 
dependency entirely.  It's used in the ShowQ module, which is really a part 
of lambdabot's check plugin and should be moved to lambdabot.

-- James

On Mar 19, 2013, at 3:18 PM, Johannes Waldmann waldm...@imn.htwk-leipzig.de 
wrote:

 Hi, I noticed that compilation of mueval (recent: 0.8.2) breaks 
 because show (0.5) cannot be built: 
 it seems the type of Failure changed in QuickCheck (from 2.5 to 2.6).
 The build succeeds with --constraint 'QuickCheck2.6' .
 
 
 
 ___
 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


Re: [Haskell-cafe] Maintaining lambdabot

2013-03-20 Thread James Cook
On Mar 15, 2013, at 5:33 PM, Jason Dagit dag...@gmail.com wrote:

 I was going to start making these changes and I noticed that it doesn't 
 currently build with ghc 7.4.1 w/Haskell Platform:
 https://travis-ci.org/dagit/lambdabot/builds/5541375
 
 Do you know if the constraints on:
 regex-posix-0.95.1
 regex-compat-0.95.1
 
 Need to be what they are? Could we relax them without breaking anything?

I've relaxed those, along with many others that I think were unnecessarily 
strict, and it now builds on travis:

https://travis-ci.org/mokus0/lambdabot/builds/5674142

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-03-16 Thread James Cook
On Mar 15, 2013, at 5:33 PM, Jason Dagit dag...@gmail.com wrote:

 Do you know if the constraints on:
 regex-posix-0.95.1
 regex-compat-0.95.1
 
 Need to be what they are? Could we relax them without breaking anything?

The constraints were added recently, and I believe they were a very 
conservative estimate based on what versions were specifically present on Jan's 
machine at the time.  Almost all of them could probably be relaxed.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-03-15 Thread James Cook
On Mar 14, 2013, at 11:08 PM, Jason Dagit dag...@gmail.com wrote:

 My real reason for reviving this thread: Can I get a status update, please?

Sure.  I don't have as much time as I'd like these days for open-source 
projects, but with Jan's help the code has been cleaned up quite a bit in 
general, and a lot of old bit-rot has been fixed.  I have not specifically 
addressed security yet, but it's not as dire a situation as I think it sounded 
from my earlier remarks.

Basically, security is currently a bit DIY.  If there are any holes, they are 
probably quite subtle because there are very, very few moving parts on 
lambdabot's side.  mueval and Safe Haskell are used to enforce resource 
limitations and type-safety, respectively, but -fpackage-trust is not (yet) 
turned on.  So all packages installed on the system are available for the 
interpreted code (if imported using a command such as @let import Foo.Bar), 
as long as Safe Haskell permits.  This is the main potential security hole - 
the system may have modules installed and marked Trustworthy that the 
administrator has not explicitly decided whether to trust, and which are not, 
in fact, as safe as the author asserts.  Currently, lambdabot trusts such 
packages.  My intention is to add some commands (available only to lambdabot 
admins) or maybe a static configuration option for managing a list of packages 
to explicitly trust, with all others being untrusted.

And of course, for a production system an OS-enforced sandbox is a great idea 
no matter how secure you believe the code do be.

Aside from that caveat, I think that the code could be put on hackage today and 
I'd have few, if any, reservations about it.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-03-15 Thread James Cook
On Mar 15, 2013, at 2:45 PM, Jason Dagit dag...@gmail.com wrote:

 I haven't been following the thread closely. Is there also a github? If so, 
 where? Some of us figured out a bug fix for the quotes plugin and I'll send a 
 pull request if I get a chance.

Yep, there is[1].  I'm not sure what the specific bug is that you are referring 
to, but it's possible it doesn't exist anymore - a large part of the quotes 
plugin has been rewritten (actually outsourced to a fortune-mod clone written 
in Haskell called misfortune).  If it still does, then of course I'd be happy 
to accept a fix :)

[1] https://github.com/mokus0/lambdabot


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-02-20 Thread James Cook
On Feb 19, 2013, at 9:54 PM, Jason Dagit dag...@gmail.com wrote:

 Random thought, feel free to ignore it: Would it make sense to split 
 lambdabot up into core and contrib like is done with xmonad? Contrib could 
 contain the sillier things like bf, unlambda, show, etc and would have a 
 lower bar for contributors. Core would be the standard things and the 
 essential things.

Sounds like a good idea to me.  I could probably do that this weekend if nobody 
else does sooner.  Any opinion about whether it's better to put them in the 
same or separate actual repos?  I've tried both with different collections of 
related packages and have no strong opinion, myself.

 It seems that people don't really contribute new plugins these days but it 
 would be great if they did. For example, having a plugin for liquid types 
 would be super spiffy. Also, any plugin that helps people to reason about 
 other code (like vacuum).

I suspect there are two big reasons for that.  The biggest reason is probably 
that lambdabot has been getting long in the tooth, and the barrier to entry is 
sorting through a somewhat bit- rotted API with little to no documentation.  
That's why a lot of the work I did to clean it up for myself was API-related.

The other is that there seemed to be, for a long time, no interest in 
maintaining it.  Several years ago I did some work on fixing up some plugins, 
for example, but couldn't get a response from whoever was the current 
maintainer (I think it might have been dons, who was probably overextended at 
the time).

Hopefully the API can be further simplified and documented; if it can be 
reduced to a few well-documented core modules and a few auxiliary 
utility/helper ones, that would probably make the educational barrier to entry 
quite a bit lower, and I'm happy to maintain the repo or willing to let others 
do so, so hopefully we can reduce the social barrier too.  I don't currently 
have a lot of time to devote to hacking on it, but I try to be a responsive 
maintainer of all my projects.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-02-19 Thread James Cook
For what it's worth, I also have a fork of lambdabot[1] I've been using for 
quite a while now, which may provide a cleaner starting point.  In particular, 
it updates the plugin and command API to be (IMO) quite a bit cleaner and 
easier to use and understand.  It could probably use some attention to security 
in the eval module (I've relaxed it quite a bit because I only run it on a 
private IRC server), but it also includes a lot of fixes and updates to other 
modules.

[1] https://github.com/mokus0/lambdabot


On Feb 19, 2013, at 2:00 AM, Jan Stolarek jan.stola...@p.lodz.pl wrote:

 I'm happy to hear your approval. 
 
 I've spent some time yesterday cleaning up the code and writing down all 
 things that do not work. 
 The list I made is avaliable on github:
 
 https://github.com/killy/lambdabot/issues
 
 There are 17 open issues at the moment and I know I will not have enough time 
 to resolve all of 
 them on my own. There are a few blockers, so the current code is definitely 
 not yet suitable for 
 any kind of release.
 
 With all that said I would appreciate help of the community :-) There's a lot 
 to do and the tasks 
 vary in difficulty: from updating documentation and fixing unused imports to 
 fixing exceptions. 
 If anyone is willing to help please contact me via email or comments on 
 github.
 
 Janek
 
 P.S. The development is done in the 'upstream' branch
 
 ___
 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


Re: [Haskell-cafe] Maintaining lambdabot

2013-02-19 Thread James Cook
Sorry, I uploaded it this morning since I knew it wasn't there (it's the dice 
repo from my github account, mokus0).  Have you run cabal update in the last 
4 or 5 hours?

On Feb 19, 2013, at 2:36 PM, Jan Stolarek jan.stola...@p.lodz.pl wrote:

 Wow, this indeed looks like a nice starting point, though I can't build 
 lambdabot from your repo - 
 seems that dice package is not on Hackage. Is this the package that you rely 
 on:
 
 https://github.com/serialhex/dice ?
 
 Anyway, how would you feel about changes that I would like to make:
 - move all modules into Lambdabot. namespace
 - remove unlambda, brainfuck and show from the repo. They are on hackage, no 
 need to keep them 
 here - these packages aren't even used in the build process.
 - cleanup scripts
 - add package versions to cabal file
 
 This is mostly code refactoring.
 
 Janek
 


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Maintaining lambdabot

2013-02-19 Thread James Cook
On Feb 19, 2013, at 2:36 PM, Jan Stolarek jan.stola...@p.lodz.pl wrote:

 Anyway, how would you feel about changes that I would like to make:
 - move all modules into Lambdabot. namespace
 - remove unlambda, brainfuck and show from the repo. They are on hackage, no 
 need to keep them 
 here - these packages aren't even used in the build process.
 - cleanup scripts
 - add package versions to cabal file

I have no objections to any of these, though I would recommend as Gwern hinted 
that if related packages are to be removed that they should also be given new 
homes - I believe that the lambdabot source is currently the main home of these 
packages.

I tend to prefer not to give package version upper bounds, but that's more of a 
preference than an objection ;)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Key-Parametrized Lookup Table

2012-07-31 Thread James Cook
Another option which allows you to define your own key type is the 
dependent-map[1] package.  It requires implementing some classes for your key 
type that encode a proof that key equality entails equality of the type 
indices. If the documentation is insufficient feel free to ask me for more 
details or examples.

[1] http://hackage.haskell.org/package/dependent-map

On Jul 31, 2012, at 6:56 AM, Alexander Foremny alexanderfore...@gmail.com 
wrote:

 At first glance I noticed some problems with the vault library for my
 particular approach.
 
 Despite from being unique, Key values don't appear to carry any
 information like the Label I need. However, it might be possible to
 work around that.
 
 The more grave problem seems to be that a Key cannot be
 (de-)serialized. This might be impossible due to the type parameter a
 in Key a.
 However, it is no problem to fix the types of values to some finite 
 collection.
 
 Because of this some solution built around Dynamic seems to be more
 and more appropriate. But I'll try to investigate vault further.
 
 Regards,
 Alexander Foremny
 
 2012/7/31 Alexander Foremny alexanderfore...@gmail.com:
 Dear Michael,
 
 thank you very much for your quick and interesting response. This
 looks very much like what I want!
 
 Regards,
 Alexander Foremny
 
 2012/7/31 Michael Snoyman mich...@snoyman.com:
 On Tue, Jul 31, 2012 at 1:13 PM, Alexander Foremny
 alexanderfore...@gmail.com wrote:
 Hello list,
 
 I am currently thinking that a problem of mine would best be solved if
 there was a Map-like data structure in which the value returned is
 parametrized over the lookup type.
 
 I wonder is this makes sense and if such a data structure exists or if
 it could be created while still being well typed. I essentially want
 to statically define a scope of Key values and dynamically define a
 list of keys.
 
 -- Scope of possible keys.
 type Label = String
 data Key a where
KeyStr :: Label - Key String
KeyInt :: Label - Key Int
KeyChoice :: Label - [a] - Key a
 
 -- Some key values, to be extended at runtime.
 strKey Some String
 strKey' Another String
 intKey Some integer
 choiceKey Chose one [ a, b, c ] :: KeyChoice String
 
 Now I need a data structure to possibly associate a value to the key.
 
 data MapG = ...
 type Value a = a
 insert :: Key a - Value a - MapG Key Value - MapG Key Value
 lookup :: Key a - MapG Key Value - Maybe (Value a)
 
 I tried implementing this with multiple Map k a's. I tried adding a
 phantom type on some storage type of to implement KeyChoice as of type
 Key Int, but I ran into troubles with this approach. I wonder if
 Dynamic or Type Families could achieve this, but I am quite at a loss
 and would like to hear your opinion.
 
 I did try to search for this a bit, but I don't quite know how to
 phrase my problem. I'd like to apologize in advance if this question
 has been asked already.
 
 Regards,
 Alexander Foremny
 
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe
 
 I think you might be looking for something like vault[1].
 
 HTH,
 Michael
 
 [1] http://hackage.haskell.org/package/vault
 
 ___
 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


Re: [Haskell-cafe] lambdabot-4.2.3.3

2012-07-18 Thread James Cook
For what it's worth, I've been maintaining a fork for personal use for quite a 
while[1].  It diverged from the official version quite a while ago, but it 
builds on the latest GHC and uses Safe Haskell for the @eval module.  If 
someone happens to want to use it they are free to do so, and I'll even fix 
problems they find if it's not too much work for me, but I can't really commit 
to officially maintaining it.  Note also that one of its dependencies is not on 
Hackage (it's on the same GitHub account though).

-- James

[1] https://github.com/mokus0/lambdabot
 
On Jul 18, 2012, at 11:04 AM, Cale Gibbard wrote:

 Lambdabot doesn't have a maintainer.
 
 On 18 July 2012 08:33, Francesco Mazzoli f...@mazzo.li wrote:
 At Wed, 18 Jul 2012 15:14:47 +0400,
 Dmitry Malikov wrote:
 A few days ago I tried to install lambdabot package from hackage
 (4.2.3.2). Cabal install failed.
 
 Then I found DanBurton's github repo with some approaches to make lambdabot
 install fixed.
 
 All dependency packages (IOSpec, numbers) was already fixed.
 
 So I add FlexibleInstances extension to cabal file and upload package to
 hackage.
 
 I hope that did everything right.
 
 Did you ask the maintainer first? You should never just upload a package that
 you are not maintaining before asking first the maintainer and then 
 haskell-cafe
 if you receive no response. If you did not ask, please do not do that again 
 and
 tell the maintainer - which in this case you should have no problem 
 contacting,
 since Cale is often online on IRC.
 
 --
 Francesco * Often in error, never in doubt
 
 ___
 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 mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] lambdabot-4.2.3.3

2012-07-18 Thread James Cook
The irc server it runs on has about 10 users, all of whom I know and trust, so 
I have not tested it extensively but it should be as safe as anything else 
running Safe Haskell. Mueval uses the ghc API and with a minor modification can 
do so in safe mode. As long as you don't trust any packages you shouldn't, it 
should be fine.  This sort of thing is why safe Haskell exists.

On Jul 18, 2012, at 11:17 AM, Gwern Branwen gwe...@gmail.com wrote:

 On Wed, Jul 18, 2012 at 11:12 AM, James Cook mo...@deepbondi.net wrote:
 It diverged from the official version quite a while ago, but it builds on 
 the latest GHC and uses Safe Haskell for the @eval module.
 
 That doesn't sound very safe. How does it handle all the DoS attacks
 etc in the mueval test suite?
 
 -- 
 gwern
 http://www.gwern.net
 
 ___
 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


Re: [Haskell-cafe] lambdabot-4.2.3.3

2012-07-18 Thread James Cook
I should probably be more clear - it supports all the same resource limiting 
mechanisms as Mueval because it uses Mueval (modified to support Safe Haskell).

On Jul 18, 2012, at 11:37 AM, James Cook mo...@deepbondi.net wrote:

 The irc server it runs on has about 10 users, all of whom I know and trust, 
 so I have not tested it extensively but it should be as safe as anything else 
 running Safe Haskell. Mueval uses the ghc API and with a minor modification 
 can do so in safe mode. As long as you don't trust any packages you 
 shouldn't, it should be fine.  This sort of thing is why safe Haskell exists.
 
 On Jul 18, 2012, at 11:17 AM, Gwern Branwen gwe...@gmail.com wrote:
 
 On Wed, Jul 18, 2012 at 11:12 AM, James Cook mo...@deepbondi.net wrote:
 It diverged from the official version quite a while ago, but it builds on 
 the latest GHC and uses Safe Haskell for the @eval module.
 
 That doesn't sound very safe. How does it handle all the DoS attacks
 etc in the mueval test suite?
 
 -- 
 gwern
 http://www.gwern.net
 
 ___
 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 mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] XDR library ?

2012-06-08 Thread James Cook
It's not on hackage because it's not really documented or maintained, but I 
have one on github:

https://github.com/mokus0/xdr

If it's too badly bit-rotted or if there are any other problems feel free to 
let me know or send pull requests.  If it's something you'd like to see on 
hackage I can probably find the time to polish it up in the not-too-distant 
future.

-- James

On Jun 8, 2012, at 7:50 AM, ARJANEN Loïc Jean David wrote:

 Hello,
 
 I would like to know if there is an Haskell XDR library, I didn't find one on 
 Hackage.
 
 Regards,
 
 -- 
 ARJANEN Loïc Jean David
 http://luigiscorner.wordpress.com
 ---
 Computer science is no more about computers than astronomy is about 
 telescopes, biology is about microscopes, or chemistry is about beakers and 
 test tubes. Science is not about tools. It is about how we use them, and what 
 we find out when we do.
 Michael R. Fellows and Ian Parberry
 ___
 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


Re: [Haskell-cafe] Most Important GHC extensions to learn/use?

2012-06-01 Thread James Cook
On Jun 1, 2012, at 6:11 AM, Gábor Lehel wrote:

 On Fri, Jun 1, 2012 at 6:29 AM, wren ng thornton w...@freegeek.org wrote:
 
TypeFamilies (aka TFs)
These are really nifty and they're all the rage these days. In
a formal sense they're equivalent to fundeps, but in practice
they're weaker than fundeps.
 
 Is that still true? The reason used to be that we didn't have
 superclass equalities, but we do have them now since 7.2. The only
 drawbacks I know of relative to FDs are that it's sometimes more
 typing, not supported by GeneralizedNewtypeDeriving, and doesn't allow
 OverlappingInstances (ick).

In addition to other things mentioned today in the Fundeps and overlapping 
instances thread, type families have no way of defining injective type 
functions where the range includes already-existing types.

For example, if you define:

 type family Succ a

there is no way (that I've found) to define it in such a way that the compiler 
can see that Succ a ~ Succ b = a ~ b.

The equivalent in MPTCs+FDs would be:

 class Succ a b | a - b, b - a

There is more discussion of this particular weakness at 
http://hackage.haskell.org/trac/ghc/ticket/6018 .

Also, there are less-common usages of fundeps that may be translatable to type 
families but not easily, when there are complex interrelationships between type 
variables.  For example, type-level binary operations will sometimes have 
fundeps such as a b - c, a c - b, b c - a - that is to say, any two 
determines the third.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Quickest way to pass Text to C code

2012-03-21 Thread James Cook
On Mar 21, 2012, at 4:35 AM, Yves Parès wrote:

 Hello,
 
 I have to interact with a C++ library that accepts as string types (putting 
 c++ strings aside) pointers of wchar_t (CWString in Haskell) or unsigned 
 32-bit int (Ptr Word32 for UTF-32 codepoints).

The vector package has storable vectors, which are essentially raw C arrays.  
It provides the function:

Data.Vector.Storable.unsafeWith :: Storable a = Vector a - (Ptr a - 
IO b) - IO b

This is probably the simplest way to do what you're describing.  You can also 
manually allocate and poke data into raw memory using Foreign.Marshall.Alloc 
and Foreign.Storable, if you're feeling particularly masochistic ;)

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why were unfailable patterns removed and fail added to Monad?

2012-01-20 Thread James Cook
On Jan 20, 2012, at 1:40 AM, Michael Snoyman wrote:

 On Jan 20, 2012 8:31 AM, John Meacham j...@repetae.net wrote:
 
   As expected, no warnings. But if I change this unfailable code above
   to the following failable version:
  
  data MyType = Foo | Bar
  
  test myType = do
  Foo - myType
  return ()
  
   I *still* get no warnings! We didn't make sure the compiler spits out
   warnings. Instead, we guaranteed that it *never* will.
 
  This is actually the right useful behavior. using things like
 
  do
Just x - xs
Just y - ys
return (x,y)
 
  will do the right thing, failing if xs or ysresults in Nothing. for
  instance, in the list monad, it will create the cross product of the
  non Nothing members of the two lists. a parse monad may backtrack and
  try another route, the IO monad will create a useful (and
  deterministic/catchable) exception pointing to the exact file and line
  number of the pattern match. The do notation is the only place in
  haskell that allows us to hook into the pattern matching mechanism of
  the language in a general way.
 
 John
 
 I mention later that this is a feature, not a bug to some people, but I'm 
 not one of them. The convenience of having this feature is IMO far outweighed 
 by the cost of the runtime errors it can produce if you use the pattern 
 matching in the wrong monad (e.g., IO, Reader, Writer...).
 
It seems like there must be deeper reasons than stated so far for wanting to 
remove the failable concept from the spec, because all the ones given so far 
seem more like pros than cons.

For example, those runtime errors would be type errors!  And when adding 
additional constructors to a single-constructor type, it would not silently 
change the meaning in most places - it would cause type errors in places where 
the binding no longer makes sense and change the meaning in a predictable way 
(the way it does now) in places where it does make sense.  The former sounds 
fantastic to me, and the latter sounds acceptable (but a warning for those who 
don't find it acceptable would be a good idea too).

There is of course still a risk that adding a constructor can cause silent 
misbehavior in code that uses those type of bindings in monads that _are_ 
instances of MonadZero, but personally the number of times I have been bitten 
by that or heard of anyone else actually being bitten by it (i.e., zero) is a 
lot smaller than the number of times I've decided a failable binding was just 
the right concise-and-clear way to implement a parser, filter, etc.  The only 
problem I have with that style is the fact that it is not rejected in places 
where it doesn't make sense.

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why were unfailable patterns removed and fail added to Monad?

2012-01-20 Thread James Cook
Actually, that's not what this conversation is about - it's about what to with 
those types of bindings instead of the way 1.4 had been doing it.

On Jan 19, 2012, at 10:19 PM, Edward Z. Yang wrote:

 Hello Gregory,
 
 The original (1998!) conversation can be found here:
 
http://www.mail-archive.com/haskell@haskell.org/msg03002.html
 
 I think Simon Peyton-Jones' example really sums up the whole issue:
 
But [MonadZero] really sticks in my craw.  How can we explain this:
 


[MonadZero] is not the correct summary here.  (1) refers to the proposal of 
replacing the failable with refutable in the semantics, which leads to the 
weird example he then gives.


f :: Monad m = m (a,b) - m a
f m1 = do { x - m1; return (fst x) }
 
g :: MonadZero m = m (a,b) - m a
g m1 = do { (a,b) - m1; return a }
 
h :: Monad m = m (a,b) - m a
h m1 = do { ~(a,b) - m1; return a }
 
Why must g be in MonadZero?  Because the pattern (a,b) is refutable (by
bottom).
 

Again, this is the situation under a proposal where MonadZero is still inferred 
for some bindings, as in 1.4, but not for unfailable ones as 1.4 would have 
specified - for refutable ones.  All of those would count as unfailable under 
1.4 and so none would require MonadZero.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] On the purity of Haskell

2012-01-02 Thread James Cook
On Jan 2, 2012, at 1:30 PM, Conal Elliott wrote:

 On 2012/1/1 Ertugrul Söylemez e...@ertes.de wrote:
 
 And that's fine, because IO is an embedded DSL.  A better view of IO is
 a GADT like:
 
data IO :: * - * where
GetLine  :: IO String
PutStrLn :: String - IO ()
...
 
 This is still hypothetical, but it shows how even IO is easily
 referentially transparent (as long as you don't use unsafe* cheats).
 
 What?? I see how a definition like this one shows how something else that you 
 call IO can be denotative  RT. I don't see how what that conclusion has to 
 do with Haskell's IO.

Whether you say such a beast is IO or something else that you call 'IO', I 
don't see the problem with positing an open GADT of this form, new constructors 
of which are introduced by built-in magic and/or by 'foreign import', and 
letting the denotation of IO be terms in the free algebraic theory on the 
resulting signature.  It is then the job of the compiler, linker, et al, to 
implement a model of that algebraic theory in the machine language.  Foreign 
imports introduce new external names - constructors of the GADT  - and the 
linker connects those names to their implementations - giving them 
denotations as terms in the target machine's language.  Maybe I'm missing 
something but, in the presence of FFI, how can the world-interfacing portion of 
a programming language possibly be any more denotative than that?

Once you cross that threshold, I'd much rather have an operational semantics 
anyway.  Ultimately, programming a computer is about making the computer _do_ 
things.  No matter what sort of denotational semantics you come up with, I 
don't see any way to avoid it eventually bottoming out at some abstract 
representation which must then either have an operational semantics or an 
informal everyone who matters knows what that means semantics.  Eventually, 
the denotation of anything that potentially involves interaction with the real 
world must be a program in some real or imaginary machine's language.  This 
model chooses a very reasonable place to sever the infinite tower of turtles 
because it produces a language that is universal:  it is the free algebra of 
the signature specified by the GADT.

Incidentally, this model also addresses a concern I've heard voiced before that 
IO isn't demonstrably a monad.  The whole point of IO is, as I understand it, 
that it is a monad _by construction_ - specifically, it is the monad whose 
Kleisli category is the category of contexts and substitutions in the free 
algebraic theory generated on this signature.  There are even at least 2 
published implementations of this construction in Haskell - the MonadPrompt and 
operational packages - and it has been shown that it does, in fact, form a 
monad.  I would assert that if there is any sense in which the IO type 
_implementation_ fails to be a monad, it is a bug and not a flaw in the concept 
of an IO monad.

 I also wonder whether you're assuming that all of the IO primitives we have 
 in Haskell treat their non-IO arguments denotationally/extensionally, so that 
 there cannot be operations like isWHNF :: a - IO Bool.

Correct me if I'm wrong, but it appears the implication here is that [[isWHNF 
x]] /= [[isWHNF]] [[x]].  I don't think this is necessarily true though.  
Somewhere in any formal model of any language which takes the real world into 
account, there must be some translation from a denotational semantics to an 
operational one.  If the denotational semantics is not computable, that 
translation necessarily must introduce some kind of accidental extra state.  
The denotational semantics will generally include no concept of this state, so 
no denotation can mention it.  But I see no problem in there being a value in 
the denotation which is translated to an operation which does make use of this 
state.  In this model, [[isWHNF x]] is something like IsWHNF [[x]], which the 
compiler then translates into some code that, at run time, checks the progress 
of the attempt to compute the denotation of x.  At no point is there a term 
whose denotation depends on that state; instead, there is a computation which 
chooses how to proceed to do based on that state.

This does not infect the denotation with the forbidden knowledge, it only 
allows you to denote operations which are aware of the mechanism by which the 
denotation is computed.  Similarly, the operations 'peek' and 'poke' allow you 
to denote operations which may do unspeakably evil things at runtime, including 
entirely subverting that mechanism.  That doesn't mean the denotation is wrong, 
it means the machine has a back door.  Certainly it would be better, all other 
things being equal, if the translation did not open the back door like that 
but, as is so often the case, all other things are not equal.  The FFI and the 
occasional heinous performance hack are far too useful for most people to ever 
consider throwing out.

This may mean 

Re: [Haskell-cafe] Overloaded Quotes for Template Haskell

2011-12-30 Thread James Cook
One possible option would be to make a library that has all the combinators 
lifted to your more general type and use lift or runQ or something similar 
for any quotes that need lifting, along with operations from monad-control or 
monad-peel to lift quotes that also need access to the StateT layer in the 
splice.  It's a bit messier and those libraries are brain-bending at first 
(although definitely worth learning about), but it would allow you to code in 
the style you're talking about with a relatively small amount of extra 
syntactic clutter.

-- James

On Dec 29, 2011, at 9:51 PM, Michael D. Adams wrote:

 What would it take to get an -XOverloadedQuotes flag of the same
 sort as the -XOverloadedStrings flag?  I.e. [| ... |] would have
 type Quasi m = m Exp instead of Q Exp and any splices in that
 quotation expect the contents of that splice to have type m Exp.
 (Obviously, top level splices would still have type Q Exp otherwise
 the compiler wouldn't know how to evaluate the monad.)
 
 I ran into this problem when writing a Template Haskell program in
 which part of it operates in a StateT S Q a monad instead of the
 usual Q a monad.  (The S type stores the state of a memoization
 table of code fragments already generated.  Without it, the code would
 loop infinitely when processing certain recursive structures.)
 
 It is fairly easy to declare an instance of Quasi for StateT S Q,
 so in order to keep the code clean, I'd like to use quotations with
 splices in them (i.e. [| ... $( ... ) ... |] ) for expressing the
 generated code.  However, quotations and splices are tied to the Q
 monad which means that as it is now I have to manually write LamE ...
 VarP ... VarE ... etc. instead of using the much nicer quotation
 syntax.
 
 Michael D. Adams
 mdmko...@gmail.com
 
 ___
 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


Re: [Haskell-cafe] Splitting off many/some from Alternative

2011-12-14 Thread James Cook
On Dec 14, 2011, at 1:23 AM, Gregory Crosswhite wrote:

 
 On Dec 13, 2011, at 3:32 AM, Bryan O'Sullivan wrote:
 
 Don't be silly. The purpose of some and many is to be used with combinators 
 that are expected to fail sometimes. If you use them with combinators that 
 always succeed, of course you're going to get an infinite loop.
 
 Yes, but how can someone using a typeclass *know* whether a type has values 
 that will always succeed?
 

Every type with an instance of Alternative has values that always succeed, 
because Alternative extends Applicative.  some (pure foo) is questionable, if 
not meaningless, for all Alternative types.  The real distinction is whether 
there can be actions that sometimes succeed and sometimes don't.  For some 
types, such as Maybe and [], there cannot.  For other types, such as parsers, 
there can.

I don't want to get too deep into the discussion but I tend to agree that it 
would have been better if some and many had been put in their own class 
sitting on top of Alternative.  I don't know whether the pitfall is so large 
that it justifies a retroactive change, but I do know the threshold for such a 
justification can safely be a LOT lower in Haskell than in other languages.  
Change doesn't hurt nearly as much in Haskell as in, say, Ruby because the 
compiler can very easily be made to do the dirty work of rejecting code that 
hasn't been updated.

Of course it's not totally painless.  It's at least an annoyance to update 
something and find your code fails to build (or worse, your code is fine but 
code you depend on fails to build), and people will inevitably get confused by 
out-of-date tutorials, documentation for old versions of the changed package, 
etc., but when it comes to actual knowledgeable users needing to get real work 
done, it's mostly just a matter of using cabal fetch to get any broken 
upstream dependencies, edit a few lines in those packages and in your own code 
(the compiler helpfully tells you exactly which lines to edit), and continuing 
on your merry way knowing you've fixed everything the change broke.

In any case, it does sound like better documentation is in order; even for 
types that do support them sensibly, some and many definitely have pitfalls.

-- James___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Splitting off many/some from Alternative

2011-12-14 Thread James Cook
On Dec 14, 2011, at 12:37 PM, Bryan O'Sullivan wrote:

 On Tue, Dec 13, 2011 at 10:23 PM, Gregory Crosswhite gcrosswh...@gmail.com 
 wrote:
   
 This way users of the classes will know whether their type has well-defined 
 instance for some and many or not.
 
 But that's precisely what the Alternative class is already for! If you are 
 writing an Alternative instance at all, then you are asserting that it must 
 be possible and reasonable to replicate the existing behaviour of some and 
 many.

It seems reasonable to say that 'empty' and '|' are what Alternative is for, 
and 'some' and 'many' happen to be useful compositions of those for several 
(but not all) Alternatives - just like there are compositions of the Monad 
operations that don't make sense in all monads (such as forever), there are 
compositions of the Alternative operations that don't make sense for all 
Alternatives.  It just happens that some and many are important enough for 
parsing that it was felt worthwhile to put them in the class to allow 
optimizing them in some cases.

So a case could be made that, just as forever (Just 1) being nonsensical 
doesn't invalidate instance Monad Maybe, some (Just 1) being nonsensical 
doesn't invalidate instance Alternative Maybe.  And on the other hand, a case 
could be made that the importance of some and many justifies the creation 
of a subclass of Alternative where they actually are mandated to be meaningful 
rather than just definable.

 I think we should take any further discussion off-list. Your messages from 
 last night betray a deep misunderstanding that I'm not sure everyone else 
 needs to sit through :-)

Obviously I can't speak for everyone, but I enjoy reading discussions like this 
(and with a threaded mail reader, they're very easy to skip when I don't feel 
like reading them).  What seems like misunderstanding is often actually another 
person's fundamental difference of perspective, and it can be valuable to 
anyone who has skimmed the thread this far to see what, if any, common ground 
can be found.

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Where is SNMap for stable names?

2011-09-22 Thread James Cook
I may be wrong, but I think the original SNMap was a map from 'StableName's to 
the specific values they were derived from, which also (IIRC) had some weak 
referencing aspect as well.  Using them as keys for arbitrary elements of the 
phantom type is actually not type-safe, because equality of 'StableName's does 
not imply equality of types.  Here's a simple demonstration (also at [1] with 
slightly more commentary) which defines a working equivalent of 'return 
unsafeCoerce'  without directly using any unsafe function: 

 import Prelude hiding (lookup)
 
 import Data.Functor.Identity
 import System.Mem.StableName
 import System.Mem.StableName.Map
 
 unsafeCoerceIO :: IO (a - b)
 unsafeCoerceIO = do
 sn1 - makeStableName undefined
 sn2 - makeStableName undefined
 
 return $ \x -
 let m = singleton sn1 (Identity x)
 Just (Identity y) = lookup sn2 m
  in y
 
 main :: IO ()
 main = do
 unsafeCoerce - unsafeCoerceIO
 unsafeCoerce () what did you do to my argument stack?!

-- James

[1] 
https://github.com/mokus0/junkbox/blob/master/Haskell/TypeExperiments/UnsafeStableMap.hs
 

On Sep 22, 2011, at 10:50 AM, Edward Kmett wrote:

 I have a stable-maps package that provides lookup and inserting into a map 
 via stable names.
 
 -Edward
 
 On Thu, Sep 22, 2011 at 5:47 AM, Sean Leather leat...@cs.uu.nl wrote:
 There is an abstract type called SNMap for stable names referred to in [1]. 
 This has apparently disappeared from GHC a long time ago. Is it still 
 available somewhere, or is there a suitable replacement for it?
 
 Regards,
 Sean
 
 [1] Stretching the storage manager: weak pointers and stable names in 
 Haskell - http://research.microsoft.com/apps/pubs/default.aspx?id=67497
 
 ___
 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 mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why no Monoid, Num, Integral, or Floating RVarT instances?

2011-08-23 Thread James Cook
On Aug 22, 2011, at 10:17 PM, Barend Venter wrote:

 It seems like you should be able to get instances for:
 
 (Monoid m) = Monoid (RVarT n m)
 (Num m) = Num (RVarT n m)
 
 and so forth for integral and floating
 
 Just wondering if I am missing something here or if there is any
 particular thing I'm missing. I am aware you would probably not be
 able to do an Eq or Show instance but me understanding was that in the
 case of the (Num b) = Num (a - b) instance the solution was simply
 to leave those things undefined.

In the case of Monoid, it's just because nobody has ever asked for it.  I'd be 
happy to add such an instance if someone finds it useful.  In the case of Num 
and its relatives, there are many reasons I would be against including such an 
instance by default.

First, although I don't think Num has any laws mandated, a Num instance for 
RVars would break many laws people rely on in practice.  For example, most 
people tacitly assume that equalities such as x - x = 0,  x * (y + z) = x * y + 
x * z, and  2 * x = x + x all hold, at least in some approximate sense.  I 
don't believe that there is any useful sense in which those laws hold for 
RVars, or any other law that changes the number of times any subexpression 
appears.  They may hold for expected values (when they even exist) in the 
limited case of RVar, but independence can't be assumed in RVarT because the 
underlying monad will often introduce correlations between successive samples 
of the same process.

Second, and much more important, there can be no correct implementation of Show 
or Eq (or Enum, Real, Ord or toInteger for the case of Integral).  Show may not 
be a big deal since show = const RVarT isn't really wrong, just not very 
useful, and hardly any numerical algorithm is going to use Show anyway.   A 
great many algorithms operating on Num (and probably the majority of those 
operating on Integral) actually use Eq though.

Even if it were relatively rare it seems to me just plain wrong to claim that 
a type such as RVarT (or a - b, for that matter) has decidable equality when 
it does not.  In my opinion it's almost the same level of abuse as 
(unjustified) unsafePerformIO - it's lying to the type checker.  It creates 
land mines for the user - programs that will pass the type checker but fail (or 
worse, give wrong answers) at runtime due to what amounts to a type error. The 
primary purpose of static typing in the first place is to avoid exactly that 
kind of error - errors of attempting an operation on a value that doesn't 
support it.

There's nothing keeping more adventurous users from defining and using Num, 
Integral, etc., instances themselves, or even creating their own hackage 
package to introduce them, but it would take a very strong argument to convince 
me that it's a good idea to provide them by default.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] why is Random in System?

2011-08-16 Thread James Cook
On Aug 16, 2011, at 4:04 PM, Evan Laforge wrote:

 I've noticed there's a convention to put modules having to deal with
 randomness into System.Random.  I thought System was for OS
 interaction?  Granted getting a random seed usually means going to the
 OS, but isn't the rest of it, like generating random sequences,
 distributions, selecting based on probability, shuffling, etc. all
 non-OS related algorithms?
 
 I'm not sure where I would expect Random to go, perhaps Math or maybe
 the toplevel, but under System seems, well, random...
 
 I notice random-fu puts it under Data, which is also not where I'd
 look, except that you always look in Data because everything goes into
 Data... but algorithms dealing with random numbers aren't really data
 structures either, are they?

System definitely does seem like an odd choice.  In most cases the only 
interaction any PRNG, even when accessed via the FFI, has with the system is 
- as you say - to get an initial seed value for a global instance.

When I wrote random-fu I chose to use Data.Random based on the perspective is 
that a random variable or process _is_ just a mathematical object, and can be 
represented by an abstract data structure.  I'm sure there's a case to be made 
against that view too, and if someone were to present a good argument for 
something better I'd even consider changing it. It seems to me, though, that 
the line between data and not-data is pretty fuzzy in a functional language 
(which is one of the many things that makes them great), and for me it seems 
quite natural to think of random variables as data.  At least, in practice it 
feels a lot more like manipulating data than anything else.  But then I'm one 
of those weirdos who thinks of IO t as just a data structure too.

-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Fwd: C9 video in the Monadic Design Patterns for the Web series

2011-07-27 Thread James Cook
I'm always glad to see videos like this.  I wish more people could have that 
much fun playing with math ;).

It wouldn't really be suitable for your application but another interesting 
generalization is to insert the 'Either' at the top level:

 data ConwayT m a
 = Pure a
 | ConwayT
 { runLeftConwayT  :: m (ConwayT m a)
 , runRightConwayT :: m (ConwayT m a)
 } 

Using this construction, the handedness of the structure doesn't appear until 
you start implementing binary operations on games, so there is a unique monad 
structure instead of just a unique bind/join:

 instance Functor m = Monad (ConwayT m) where
 return = Pure
 Pure x = f  = f x
 ConwayT l r = f= ConwayT (fmap (= f) l) (fmap (= f) r)

but there are then (at least) two versions of every monoid structure.  Given 
that monoidal structures such as addition and multiplication are the main 
purpose of a calculator it's probably simpler in this case to just give up the 
'unit' as you chose to do.  On the other hand, if for some reason a monadic 
structure is the extent of one's interest then this version definitely 
simplifies that structure.

-- James

On Jul 27, 2011, at 4:31 AM, Greg Meredith wrote:

 Dear Haskellians,
 
 A new C9 video in the series!
 
 So, you folks already know most of this... except for maybe the 
 generalization of the Conway construction!
 
 Best wishes,
 
 --greg
 
 -- Forwarded message --
 From: Charles Torre ...
 Date: Tue, Jul 26, 2011 at 1:12 PM
 Subject: C9 video in the Monadic Design Patterns for the Web series
 To: Meredith Gregory lgreg.mered...@gmail.com
 Cc: Brian Beckman ...
 
 
 And we’re live!
 
  
 
 http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Greg-Meredith-Monadic-Design-Patterns-for-the-Web-4-of-n
 
 C
 
  
 
 From: Charles Torre 
 Sent: Tuesday, July 26, 2011 11:51 AM
 To: 'Meredith Gregory'
 Cc: Brian Beckman
 Subject: C9 video in the Monadic Design Patterns for the Web series
 
  
 
 Here it ‘tis:
 
  
 
 Greg Meredith, a mathematician and computer scientist, has graciously agreed 
 to do a C9 lecture series covering monadic design principles applied to web 
 development. You've met Greg before in a Whiteboard jam session with Brian 
 Beckman.
 
 The fundamental concept here is the monad, and Greg has a novel and 
 conceptually simplified explanation of what a monad is and why it matters. 
 This is a very important and required first step in the series since the 
 whole of it is about the application of monadic composition to real world web 
 development.
 
 In part 4, Greg primarily focuses on the idea that a monad is really an API 
 -- it's a view onto the organization of data and control structures, not 
 those structures themselves. In OO terms, it's an interface. To make this 
 point concrete Greg explores one of the simplest possible data structures 
 that supports at least two different, yet consistent interpretations of the 
 same API. The structure  used, Conway's partisan games, turned out to be 
 tailor-made for this investigation. Not only does this data structure have 
 the requisite container-like shape, it provided opportunities to see just 
 what's necessary in a container to implement the monadic interface.
 
 Running throughout the presentation is a more general comparison of reuse 
 between an OO approach versus a more functional one. When the monadic API is 
 mixed into the implementing structure we get less reuse than when the 
 implementing structure is passed as a type parameter. Finally, doing the work 
 put us in a unique position to see not just how to generalize Conway's 
 construction, monadically, but the underlying pattern which allows the 
 generalization to suggest itself.
 
 See part 1 
 See part 2
 See part 3
 
  
 
 -- 
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 7329 39th Ave SW
 Seattle, WA 98136
 
 +1 206.650.3740
 
 http://biosimilarity.blogspot.com
 
 
 
 
 -- 
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St 
 Seattle, WA 98117
 
 +1 206.650.3740
 
 http://biosimilarity.blogspot.com
 ___
 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


Re: [Haskell-cafe] Fwd: C9 video in the Monadic Design Patterns for the Web series

2011-07-27 Thread James Cook
For any who are interested, here's a quick and dirty Haskell version of the 
generalized Conway game monad transformer described in the video.  It uses two 
newtypes, L and R, to select from two possible implementations of the Monad 
class.

(all the LANGUAGE pragmas are just to support a derived Show instance to make 
it easier to play around with in GHCi - the type and monad itself are H98)

-- James


 {-# LANGUAGE StandaloneDeriving #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
 module Monads.Conway where
 
 import Control.Applicative
 import Control.Monad
 
 data ConwayT m a
 = ConwayT
 { runLeftConwayT  :: m (Either a (ConwayT m a))
 , runRightConwayT :: m (Either a (ConwayT m a))
 } 
 
 deriving instance (Eq   a, Eq   (m (Either a (ConwayT m a = Eq   
 (ConwayT m a)
 deriving instance (Ord  a, Ord  (m (Either a (ConwayT m a = Ord  
 (ConwayT m a)
 deriving instance (Read a, Read (m (Either a (ConwayT m a = Read 
 (ConwayT m a)
 deriving instance (Show a, Show (m (Either a (ConwayT m a = Show 
 (ConwayT m a)
 
 instance Functor m = Functor (ConwayT m) where
 fmap f (ConwayT l r) = ConwayT (fmap g l) (fmap g r)
 where
 g (Left  x) = Left (f x)
 g (Right x) = Right (fmap f x)
 
 bind liftS (ConwayT l r) f = ConwayT
 (liftS g l)
 (liftS g r)
 where
 g (Left  x) = Right (f x)
 g (Right x) = Right (bind liftS x f)
 
 newtype L f a = L { runL :: f a } deriving (Eq, Ord, Read, Show)
 
 instance Functor m = Functor (L (ConwayT m)) where
 fmap f (L x) = L (fmap f x)
 
 instance MonadPlus m = Monad (L (ConwayT m)) where
 return x = L (ConwayT (return (Left x)) mzero)
 L x = f   = L (bind liftM x (runL . f))
 
 newtype R f a = R { runR :: f a } deriving (Eq, Ord, Read, Show)
 
 instance Functor m = Functor (R (ConwayT m)) where
 fmap f (R x) = R (fmap f x)
 
 instance MonadPlus m = Monad (R (ConwayT m)) where
 return x = R (ConwayT (return (Left x)) mzero)
 R x = f   = R (bind liftM x (runR . f))




On Jul 27, 2011, at 4:31 AM, Greg Meredith wrote:

 Dear Haskellians,
 
 A new C9 video in the series!
 
 So, you folks already know most of this... except for maybe the 
 generalization of the Conway construction!
 
 Best wishes,
 
 --greg
 
 -- Forwarded message --
 From: Charles Torre ...
 Date: Tue, Jul 26, 2011 at 1:12 PM
 Subject: C9 video in the Monadic Design Patterns for the Web series
 To: Meredith Gregory lgreg.mered...@gmail.com
 Cc: Brian Beckman ...
 
 
 And we’re live!
 
  
 
 http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Greg-Meredith-Monadic-Design-Patterns-for-the-Web-4-of-n
 
 C
 
  
 
 From: Charles Torre 
 Sent: Tuesday, July 26, 2011 11:51 AM
 To: 'Meredith Gregory'
 Cc: Brian Beckman
 Subject: C9 video in the Monadic Design Patterns for the Web series
 
  
 
 Here it ‘tis:
 
  
 
 Greg Meredith, a mathematician and computer scientist, has graciously agreed 
 to do a C9 lecture series covering monadic design principles applied to web 
 development. You've met Greg before in a Whiteboard jam session with Brian 
 Beckman.
 
 The fundamental concept here is the monad, and Greg has a novel and 
 conceptually simplified explanation of what a monad is and why it matters. 
 This is a very important and required first step in the series since the 
 whole of it is about the application of monadic composition to real world web 
 development.
 
 In part 4, Greg primarily focuses on the idea that a monad is really an API 
 -- it's a view onto the organization of data and control structures, not 
 those structures themselves. In OO terms, it's an interface. To make this 
 point concrete Greg explores one of the simplest possible data structures 
 that supports at least two different, yet consistent interpretations of the 
 same API. The structure  used, Conway's partisan games, turned out to be 
 tailor-made for this investigation. Not only does this data structure have 
 the requisite container-like shape, it provided opportunities to see just 
 what's necessary in a container to implement the monadic interface.
 
 Running throughout the presentation is a more general comparison of reuse 
 between an OO approach versus a more functional one. When the monadic API is 
 mixed into the implementing structure we get less reuse than when the 
 implementing structure is passed as a type parameter. Finally, doing the work 
 put us in a unique position to see not just how to generalize Conway's 
 construction, monadically, but the underlying pattern which allows the 
 generalization to suggest itself.
 
 See part 1 
 See part 2
 See part 3
 
  
 
 -- 
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 7329 39th Ave SW
 Seattle, WA 98136
 
 +1 206.650.3740
 
 http://biosimilarity.blogspot.com
 
 
 
 
 -- 
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St 
 Seattle, WA 98117
 
 +1 206.650.3740
 
 

Re: [Haskell-cafe] Fwd: C9 video in the Monadic Design Patterns for the Web series

2011-07-27 Thread James Cook
Dang, I should have played with both versions before sending this.  The 'R' 
instance has a very obvious error:

return x = R (ConwayT (return (Left x)) mzero)

should be changed to

return x = R (ConwayT mzero (return (Left x)))

Sorry!

-- James

On Jul 27, 2011, at 9:28 AM, James Cook wrote:

 For any who are interested, here's a quick and dirty Haskell version of the 
 generalized Conway game monad transformer described in the video.  It uses 
 two newtypes, L and R, to select from two possible implementations of the 
 Monad class.
 
 (all the LANGUAGE pragmas are just to support a derived Show instance to make 
 it easier to play around with in GHCi - the type and monad itself are H98)
 
 -- James
 
 
  {-# LANGUAGE StandaloneDeriving #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE UndecidableInstances #-}
  module Monads.Conway where
  
  import Control.Applicative
  import Control.Monad
  
  data ConwayT m a
  = ConwayT
  { runLeftConwayT  :: m (Either a (ConwayT m a))
  , runRightConwayT :: m (Either a (ConwayT m a))
  } 
  
  deriving instance (Eq   a, Eq   (m (Either a (ConwayT m a = Eq   
  (ConwayT m a)
  deriving instance (Ord  a, Ord  (m (Either a (ConwayT m a = Ord  
  (ConwayT m a)
  deriving instance (Read a, Read (m (Either a (ConwayT m a = Read 
  (ConwayT m a)
  deriving instance (Show a, Show (m (Either a (ConwayT m a = Show 
  (ConwayT m a)
  
  instance Functor m = Functor (ConwayT m) where
  fmap f (ConwayT l r) = ConwayT (fmap g l) (fmap g r)
  where
  g (Left  x) = Left (f x)
  g (Right x) = Right (fmap f x)
  
  bind liftS (ConwayT l r) f = ConwayT
  (liftS g l)
  (liftS g r)
  where
  g (Left  x) = Right (f x)
  g (Right x) = Right (bind liftS x f)
  
  newtype L f a = L { runL :: f a } deriving (Eq, Ord, Read, Show)
  
  instance Functor m = Functor (L (ConwayT m)) where
  fmap f (L x) = L (fmap f x)
  
  instance MonadPlus m = Monad (L (ConwayT m)) where
  return x = L (ConwayT (return (Left x)) mzero)
  L x = f   = L (bind liftM x (runL . f))
  
  newtype R f a = R { runR :: f a } deriving (Eq, Ord, Read, Show)
  
  instance Functor m = Functor (R (ConwayT m)) where
  fmap f (R x) = R (fmap f x)
  
  instance MonadPlus m = Monad (R (ConwayT m)) where
  return x = R (ConwayT (return (Left x)) mzero)
  R x = f   = R (bind liftM x (runR . f))
 
 
 
 
 On Jul 27, 2011, at 4:31 AM, Greg Meredith wrote:
 
 Dear Haskellians,
 
 A new C9 video in the series!
 
 So, you folks already know most of this... except for maybe the 
 generalization of the Conway construction!
 
 Best wishes,
 
 --greg
 
 -- Forwarded message --
 From: Charles Torre ...
 Date: Tue, Jul 26, 2011 at 1:12 PM
 Subject: C9 video in the Monadic Design Patterns for the Web series
 To: Meredith Gregory lgreg.mered...@gmail.com
 Cc: Brian Beckman ...
 
 
 And we’re live!
 
  
 
 http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Greg-Meredith-Monadic-Design-Patterns-for-the-Web-4-of-n
 
 C
 
  
 
 From: Charles Torre 
 Sent: Tuesday, July 26, 2011 11:51 AM
 To: 'Meredith Gregory'
 Cc: Brian Beckman
 Subject: C9 video in the Monadic Design Patterns for the Web series
 
  
 
 Here it ‘tis:
 
  
 
 Greg Meredith, a mathematician and computer scientist, has graciously agreed 
 to do a C9 lecture series covering monadic design principles applied to web 
 development. You've met Greg before in a Whiteboard jam session with Brian 
 Beckman.
 
 The fundamental concept here is the monad, and Greg has a novel and 
 conceptually simplified explanation of what a monad is and why it matters. 
 This is a very important and required first step in the series since the 
 whole of it is about the application of monadic composition to real world 
 web development.
 
 In part 4, Greg primarily focuses on the idea that a monad is really an API 
 -- it's a view onto the organization of data and control structures, not 
 those structures themselves. In OO terms, it's an interface. To make this 
 point concrete Greg explores one of the simplest possible data structures 
 that supports at least two different, yet consistent interpretations of the 
 same API. The structure used, Conway's partisan games, turned out to be 
 tailor-made for this investigation. Not only does this data structure have 
 the requisite container-like shape, it provided opportunities to see just 
 what's necessary in a container to implement the monadic interface.
 
 Running throughout the presentation is a more general comparison of reuse 
 between an OO approach versus a more functional one. When the monadic API is 
 mixed into the implementing structure we get less reuse than when the 
 implementing structure is passed as a type parameter. Finally, doing the 
 work put us in a unique position to see not just how to generalize Conway's 
 construction, monadically, but the underlying pattern which

Re: [Haskell-cafe] Why the reluctance to introduce the Functor requirement on Monad?

2011-07-26 Thread James Cook
On Jul 25, 2011, at 4:55 PM, Ryan Ingram wrote:

 My guess is that nobody has put forward a clear enough design that solves all 
 the problems.  In particular, orphan instances are tricky.
 
 Here's an example:
 
 module Prelude where
 
 class (Functor m, Applicative m) = Monad m where
 return :: a - m a
 (=) :: m a - (a - m b) - m b
 () :: m a - m b - m b
 a  b = a = const b
 
 pure = return
 (*) = ap
 fmap = liftM
 
 module X where
 data X a = ...
 
 module Y where
 instance Functor X where fmap = ...
 
 module Z where
 instance Monad X where
 return = ...
 (=) = ...
 -- default implementation of fmap brought in from Monad definition
 
 module Main where
 import X
 import Z
 
 foo :: X Int
 foo = ...
 
 bar :: X Int
 bar = fmap (+1) foo  -- which implementation of fmap is used?  The one from Y?
 

I don't believe it would make orphan instances any trickier than they already 
are.  If Functor m = Monad m, you can't have Monad m without Functor m, so 
module Z must introduce Functor m either implicitly or explicitly or it cannot 
compile.  Viewed from outside a module, the problem is the same either way.  I 
would propose that viewed from outside a module, an implicitly declared 
instance should be indistinguishable from an explicitly declared one, and 
within a module the implicit instance would be generated if and only if there 
is no overlapping instance in scope.  An additional warning flag could be added 
to warn people who are worried about it that they have implicitly created an 
orphan instance for a superclass.

The only real problem I see relating to orphans is in cases where old code 
declares an orphan Monad instance for a type without a Functor instances, 
something which I don't think happens very often (except perhaps with Either, 
but forcing a solution to that hornet's nest would be a Good Thing IMO).  But 
either way, that breakage is more related to the superclass change than to any 
new means of declaring instances; even without the latter, the former would 
force those modules to introduce orphan Functor instances explicitly (or to 
introduce non-orphans somewhere to avoid doing so)

-- James

   -- ryan
 
 
 On Sun, Jul 24, 2011 at 8:55 PM, Ivan Lazar Miljenovic 
 ivan.miljeno...@gmail.com wrote:
 On 25 July 2011 13:50, Sebastien Zany sebast...@chaoticresearch.com wrote:
  I was thinking the reverse. We can already give default implementations of 
  class operations that can be overridden by giving them explicitly when we 
  declare instances, so why shouldn't we be able to give default 
  implementations of operations of more general classes, which could be 
  overridden by a separate instance declaration for these?
 
  Then I could say something like a monad is also automatically a functor 
  with fmap by default given by... and if I wanted to give a more efficient 
  fmap for a particular monad I would just instantiate it as a functor 
  explicitly.
 
 I believe this has been proposed before, but a major problem is that
 you cannot do such overriding.
 
 --
 Ivan Lazar Miljenovic
 ivan.miljeno...@gmail.com
 IvanMiljenovic.wordpress.com
 
 ___
 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 mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ANN: Two new random-fu releases

2011-06-24 Thread James Cook
Announcing the Hackage release of two new versions[1,2] of the random- 
fu package:


Version 0.1.4 is a build-fix release that extends support of the 0.1  
API to GHC 7.


Version 0.2 is a significantly restructured version of the package.   
Its API is mostly the same as the old for end users, but its back-end  
has been redesigned and separated into two new packages:  random- 
source provides an abstract interface for sources of entropy, and  
rvar provides an abstract interface for consumers of entropy.  The  
parts remaining in random-fu provide a more concrete interface for  
representing and sampling specific distributions.


-- James

[1] http://hackage.haskell.org/package/random-fu-0.1.4
[2] http://hackage.haskell.org/package/random-fu-0.2


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 93, Issue 58

2011-06-09 Thread James Cook

On Jun 8, 2011, at 11:17 PM, Gregory Guthrie wrote:


I rather had the feeling expressed by Robert Harper:
  Once you're in the IO monad, you're stuck there forever, and are  
reduced to Algol-style imperative programming.
 (http://existentialtype.wordpress.com/2011/05/01/of-course-ml-has-monads/ 
)


If Algol is as elegant and expressive as IO in Haskell, I'd hardly  
consider that a problem.  In fact, I would seriously consider learning  
Algol.


There seems to be a lot of IO-hate floating around, but in my opinion  
it is largely undeserved.  Even if every function in Haskell had to  
use IO, Haskell would still be a vastly more expressive language than  
most.  It would essentially be a lazy dialect of ML with different  
syntax and without parameterized modules (and, in GHC, with a lot of  
awesome type system extensions).  IO has pretty much the same  
expressiveness as ML.  It has higher-order functions, closures, etc.
You can build higher level abstractions on top of it, and people do -  
there are some pretty awesome libraries out there that are nothing  
more than glorified IO.  The CHP library, for example, builds a very  
powerful and very un-IO-like abstraction on top of IO.  IO is not such  
a bad place to be stuck, all things considered.


I think there is a tendency to look at IO as bad because pure code is  
so much better.  But it's important to keep things in perspective -  
the existence of something better doesn't make something bad.  IO is  
still better than the best of most other languages.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: remove Stability from haddock documentation on hackage

2011-06-08 Thread James Cook

On Jun 8, 2011, at 11:08 AM, Tom Murphy wrote:


On 6/7/11, James Cook mo...@deepbondi.net wrote:
[...]


The name of the field could be better, though.  On first exposure,
people tend to think stability: experimental or stability:
unstable means the package is likely to crash (For those who don't
know, it means the API is likely to change in future releases).



What is the way to indicate actual code stability? Some packages on
Hackage definitely have broken parts.



Since all cabal fields are set before uploading that would imply  
someone is uploading something they know to be broken, which doesn't  
seem right.  But assuming some legitimate reason exists, WARNING or  
DEPRECATED pragmas on the bad stuff would probably be a good way to go.


-- James


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: remove Stability from haddock documentation on hackage

2011-06-07 Thread James Cook

On Jun 6, 2011, at 10:57 PM, Chris Smith wrote:

I got asked a question today about why Control.Applicative is  
labeled as
experimental on Hackage.  Perhaps that field is something of a  
failed

experiment, and it remaining there is likely to confuse people.

Just a thought... not sure of the best place to mention it.



As far as Control.Applicative, I'm not sure to what package you're  
referring.  That label doesn't apply to modules, it applies to  
packages, and Control.Applicative is a part of the base package  
(which is not labeled experimental).


Regarding the Stability field itself, I strongly believe in it.  I  
like to know whether code I'm thinking about using is likely to have  
15 new versions in the next month or whether its interface is likely  
to change drastically with the next release.  When releasing packages  
I also like to be able to state that it's a work in progress and that  
I decline to promise forward compatibility.  If I release a package  
labeled experimental, I don't feel nearly as bad making major API  
changes because any users that might have picked it up have had fair  
warning.  On the other hand, if I've marked it stable or even  
provisional, I know I need to make a stronger effort to preserve  
source-level compatibility.


It's good, in my opinion, to be able to state succinctly in a  
standardized way that, although it does something now, what the code  
does and how it does it are probably going to change in the future.


The name of the field could be better, though.  On first exposure,  
people tend to think stability: experimental or stability:  
unstable means the package is likely to crash (For those who don't  
know, it means the API is likely to change in future releases).


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: remove Stability from haddock documentation on hackage

2011-06-07 Thread James Cook

On Jun 7, 2011, at 9:22 AM, Tillmann Rendel wrote:


Hi,

James Cook wrote:

As far as Control.Applicative, I'm not sure to what package you're
referring. That label doesn't apply to modules, it applies to  
packages,

and Control.Applicative is a part of the base package (which is not
labeled experimental).


On http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html 
, in the upper right corner, the module is marked as experimental.  
I think this is a Haddock feature, not a Hackage feature.




Ah, I did not realize it did that.  Looking at the source I see that  
it is indeed in a haddock comment.  In that case, I'll go back and  
respond to the original question.  I do not know why it's labeled  
experimental, but would hazard a wild guess that it's because the  
relation of Applicative to Monad is still an open question.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: remove Stability from haddock documentation on hackage

2011-06-07 Thread James Cook

On Jun 7, 2011, at 10:17 AM, Christopher Done wrote:


On 7 June 2011 15:05, James Cook mo...@deepbondi.net wrote:
It's good, in my opinion, to be able to state succinctly in a  
standardized way that, although it does something now, what the code  
does and how it does it are probably going to change in the future.


I think no one really updates this field and it's a human factor  
that could otherwise be generated by Hackage reliably. I'm using  
many packages that are experimental or unstable that've been  
stable for a year or more. The field is mostly useless to me. The  
stability of a package can be judged based on how often the versions  
bump up based on the PVP and/or the exports of the package change,  
that is something Hackage could trivially do. Agreed, the naming is  
also ambiguous, “API stability” seems more straight-forward.


I can't speak for anyone besides myself, but I do update it and its  
value is determined, for me, in a way that could never be automated.   
When I mark a package provisional or experimental, I am saying that I  
am not convinced that the API I've created is the best one I can come  
up with, and often I have specific plans to (when I get around to  
it) change it.  It is an indication of intent for, not history of,  
change.  Similarly, when I do reach a design that I'm satisfied with,  
I change the stability field.  But an automated decision system has no  
conceivable way of knowing that the major change I just made will be  
the last major change.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Library Versioning

2011-06-07 Thread James Cook

On Jun 7, 2011, at 11:10 AM, Luis Cabellos wrote:


Hello,

 I have a question about cabal versioning. It's possible to export  
in a cabal library a version, so instead of getting version from:


   import Paths_my_package( version )

I want to get version from my library using:

   import MyPackage( version )

And then using this from programs.

Thanks, Luis



You can export things from one module that are defined in other  
modules.  For example:


 module MyPackage ( version, ... )
 import Paths_my_package( version )
 ...

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Library Versioning

2011-06-07 Thread James Cook

On Jun 7, 2011, at 12:28 PM, Luis Cabellos wrote:

You can export things from one module that are defined in other  
modules.  For example:


 module MyPackage ( version, ... )

 import Paths_my_package( version )
 ...

Yes indeed, but I getting ugly errors (undefined references to  
version I think) when use Paths_my_package from library, and i don't  
know a better fix:
 /home/cabellos/.cabal/lib/skema-server-0.1.0/ghc-6.12.3/libHSskema- 
server-0.1.0.a(Main.o): In function `r4HU_info':
(.text+0x3ef9): undefined reference to  
`skemazmserverzm0zi1zi0_Pathszuskemazuserver_version1_closure'
/home/cabellos/.cabal/lib/skema-server-0.1.0/ghc-6.12.3/libHSskema- 
server-0.1.0.a(Main.o): In function `s5TE_info':
(.text+0x8e03): undefined reference to  
`__stginit_skemazmserverzm0zi1zi0_Pathszuskemazuserver_'


Also, I'm using Dyre, It's possible that recompile proccess of dyre  
cause the error.


Did you tell cabal that Paths_my_package is a part of your library?   
If it is referenced by your code, then it should be listed in either  
exposed-modules or other-modules, otherwise it won't be  
installed.  I've never used dyre so I don't know whether it would  
cause any issues, but I suspect not.


-- James


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cons of -XUndecidableInstances

2011-06-07 Thread James Cook

On Jun 7, 2011, at 12:43 PM, MigMit wrote:




One particularly trivial example that comes to mind is:

  newtype Mu f = Mu (f (Mu f))

  instance Show (f (Mu f)) = Show (Mu f) where
  show (Mu x) = Mu ( ++ show x ++ )
  -- Or however you'd like to show it


Ehm, that does look like poor design.

Sure you don't mean Mu f can be printed if and only if f (Mu f) can  
be printed. What you probably mean is if f transforms printable  
things to printable things, then Mu f is a printable thing. And you  
CAN express just that:




Actually, I would argue that the former _is_ what is meant.  It's a  
weaker condition than the latter and it is the necessary and  
sufficient condition to define the instance - one of the steps  
involved in formatting a value of type Mu f is to format a value of  
type f (Mu f).  It doesn't actually matter whether forall x. Show x  
= Show (f x) holds in general.



type ShowD a = forall p. (forall x. Show x = p x) - p a

showD :: Show a = ShowD a
showD px = px

class ShowF f where showF :: Show a = ShowD (f a)

instance Show a = Show (F a) where... -- here goes your f

instance ShowF F where showF = showD -- and that is the only line of  
boilerplate


instance ShowF f = Show (Mu f) where
 show (Mu fm) = Mu ( ++ runShowHelper (showF (ShowHelper show)) fm  
++ )


newtype ShowHelper x = ShowHelper {runShowHelper :: x - String}

Sorry for possible bugs — I don't have ghc anywhere near me at the  
moment, but the idea is clear, I guess.




I don't really see how this is preferable when the compiler can solve  
the equation automatically.  All that is needed is to tell it to try.   
If portability is a concern then I could see going through the  
gymnastics (and also eliminating the use of higher-rank types), but  
that's the only case in which I would consider it the preferred option.


-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347

2011-05-21 Thread James Cook

On May 21, 2011, at 8:55 AM, Paolo G. Giarrusso wrote:


Hi all, I have some problem with ScopedTypeVariables, let and so on,
at least in GHC 7.
My aim is to be able to supply a polymorphic type signature in let
bindings. Confusingly, I find no such example in the blog post about
local let generalization [1]. I first met this problem when porting
some test-code from Kiselyov, when refusing to convert its let-
bindings into where-bindings (which, btw, can't be typed into GHCi).
I've also added a comment to the bug report, but it's still quite
possible that I'm missing something.



You don't need ScopedTypeVariables for this, you can just give type  
signatures in the let binding:


Prelude let id2 :: t - t; id2 = \x - x in (id2 '1', id2 10)
('1',10)

-- James


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Advertisement: the Haskell Stack Overflow Q A site

2011-05-04 Thread James Cook

On May 4, 2011, at 4:50 PM, Andrew Coppin wrote:


   One of the benefits of a site like SO as a forum is the ability to
   record and link to prior work, edit for technical errors, and  
easily
   search and categorize past answers. It is also less prone to  
noise,

   for those suffering from cafe overload.


I would also recommend SO.


My only experience of SO is that I asked a question once, and to  
this day it has still only been viewed a grand total of 6 times.  
(And I think that was just me looking to see if there were any  
replies yet.) OTOH, it wasn't Haskell-related.


I think Haskell questions on SO tend to the opposite extreme; no  
matter how poorly thought-out the question, the Haskell community will  
descend on it like a swarm of helpful piranhas.


Languages like Java and C# have such an overwhelmingly huge number of  
questions (the quality of which are, frankly, quite poor on average)  
that very few people are going to actually sit and look through even  
1% of them.  Haskell, on the other hand, has a small enough volume  
that people can at least skim the ones from the last past day or two  
in a fairly small amount of time.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Python is lazier than Haskell

2011-04-28 Thread James Cook


On Apr 28, 2011, at 11:27 AM, Ertugrul Soeylemez wrote:


Gracjan Polak gracjanpo...@gmail.com wrote:


Ketil Malde ketil at malde.org writes:


In Haskell, I often need to add stubs of undefined in order to do
this.  I don't mind, since it is often very useful to say
*something* about the particular piece - e.g. I add the type
signature, establishing the shape of the missing piece without
bothering with the actual implementation just yet.


Seconded.


I don't see any problem with this.  Although I usually have a bottom- 
up
approach, so I don't do this too often, it doesn't hurt, when I have  
to.




Agreed - in fact, I have always thought of this style of coding as one  
of the truly great things about Haskell, and was surprised to see it  
presented as a negative.  The idea of that being a burden had never  
even entered my mind.


The fact that I can say foo = undefined and go about my business as  
if foo were, in fact, an existing component, is nice.  But as you  
point out, that can be done in pretty much any dynamically typed  
language just as trivially.   The truly great thing about it is that I  
can also say foo :: (Bar a, Num b) = a - b - (qux - m baz) - f m  
(x, Either q g), etc., and the compiler can then tell me when I  
misuse this *entirely fictitious* entity.   Or, when I'm done writing  
my code that uses foo, I can say foo :: () and let the compiler  
errors tell me what sort of a creature I have asked foo to be.  Or,  
I can just start coding foo and let the compiler tell me whether  
what I do is consistent with how I've used it elsewhere.





Sometimes I wish for a -fphp flag that would turn some type errors
into warnings. Example:

v.hs:8:6:
   Couldn't match expected type `[a]' against inferred type `()'
   In the first argument of `a', namely `y'
   In the expression: a y
   In the definition of `c': c = a y

GHC could substitute 'y = error Couldn't match expected type `[a]'
against inferred type `()'' and compile anyway.

Would that bring Haskell closer to Python?


It would make people abuse that feature.  I don't want it.  Haskell is
so difficult to abuse compared to other languages, and I'd like to  
keep

it that way.


Maybe, but it should be easy to make sure that you aren't using any  
code that abuses it; just make sure you compile all your stuff with  
that flag explicitly turned off - any code that abuses it would  
simply fail to build.  I'd expect to be able to do that by setting - 
fno-php as a global ghc-option in the cabal config file.  I'd  
probably also advocate making that flag switch type errors to non- 
suppressible warnings (that is, do not provide any way whatsoever in  
the compiler to make those warnings silent).


On a related note, I think that this sort of a feature would not  
really get at the usual objection about strong static typing  
incorrectly rejecting valid programs.  All this does is change it so  
that such programs are, instead of being rejected, altered to throw  
runtime errors in cases that could actually have worked but the type  
system was not expressive enough to prove.  It would give what I think  
of as the worst of both worlds:  Programs that can never work would be  
allowed to slip past the compiler, and programs that could work if the  
type system were smarter still won't work.


I think the proper thing to do would be to translate such code into  
code that uses Dynamic, or more likely some generalization of it.  It  
would require some serious thought about how to deal with polymorphic  
types, and especially ones that involve type classes.  All in all, it  
seems to me that a full correct implementation of such a system would  
essentially amount to embedding a full Haskell interpreter in the  
compiled executable.


Done right, though, it could be a pretty nice feature.  If nothing  
else, it would let you experiment extensively in a nice safe little  
sandbox to gain confidence in your dangerous untypeable code before  
you take the plunge and use unsafeCoerce.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using _ on the RHS of an equation?

2011-04-05 Thread James Cook
It's quite hacky, but this can be done with CPP and quasiquoting  
(incidentally, it would be _REALLY_ nice if 'undefined' and 'error'  
had similar source-location-dependent error messages by default):


https://github.com/mokus0/junkbox/commit/bad59f486c3457f1d880a1cfa5b1baa33aff4ade

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] HDF5 binding (was: why is ghci trying to load hsc file ??)

2011-04-04 Thread James Cook

On Apr 3, 2011, at 10:43 PM, mauricio.antu...@gmail.com wrote:


I worked out a small hdf5 binding using cabal and bindings-DSL and
sqlite3 as my example.



I just wanted to add that I also started an HDF5 binding recently
(using hsc2hs only).  It does more than enough for me ATM, so I  
don't

develop it actively, but if you want to pursue this (and I think
it would be a useful addition to Hackage), we may share experience
and code.  My binding is part of a bigger project, but I meant to
split it out anyway.



What an interesting coincidence, that makes at least three of
us. Apparently it's an idea whose time has come.  Mine is also an
incomplete low-level binding but is currently under semi-active
development and I aim to make it cover the entire hdf5.h interface.
If anyone is interested in it I've put it on github at:

https://github.com/mokus0/bindings-hdf5



Bindings to the full hdf5 were supposed to be in the example set for
bindings-DSL. It doesn't use pkg-config, though, and hdf5 developers
didn't like the idea of adding support. I wanted reference bindings-*
libraries to be free of linking problems some users might not be able
to solve or understand, so I gave up.


That seems strange to me - pkg-config is such a useful system, and  
support for it is incredibly easy to add and practically zero- 
maintenance.   Was it that they didn't find it worth the programmer  
time to figure out how to add pkg-config support or did they have  
specific objections?  All it seems to take is to generate a file with  
about 10 lines of text and install it to the right place.


In any case, though, the fact that current versions doesn't support it  
means that a Haskell binding package has to work around that for  
several years to come, since most stable linux distros wouldn't pick  
up an updated version for quite some time.


Currently I've got a template hdf5.pc file in the source tree which  
can be customized and dropped into the appropriate directory.  It's a  
lot less manual than it ought to be, but it's at least a lot less ugly  
than hard-coding my development machine's include and lib paths.   
Eventually my plan is to use a cabal flag to control whether it looks  
for hdf5 as using pkgconfig-depends or just extra-libs, with some  
Setup.hs logic to check whether the former will work and set the flag  
appropriately.


Incidentally, I've thought many times before that it sure would be  
great if cabal's backtracking search would consider more than just  
haskell package dependencies.  In this case, it would be really nice  
if it would backtrack on an unsatisfiable pkg-config dependency.  In  
the past I've come across cases where it would have been very helpful  
to support backtracking on buildable: False.  Maybe I'll take a look  
one of these days at how hard that would be to change.  I suspect that  
to do so in a backward-compatible way would take a lot of work though,  
because of the way Cabal exposes its internal types to Setup.hs files.


-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANNOUNCE: enumerator 0.4.8

2011-03-28 Thread James Cook

On Mar 28, 2011, at 12:54 AM, wren ng thornton wrote:


On 3/27/11 9:58 PM, John Millikin wrote:
Resending is slightly more complex -- if the other end can say  
resend that
last chunk, then it should be easy enough, but resend the last 2  
bytes of
that chunk you sent 5 minutes ago would be much harder. What is  
your use

case?


This does highlight one of the restrictions I've lamented about the  
iteratee framework. Namely that the current versions I've seen place  
unnecessary limitations on the communication the iteratee is allowed  
to give to the enumerator/enumeratees above it. This is often  
conflated with the iteratee throwing an error/exception, which is  
wrong because we should distinguish between bad program states and  
argument passing. Moreover the type system doesn't capture the kinds  
of communication iteratees assume of their enumerators/enumeratees,  
nor the kinds of communication supported by the enumerators/ 
enumeratees, which means that failure to hook them up in the right  
(non-typechecked) way /does/ constitute an error.


The one example that tends to be supported is the iteratee  
requesting that the enumerator/enumeratees seek to a given position  
in a file. Which is a good example, but it's not the only one.  
Requesting the resending of chunks is another good example. But  
there's no limit to the reasonable kinds of communication an  
iteratee could want.


In an ideal framework the producers, transformers, and consumers of  
stream data would have a type parameter indicating the up-stream  
communication they support or require (in addition to the type  
parameters for stream type, result type, and side-effect type). That  
way clients can just define an ADT for their communication protocol,  
and be done with it. There may still be issues with the Expression  
Problem, but at least those are pushed out of the stream processing  
framework itself which really shouldn't care about the types of  
communication used.


It's somewhat outdated and underdeveloped (I was writing for myself so  
I never really bothered finishing it), but I wrote an exploration of  
iteratee semantics[1] a while back in which I specified an iteratee as  
a monad-transformer stack involving, at its core, the PromptT or  
ProgramT monad transformers (as far as I know, the same could be  
done with the Coroutine monad).  I personally found that  
construction far more lucid than the usual ad-hoc view, and it also  
makes it very clear how the model can be trivially extended to support  
additional operations such as these.


Based on what I learned while writing that (and on the similarity  
between coroutines and the concepts I used), I strongly agree with  
Mario Blažević, suggestion to look at his monad-coroutine library as  
a way of understanding where they fit in some larger design space.  I  
would even go so far as to suggest that something like it could be  
considered as either a replacement for iteratees or as the underlying  
implementation of an iteratee library, because the concept not only  
subsumes iteratees and enumerators, but also delegates control to code  
that can be independent of both rather than simply reversing the  
conventional iterator concept.  I believe it also subsumes iterators  
and whatever their corresponding parts are called.


As he mentions, his implementation does not come with all the  
plumbing, but I think it would be worthwhile to create that  
plumbing, because either coroutines or operational monads may very  
well be the basis needed to develop a grand unified theory of  
composable stream processing.  If nothing else, the isomorphisms in  
his coroutine-enumerator[2] and coroutine-iteratee[3] packages seem to  
give a much more direct and useful iteratee semantics than I've seen  
given anywhere else, and at the same time they are much more readily  
extended to cover additional operations.


-- James

1. https://github.com/mokus0/junkbox/tree/master/Papers/HighLevelIteratees
2. http://hackage.haskell.org/package/coroutine-enumerator
3. http://hackage.haskell.org/package/coroutine-iteratee
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] bug in Prelude.words?

2011-03-28 Thread James Cook

On Mar 28, 2011, at 12:05 PM, Christopher Done wrote:

On 28 March 2011 17:55, malcolm.wallace malcolm.wall...@me.com  
wrote:
Does anyone else think it odd that Prelude.words will break a string  
at a non-breaking space?


Prelude words abc def\xA0ghi
[abc,def,ghi]

I think it's predictable, isSpace (which words is based on) is based  
on generalCategory, which returns the proper Unicode category:


λ generalCategory '\xa0'
Space


I agree, and I also agree that it would make sense the other way (not  
breaking on non-breaking spaces).  Perhaps it would be a good idea to  
add a remark to the documentation which specifies the treatment of non- 
breaking spaces.


-- James___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to use roots package?

2011-03-23 Thread James Cook

On Mar 23, 2011, at 6:57 PM, Henning Thielemann wrote:


James Cook schrieb:

Those are both options,  as is to simply restart findRoot if it  
returns

a 'Left' vaule.  I personally would incline toward a custom driver
function (findRoot).  I should probably add one to the library that
accepts a step limit and/or one that just iterates until convergence.


I thought that the mosts Haskellish way to do numerical iterations  
is to

generate a list of successive approximations (by List.iterate, of
course) and then let the user choose where and why he wants to abort  
the

list, and thus the iteration.



That's probably true, and the same module exports a function that does  
so.  But sometimes you just want to ask what is the root?, and get  
an answer without taking (possibly literally) forever.


Overall, the code is relatively un-Haskellish to begin with though.   
It was assembled in a short period of time in order to simply have  
code that performs the task, and hasn't really been touched since.


-- James___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to use roots package?

2011-03-18 Thread James Cook

On Mar 18, 2011, at 7:39 PM, Artyom Kazak wrote:



Hi Café!

roots (http://hackage.haskell.org/package/roots) is a package to  
solve equations like f(x)==0.


In RootFinder class there is an 'defaultNSteps' value, which is used  
as maximal count of iterations functions like findRoot and traceRoot  
can make. By default it is 250, but sometimes it's not enough. How  
can I use another value instead of 250? Should I write my own  
RootFinder instance, or findRoot function?




Those are both options,  as is to simply restart findRoot if it  
returns a 'Left' vaule.  I personally would incline toward a custom  
driver function (findRoot).  I should probably add one to the library  
that accepts a step limit and/or one that just iterates until  
convergence.


I'm curious, though - what sort of functions are you using, and what  
root finding algorithm, that it takes that long to converge?  And are  
you sure that it ever does, if it were allowed to run longer?   
Typically, for functions on Double, if an algorithm fails to converge  
within around 50 steps it's fairly likely that it never will -  
especially with an algorithm like bisection or Brent's method.  If  
you're using a higher precision type, then I probably need to change  
the default iteration limit to something more suited to the function  
type.


-- James
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] HDF5 binding

2011-03-04 Thread James Cook

On Mar 4, 2011, at 8:25 AM, Ferenc Wagner wrote:


Hi,

This is fairly extensive indeed!  I got nowhere near this, but also  
took

a somewhat different angle, especially by using StorableArrays for
passing arrays around (I used HDF5 in conjunction with LaPack).  I  
also
experienced with going a little higher level here and there.   
Attributes
aren't implemented yet, because that would require making location  
ids a
type class.  An unsolved problem is the safe representation of  
ranks: I
went for generality by using lists for indexing, but it would be  
nice to

express dimensionality constraints in the types (with sane syntax).
Maybe there's a handy technique for this, I didn't explore the field.
Talking about indexing, choosing Fortran convention seems to be a
mistake in retrospect, but that's no big deal.


I've skimmed through your code, it looks good.  It's definitely a bit  
higher level than mine - mine is (intentionally) little more than a  
bunch of types and foreign imports with names changed minimally,  
mostly just uppercasing or lowercasing the H5? prefixes as needed.   
That approach seems to work really well for large C interfaces (like  
OpenGLRaw, etc.) if for no other reason than that it exposes the C  
interface via Haskell's much-better type system and documentation  
tools.  I'll read through yours in more detail, it looks like there  
are some good ideas there that I can apply when I start working on  
something higher-level.



I attach my code so you can get a better idea what I'm talking about,
maybe you can find some usable pieces.  Separating the generic hid  
type
into specific newtypes worked out to some extent, but maybe isn't a  
good

idea at the lowest level (where the FFI makes it automatic).  I'd need
broader experience with the HDF5 API to tell.


My experience isn't especially broad either, but from what I've seen a  
type-level approach for distinguishing hid_t usages ought to work, at  
least most of the time.  One thought I have is to use a phantom type  
parameter at the lowest level, so that foreign imports can either  
constrain it or not, as the situation seems to call for.


Thanks

-- James

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: True Random Numbers

2010-04-05 Thread James Cook
As the maintainer of random-fu, I'd be interested to know whether you  
find it useful after further inspection.  It does, in fact, support  
using /dev/random as its entropy source.  I don't know what exact sort  
of things you're wanting to do, but very basic usage (random Int in IO  
from DevRandom, etc.) is along these lines:


 sampleFrom DevRandom (uniform 1 100) :: IO Int
 sampleFrom DevRandom stdNormal :: IO Double

If the haddock docs are insufficient, feel free to drop me an email  
for clarification - I know they're a bit spotty at the moment.


Minor warning: I'm getting ready to release a fairly major overhaul of  
the library's innards (the latest is in the darcs repo).  The public  
interface will probably not change much, but if you happen to end up  
using any of the low-level interfaces (such as to define your own new  
random source) just be aware that those are changing soon.  It's  
nearing release, I'm mostly just trying to knock off rough edges and  
trying to decide whether to take the plunge and make some interface  
changes (mostly whether I want to hide some data constructors in order  
to better enforce some invariants).


-- James Cook

On Apr 3, 2010, at 1940, Alex Rozenshteyn wrote:

Looking over the random-fu package, I think it might have what I'm  
looking for (and a lot that I'm not).


On Sat, Apr 3, 2010 at 6:27 PM, Gökhan San g...@stillpsycho.net  
wrote:

Alex Rozenshteyn rpglove...@gmail.com writes:

 The Rand monad you linked seems to be a step in the right direction
 for what I want, but it uses getStdGen, which appears to end up  
using

 cpu time to seed the generator.

There's the random-stream package but looks like it's subject to code
rot. Its RandomGen instance lacks the split functionality but I  
guess it

could be used with MonadRandom.

--

Gökhan San
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
 Alex R
___
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