Re: [Haskell-cafe] Trouble installing FileManipCompat

2011-04-28 Thread Thomas Hartman
I uploaded a new version of FileManipCompat which is mtl-2 compatible.

2011/1/5 Daniel Fischer daniel.is.fisc...@googlemail.com:
 On Wednesday 05 January 2011 19:43:53, Tony Miller wrote:
 Thanks that works, but I have packages that rely on mtl=2.0, so its
 not the best solution. Perhaps the maintainer of FileManipCompat could
 be contacted to update the package?

 Visiting http://hackage.haskell.org/package/FileManip reveals that that
 package is obsolete, one should use filemanip (all lowercase) instead,
 which has been built on 6.12 and 7.0, so that should work and it's rather
 the maintainer(s) of HStringTemplateHelpers (and FileManipCompat) who
 should be asked to update their package(s).

 ___
 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] Haskell Web Framework Happstack 6 Released

2011-02-17 Thread Thomas Hartman
I don't know who said it first, but I'm repeating it.

2011 is going to be the tipping point year for haskell web frameworks.

Thanks Jeremy!

2011/2/17 Jeremy Shaw jer...@n-heptane.com:
 Hello,

 I am pleased to announce the release of Happstack 6. We fully recommend that
 all Happstack users migrate to the new release.

 Happstack is a high-performance Haskell web framework. It has high-level
 functionality for routing requests, extracting parameters, manipulating
 responses, serving static file contents, compression responses, and more. It
 includes an integrated HTTP server and a native RAM-cloud database system
 known as MACID. This allows you to deploy your web application with out
 having to configure apache, php, mysql, memcached, etc!

 Install instructions can be found here:

 http://happstack.com/download

 If you are porting existing applications you should check out the Happstack
 6 migration guide:

 http://code.google.com/p/happstack/wiki/Happstack6Migration

 Porting should be pretty straight-forward. Despite the massive
 reorganization, the exports from Happstack.Server are largely the same.

 What's Exciting!
 

 The focus of this release has been happstack-server. The primary goal
 was to make happstack-server much easier to learn and to use.

 This includes:

  1. improving the overall organization of the library
  2. greatly improving the documentation
  3. making it easier to install
  4. ensuring that the server provides fast, reliable performance
  5. making it easier for new (and old) developers to understand and get
 started

 If you have looked at Happstack before and found it too difficult to
 understand, I highly recommend you take another look. The new organization
 and documentation make it far easier to understand.

 More Logical Organiation
 

 In prior versions, the Happstack.Server.SimpleHTTP module contained just
 about everything, with little organization, and no real differentiation
 between the external API and the library internals. In Happstack 6,
 SimpleHTTP has been refactored into numerous, smaller modules. The internals
 have been moved into Happstack.Server.Internal.* so that they are not
 leaking into the external API. This should make it much easier to find what
 you are looking for, and prevent you from accidently running across internal
 things like the WebT monad, which you do not really need to know anything
 about.

 Better Documentation
 

 The API documentation for happstack-server is also much better. All external
 API functions should now have good haddock documentation with many inline
 examples.

 However, learning a new library by studying the API documentation can still
 be pretty frustrating. So we also have the brand new Happstack Crash Course.
 http://happstack.com/docs/crashcourse/index.html.

 The Happstack Crash Course covers a vast majority of the happstack-server
 API. It covers the API in a logical manner and includes many downloadable,
 runnable examples. It is intended to be read start to finish, and to also be
 usable as a reference guide for specific How do I do XXX questions.

 Additionally, the guestbook example has been updated to a cleaner, more
 modern style of Happstack coding. It also has more comments/haddock
 documentation.

 Better API
 --

 During the process of documenting Happstack, many small improvements where
 made to the API. Once you try to document something stupid you realize how
 stupid it is and decided it would be good to fix it first ;)

 For example, the Cookie API now makes it more obvious how to create session
 cookies vs persistent cookies. And makes it obvious how to expire a cookie.

 The functions for looking up values in the query string and require body no
 longer require the use of the RqData monad. You can use the look* functions
 directly in the ServerPart monad.

 If you do choose to use RqData, it now has an Applicative instance which can
 accummulate and report lookup errors.
 (http://happstack.blogspot.com/2010/10/is-rqdata-monad-still-needed.html)
 There are a bunch of other improvements to request data handling documented
 here, http://happstack.com/docs/crashcourse/RqData.html.

 Easier Install
 --

 In order to make Happstack easier to install we have removed as many
 dependencies as possible. happstack-data no longer depends on
 happstack-util, which makes it easier to install happstack-data or
 happstack-state with out the rest of the framework. HSP and HStringTemplate
 support has been moved into *optional* happstack-hsp and
 happstack-hstringtemplate packages.

 New Features
 

 Happstack also has a number of new features including:

  - support for Heist templates
  (http://happstack.com/docs/crashcourse/Templates.html#helloheist)
  - support for Hamlet templates
  - improved environment for extracting query string and form values
 

[Haskell-cafe] What is the point of many and some functions in Control.Applicative (for Alternative?)

2010-07-03 Thread Thomas Hartman
When I load up Control.Applicative in ghci and try, eg

many [1,2] or many (Just 1) or some [1,2] or some (Just 1)

this never returns.

What are the practical uses of these combinators, or for using the
Alternative class in general?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Function to find a substring

2010-06-07 Thread Thomas Hartman
If you want to use libs to make your life easier, maybe something
along these lines?

Prelude Data.List.Split Safe fmap length . headMay . split (onSublist
asdf) $ blee blah asdf bloo
Just 10

If they are big strings, it's probably faster to use bytestrings, or
arrays of some kinds, rather than default List implementation of
string.

2010/6/6 R J rj248...@hotmail.com:
 What's an elegant definition of a Haskell function that takes two strings
 and returns Nothing in case the first string isn't a substring of the
 first, or Just i, where i is the index number of the position within the
 first string where the second string begins?

 
 Hotmail has tools for the New Busy. Search, chat and e-mail from your inbox.
 Learn more.
 ___
 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] Removing alternate items from a list

2010-06-07 Thread Thomas Hartman
maybe this?

map snd . filter (odd . fst) . zip [1,2..] $ [1,2,3,4,5]

2010/6/6 R J rj248...@hotmail.com:
 What's the cleanest definition for a function f :: [a] - [a] that takes a
 list and returns the same list, with alternate items removed?  e.g., f [0,
 1, 2, 3, 4, 5] = [1,3,5]?

 
 The New Busy is not the old busy. Search, chat and e-mail from your inbox.
 Get started.
 ___
 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] is there a way to prove the equivalence of these two implementations of (Prelude) break function?

2010-06-07 Thread Thomas Hartman
Here's two implementations of break, a snappy one from the prelude,
and a slow stupid stateful one.

They are quickchecked to be identical.

Is there a way to prove they are identical mathematically? What are
the techniques involved? Or to transform one to the other?

import Control.Monad.State
import Test.QuickCheck

tThis = take 5 . show .  mybreak (400) $ [1..10^7]
tPrel = take 5 . show .  prelbreak (400) $ [1..10^7]


prelbreak p xs = (takeWhile (not . p) xs,dropWhile (not . p) xs) --
fast, more or less as implemented in prelude iiuc

mybreak p xs =  evalState (brk p) ([],xs) -- stateful, slow
brk p = do
  (notsat,remaining) - get
  case remaining of
[] - return (notsat,remaining)
(r:rs) - if p r
then return (notsat,remaining)
else do put (notsat++[r],rs) -- ++ is probaby a
major reason
brk p
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] yet another functional reactive programming tutorial :)

2010-06-01 Thread Thomas Hartman
cabal installable would be nice. for that matter, throw it on hackage!

2010/5/26 Jinjing Wang nfjinj...@gmail.com:
 Dear list,

 As I'm learning frp and reading the wonderful tutorial at

 http://www.formicite.com/dopage.php?frp/frp.html

 , I'm putting up some more basic cheatsheet style tutorial for myself.

 http://github.com/nfjinjing/frp-guide

 Feel free to take advantage of it.

 --
 jinjing
 ___
 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] Re: [web-devel] Google Summer of Code: BlazeHTML RFC

2010-05-30 Thread Thomas Hartman
I'm a heavy hsp user. Could hsp benefit from this project by using
blaze as a back end instead of whatever it's using now?

IIUC, Hsp uses hsx (via the preprocessor program trhsx) to convert
xml-containing hybrid hsp/xml/html files into compilable haskell.

I expected hsx uses XHTML (which iiuc is what blaze would replace) on
the backend but I don't see it listed in the dependencies at

http://hackage.haskell.org/package/hsx-0.7.0

so I guess it doesn't and uses something internal rather than xhtml. (Right?)

My question as regards BlazeHTML is if there could be any performance
win/tie in for the hsp/hsx toolchain.

FWIW, wrt to blaze sclv commented on reddit The idea is rather that
this would be a replacement for the html combinator library, as
distinct from templating (hamlet, hstringtemplate, bravo, chunks,
press,  co) and as distinct from the *sp model of inlined code (hsp).

Edit: Ideally, and generally for Haskell libs, the choices of
persistence layer, html generation library, dispatch model, and server
layer are largely orthogonal. Strong typing makes any ad-hoc plumbing
a breeze.

http://www.reddit.com/r/haskell/comments/bxa0a/blazehtml_a_blazingly_fast_html_combinator/

thomas.

2010/5/30 Tom Lokhorst t...@lokhorst.eu:
 +1 for HTML5.

 Also, I suggest focussing on the html serialization of HTML5.

 The xml serialization (XHTML5) is only useful in an XML environment.
 For such environments pure xml libraries are more appropriate.

 Besides, I like html syntax better.

 On 30 May 2010 16:27, Jochem Berndsen joc...@functor.nl wrote:
 On 05/29/2010 08:05 PM, Gregory Collins wrote:

 Matt Parkermoonmaster9...@gmail.com  writes:

     Q3: Which HTML version would you preferably use?

 HTML 5. google summer of code should be about pushing the new and
 exciting.

 Yes, definitely, this should be the default IMO.

 +1


 --
 Jochem Berndsen | joc...@functor.nl
 ___
 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] why does Data.Text.Lazy.IO.readFile return the internal type Data.Text.Lazy.Internal.Text, when Data.Text.IO.readFile returns plain IO Data.Text.Text?

2010-04-30 Thread Thomas Hartman
*Main :t Data.Text.IO.readFile
Data.Text.IO.readFile :: FilePath - IO T.Text

but

*Main :t Data.Text.Lazy.IO.readFile
Data.Text.Lazy.IO.readFile
  :: FilePath - IO text-0.7.1.0:Data.Text.Lazy.Internal.Text

why does the lazy version use the internal type, whereas the strict
version of Text IO just using plain Data.Text type?
and how can I get from internal type to regular type when using Data.Text?

also the internal type doesn't appear to be reflected in the haddock:
 
http://hackage.haskell.org/packages/archive/text/0.7.1.0/doc/html/Data-Text-Lazy-IO.html

ghc-pkg list | grep -i text
text-0.7.1.0

thanks for any help!
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The instability of Haskell libraries

2010-04-23 Thread Thomas Hartman
1) Folks, what exactly is the situation with buildbots?
2) Easily available images for installing virtualized environments
could also ameliorate the pain, no?

wrt 1) It seems to me that in an ideal world you could have a
candidate for uploading to hackage, but before uploading you could
push a magic button and get a message within one hour stating whether
this broke any packages on hackage.

I start thinking about a (cloneable) community ec2 or slicehost server
for buildbot -- 72 bucks a month should be doable for a community in
the thousands.

Does this make sense? Is it within the realm of possibility? What
would it take to make it happen?

I made a baby step in the direction of 2) with

http://blog.patch-tag.com/2010/02/12/ec2-amis-for-gitit-happstack/

At the very least, what this means for me personally is that I (or
anybody) can spin up a working box with gitit installed on it, for
some past incarnation of gitit/happstack/haskell platform.

Now, what happens when you attempt to cabal update  cabal reinstall
gitit -- I dunno. Very possibly breakage.

But at least you get a working place to start from.

I can see how this might apply to other pain points that I have less
personal knowledge of, like glut (?)  many others.

thomas.

2010/4/23 Jason Dagit da...@codersbase.com:


 On Fri, Apr 23, 2010 at 11:34 AM, John Goerzen jgoer...@complete.org
 wrote:

 A one-character change.  Harmless?  No.  It entirely changes what the
 function does.  Virtually any existing user of that function will be
 entirely broken.  Of particular note, it caused significant breakage in the
 date/time handling functions in HDBC.

 Now, one might argue that the function was incorrectly specified to begin
 with.  But a change like this demands a new function; the original one ought
 to be commented with the situation.

 My second example was the addition of instances to time.  This broke code
 where the omitted instances were defined locally.  Worse, the version number
 was not bumped in a significant way to permit testing for the condition, and
 thus conditional compilation, via cabal.  See http://bit.ly/cBDj3Q for more
 on that one.

 This is of course in part due to a strength of cabal (remember that
 strengths and weaknesses tend to come together).  Cabal discourages testing
 libraries/apis at configure time.  The result is that version numbers need
 to encode this information.  We don't (yet), have a tool to help detect when
 a change in version number is needed or what the next version should be.  We
 leave this up to humans and it turns out, humans make mistakes :)

 Even once we have an automatic tool to enforce/check the package version
 policy, mistakes may still sneak in.  I would expect the 'T' in the time
 format to be in this same category.  More about that below.


 I don't have a magic bullet to suggest here.  But I would first say that
 this is a plea for people that commit to core libraries to please bear in
 mind the implications of what you're doing.  If you change a time format
 string, you're going to break code.  If you introduce new instances, you're
 going to break code.  These are not changes that should be made lightly, and
 if they must be made (I'd say there's a stronger case for the time instances
 than the s/ /T/ change), then the version number must be bumped
 significantly enough to be Cabal-testable.

 While I haven't participated in the library proposal process myself, I was
 under the impression that Haskell has a fairly rigorous process in place for
 modifying the core libraries.  Is the above change too small to for that
 process?  Did that process simply fail here?

 Jason

 ___
 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] Build problems (hsp, trhsx, ultimately Happstack)

2010-04-23 Thread Thomas Hartman
I've had this problem too.

I believe trhsx is installed by

http://hackage.haskell.org/package/hsx

So, you might need to
-- upgrade hsx
-- make sure that the upgraded trhsx executable is the one being
executed by cabal install hsx (maybe deleting/temporarily moving other
trhsx exes)

thomas.

2010/4/22 Alexander Solla a...@2piix.com:
 Consider the following bash session:

 [ a...@kizaru:~/ ]$ which trhsx
 /home/ajs/.cabal/bin/trhsx

 [ a...@kizaru:~/ ]$ trhsx
 Usage: trhsx infile [outfile]

 [ a...@kizaru:~/ ]$ cabal install hsp
 Resolving dependencies...
 Configuring hsp-0.4.5...
 Preprocessing library hsp-0.4.5...
 Building hsp-0.4.5...
 ghc: could not execute: trhsx
 cabal: Error: some packages failed to install:
 hsp-0.4.5 failed during the building phase. The exception was:
 ExitFailure 1

 Does anybody have any suggestions?  I'm trying to install Happstack on Arch
 Linux (GHC 6.12.1).   ~/.cabal/bin/ is in my path and trhsx runs.

 I've had this problem before, and I think I ran cabal as root for the HSP
 package.  That's not working this time.  I get the same failure.
 ___
 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] The instability of Haskell libraries

2010-04-23 Thread Thomas Hartman
So the situation is

1) The buildbot will catch dependencies with compile errors, but only
after the package has been pushed, and there is no easy way for
packagers to check that this won't happen

2) There are many important packages that will pass a compile check
but not a runtime check.

Well, 2 seems like a hard problem to solve.

But 1) could be solved by having a candidate snapshot hackage that can
be cloned at will, and buildbotted against, no?

2010/4/23 Erik de Castro Lopo mle...@mega-nerd.com:
 Thomas Hartman wrote:

 1) Folks, what exactly is the situation with buildbots?

 If I'm not mistaken, the buildbots run *after* the package has been
 pushed to hackage. Thats already too too late.

 Erik
 --
 --
 Erik de Castro Lopo
 http://www.mega-nerd.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] Upgrading to Haskell Platform

2010-03-12 Thread Thomas Hartman
It should not be necessary to uninstall ghc, as hask plat and ghc are
orthogonal by design.
r
Unless there is some gotcha I am unaware of, not being a mac user.

You are aware that hask plat is beta though, right?

You might be better served simply upgrading your cabal, and waiting
for the all-in-one mac packager to be really shiny.

You can grab cabal here, and after you have unzipped it run the
bootstrap script which also downloads dependencies you might need.

cheers.

2010/3/10 David Place d...@vidplace.com:
 Hi:

 I am running GHC 6.10.4 on Mac OSX 10.6.2.   Somehow, I have a broken version 
 of Cabal (1.6.0.3) installed.  In order to fix it, I thought I should just 
 upgrade to the Haskell Platform.  Is it necessary to uninstall my current GHC 
 first?  If, so, how?

 Thanks you.

 Cheers,
 David

 ___
 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] Upgrading to Haskell Platform

2010-03-12 Thread Thomas Hartman
grab cabal here I mean:

http://hackage.haskell.org/trac/hackage/wiki/CabalInstall

2010/3/12 Thomas Hartman tphya...@gmail.com:
 It should not be necessary to uninstall ghc, as hask plat and ghc are
 orthogonal by design.
 r
 Unless there is some gotcha I am unaware of, not being a mac user.

 You are aware that hask plat is beta though, right?

 You might be better served simply upgrading your cabal, and waiting
 for the all-in-one mac packager to be really shiny.

 You can grab cabal here, and after you have unzipped it run the
 bootstrap script which also downloads dependencies you might need.

 cheers.

 2010/3/10 David Place d...@vidplace.com:
 Hi:

 I am running GHC 6.10.4 on Mac OSX 10.6.2.   Somehow, I have a broken 
 version of Cabal (1.6.0.3) installed.  In order to fix it, I thought I 
 should just upgrade to the Haskell Platform.  Is it necessary to uninstall 
 my current GHC first?  If, so, how?

 Thanks you.

 Cheers,
 David

 ___
 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] How to do the permutation and combination thing?

2010-03-12 Thread Thomas Hartman
There is also polyomino.f2s:

http://www.polyomino.f2s.com/david/haskell/combinatorics.html

Iirc correctly there is some stuff here that is not on hackage but
probably could/should be.


2010/3/12 Victor Mateus Oliveira rhapso...@gmail.com:
 Hi,

 Give a try to this library: http://hackage.haskell.org/package/permutation
 You can construct the combinations with list of indices and then apply
 it to your sets.

 []s
 Victor

 On Fri, Mar 12, 2010 at 5:16 AM, Ketil Malde ke...@malde.org wrote:
 Casey Hawthorne cas...@istar.ca writes:

  For example, I have this:
list1 = [a, b, c]
list2 = [d, e, f]
list3 = [g, h, i]

 Think in abstract terms what you want to accomplish.

 A bit more specifically, let's say the input is a list of lists, and you
 want to produce all combinations of drawing one element from each of the
 input lists¹:

  perms :: [[a]] - [[a]]

 You need to consider two cases, when the input is empty, and when the
 input contains at least one list of elements:

  perms (l:ls) = ...
  perms [] = ...

 The second case shouldn't be so hard.

 Now, if you pretend that 'perms' is already implemented, then you can
 use it to generate all permutations for the tail of the input list.  The
 first case boils down to combining the first input list with all
 permutations of the rest of the lists:

  perms (l:ls) = ... l ... perms ls

 Does this help?

 -k

 ¹ Using tuples is harder to generalize for length, but nicer typewise,
 since you'd get something like 'perms :: ([a],[b],..[x]) - [(a,b,..,x)]
 --
 If I haven't seen further, it is by standing in the footprints of giants
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




 --
 GNU/Linux user #446397 - http://counter.li.org
 ___
 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] mirroring patch tag

2010-03-12 Thread Thomas Hartman
http://blog.patch-tag.com/2010/03/13/mirroring-patch-tag/

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


Re: [Haskell-cafe] sendfile leaking descriptors on Linux?

2010-02-28 Thread Thomas Hartman
As far as I can tell, stepcut was probably correct in his diagnosis before.

I was getting two processes started because of a stray cron job.

2010/2/26 Thomas Hartman tphya...@gmail.com:
 Indeed, the error occurs when two processes are running at the same
 time. One process isn't serving anything, and the other is just
 looping, reported that it can't stop because the port is taken, and
 repeating ad infinitum.

 The loop I have is

 ulimit -v 15
 while true; do
  echo starting patchtag: `date`
 ./dist/build/patchtagserver/patchtagserver --port=80 --
  echo patchtag exited: `date`
  echo patchtag exited: `date`  patch-tag.log
  rm -f _local/patchtagserver_state.lock

 The ulimit is so that it will die after consuming a reasonable amount
 of memory. (I seem to have a memory leak somewhere, but it takes many
 hours to get up to 150M.)

 Everything else looks pretty standard to me. It seems to work as
 designed most of the time, but occasionally will result in two
 processes. I'm baffled as to how this happens.

 If anybody has any idea, I would love to hear them.

 2010/2/26 Jeremy Shaw jer...@n-heptane.com:
 Hello,
 It will be interesting to see if that makes any difference -- it shouldn't.
 In happstack-server we use 'listenOn'. According to the documentation
 listenOn already sets ReuseAddr:
 http://hackage.haskell.org/packages/archive/network/2.2.1.7/doc/html/Network.html#v%3AlistenOn
 A quick look at the source code confirms it is calling:
    setSocketOption sock ReuseAddr 1
 It sounds to be like you are getting the socket in use error because you
 have 2 processes running. Seems like the first one hasn't really died, but
 the second one is started anyway. How is it that your loop starts a second
 server when the first one has not finished?
 - jeremy
 On Fri, Feb 26, 2010 at 1:43 PM, Thomas Hartman tphya...@gmail.com wrote:

 Thanks, I altered my top level request handler as follows

 mysmartserver conf h stateProxy = do
      socket - bindPort conf

       I added (setSocketOption socket ReuseAddr 1) here
       Should this be added in a comment, or even in function code,
 in Happstack.Server.SimpleHTTP? What are the tradeoffs, when would you
 *not* want ot use ReuseAddr?)

      webserverTid - forkIO $ simpleHTTPWithSocket socket conf h
      putStrLn . ( starting happs server ++ ) = time

      control - startSystemState stateProxy -- start the HAppS state
 system
      putStrLn . ( happs state started ++ ) = time

      waitForTermination
      killThread webserverTid
      stateShutdown control

 I can't replicate the error reliably so I won't know if it actually
 fixed the problem for a while, therefore just leaving this cookie
 crumb trail in case others may find it helpful.

 2010/2/26 Brandon S. Allbery KF8NH allb...@ece.cmu.edu:
  On Feb 26, 2010, at 04:28 , Thomas Hartman wrote:
 
  me: Like mightybyte, I run my app in a shell loop that will just
  restart it after a crash. But every once in a while it won't restart
  because of the busy socket and I need to do a manual restart, killing
  multiple processes (usually 2).
 
  the error I get is:
 
  bind: resource busy (Address already in use)
 
  This is on application restart?  It's not out of file descriptors, it's
  just
  the system keeping the socket around (netstat will show it in TIME_WAIT,
  or
  possibly in a shutdown negotiation state such as LAST_ACK, FIN_WAIT,
  etc.
   TCP lacks *reliable* socket shutdown negotiation).
 
  You want to configure the socket with SO_REUSEADDR before trying to bind
  it
  (setSocketOption socket ReuseAddr 1).
 
  As to the portable version of sendfile, it's because not all systems
  offer a
  sendfile() system call.  Linux and *BSD do, and can use the native
  implementation; the portable version emulates sendfile() when it doesn't
  exist, at the price of additional CPU usage/system load (sendfile()
  having
  been created specifically to reduce system load in the common case for
  web
  servers).
 
  --
  brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
  system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
  electrical and computer engineering, carnegie mellon university    KF8NH
 
 
 



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


Re: [Haskell-cafe] sendfile leaking descriptors on Linux?

2010-02-26 Thread Thomas Hartman
I believe this might be causing problems for me with patch-tag.

me: Like mightybyte, I run my app in a shell loop that will just
restart it after a crash. But every once in a while it won't restart
because of the busy socket and I need to do a manual restart, killing
multiple processes (usually 2).

the error I get is:

bind: resource busy (Address already in use)

This sounds like what is being discussed. I have some questions.

 the server will eventually run out of file descriptors

How can I tell if I am running out of file descriptors?

 If I use the portable build of the sendfile package,  everything works fine 
 for hours and hours of this happening.

What is the portable build and how do I use it? Do you eventually have
troubles here as well? What is the reason to use the linux native
build then? speed / more connections per second?

thanks for your help!

2010/2/4 Bardur Arantsson s...@scientician.net:
 Hi all,

 I've been using the sendfile package off Hackage, but it seems to be leaking
 file descriptors when using the Linux-native build.

 What's happening in my specific case is the following:

   1) client requests a range of a file
   2) server starts sending the range
   3) client disconnects before receiving the whole file

 This happens over and over with the client requesting different ranges of
 the file (so the client does make progress).

 If I use the portable build of the sendfile package, everything works fine
 for hours and hours of this happening.

 If I use the Linux-native build of the sendfile package, the server
 will eventually run out of file descriptors. According to lsof the files
 that are being kept open are the data files being sent in 2) above.

 This is on GHC 6.10.x (Ubuntu).

 Is anyone else seeing this? Anyone got any idea what's going on?

 Cheers,

 ___
 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] sendfile leaking descriptors on Linux?

2010-02-26 Thread Thomas Hartman
Thanks, I altered my top level request handler as follows

mysmartserver conf h stateProxy = do
  socket - bindPort conf

   I added (setSocketOption socket ReuseAddr 1) here
   Should this be added in a comment, or even in function code,
in Happstack.Server.SimpleHTTP? What are the tradeoffs, when would you
*not* want ot use ReuseAddr?)

  webserverTid - forkIO $ simpleHTTPWithSocket socket conf h
  putStrLn . ( starting happs server ++ ) = time

  control - startSystemState stateProxy -- start the HAppS state
system
  putStrLn . ( happs state started ++ ) = time

  waitForTermination
  killThread webserverTid
  stateShutdown control

I can't replicate the error reliably so I won't know if it actually
fixed the problem for a while, therefore just leaving this cookie
crumb trail in case others may find it helpful.

2010/2/26 Brandon S. Allbery KF8NH allb...@ece.cmu.edu:
 On Feb 26, 2010, at 04:28 , Thomas Hartman wrote:

 me: Like mightybyte, I run my app in a shell loop that will just
 restart it after a crash. But every once in a while it won't restart
 because of the busy socket and I need to do a manual restart, killing
 multiple processes (usually 2).

 the error I get is:

 bind: resource busy (Address already in use)

 This is on application restart?  It's not out of file descriptors, it's just
 the system keeping the socket around (netstat will show it in TIME_WAIT, or
 possibly in a shutdown negotiation state such as LAST_ACK, FIN_WAIT, etc.
  TCP lacks *reliable* socket shutdown negotiation).

 You want to configure the socket with SO_REUSEADDR before trying to bind it
 (setSocketOption socket ReuseAddr 1).

 As to the portable version of sendfile, it's because not all systems offer a
 sendfile() system call.  Linux and *BSD do, and can use the native
 implementation; the portable version emulates sendfile() when it doesn't
 exist, at the price of additional CPU usage/system load (sendfile() having
 been created specifically to reduce system load in the common case for web
 servers).

 --
 brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
 system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
 electrical and computer engineering, carnegie mellon university    KF8NH



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


Re: [Haskell-cafe] sendfile leaking descriptors on Linux?

2010-02-26 Thread Thomas Hartman
Indeed, the error occurs when two processes are running at the same
time. One process isn't serving anything, and the other is just
looping, reported that it can't stop because the port is taken, and
repeating ad infinitum.

The loop I have is

ulimit -v 15
while true; do
  echo starting patchtag: `date`
./dist/build/patchtagserver/patchtagserver --port=80 --
  echo patchtag exited: `date`
  echo patchtag exited: `date`  patch-tag.log
  rm -f _local/patchtagserver_state.lock

The ulimit is so that it will die after consuming a reasonable amount
of memory. (I seem to have a memory leak somewhere, but it takes many
hours to get up to 150M.)

Everything else looks pretty standard to me. It seems to work as
designed most of the time, but occasionally will result in two
processes. I'm baffled as to how this happens.

If anybody has any idea, I would love to hear them.

2010/2/26 Jeremy Shaw jer...@n-heptane.com:
 Hello,
 It will be interesting to see if that makes any difference -- it shouldn't.
 In happstack-server we use 'listenOn'. According to the documentation
 listenOn already sets ReuseAddr:
 http://hackage.haskell.org/packages/archive/network/2.2.1.7/doc/html/Network.html#v%3AlistenOn
 A quick look at the source code confirms it is calling:
    setSocketOption sock ReuseAddr 1
 It sounds to be like you are getting the socket in use error because you
 have 2 processes running. Seems like the first one hasn't really died, but
 the second one is started anyway. How is it that your loop starts a second
 server when the first one has not finished?
 - jeremy
 On Fri, Feb 26, 2010 at 1:43 PM, Thomas Hartman tphya...@gmail.com wrote:

 Thanks, I altered my top level request handler as follows

 mysmartserver conf h stateProxy = do
      socket - bindPort conf

       I added (setSocketOption socket ReuseAddr 1) here
       Should this be added in a comment, or even in function code,
 in Happstack.Server.SimpleHTTP? What are the tradeoffs, when would you
 *not* want ot use ReuseAddr?)

      webserverTid - forkIO $ simpleHTTPWithSocket socket conf h
      putStrLn . ( starting happs server ++ ) = time

      control - startSystemState stateProxy -- start the HAppS state
 system
      putStrLn . ( happs state started ++ ) = time

      waitForTermination
      killThread webserverTid
      stateShutdown control

 I can't replicate the error reliably so I won't know if it actually
 fixed the problem for a while, therefore just leaving this cookie
 crumb trail in case others may find it helpful.

 2010/2/26 Brandon S. Allbery KF8NH allb...@ece.cmu.edu:
  On Feb 26, 2010, at 04:28 , Thomas Hartman wrote:
 
  me: Like mightybyte, I run my app in a shell loop that will just
  restart it after a crash. But every once in a while it won't restart
  because of the busy socket and I need to do a manual restart, killing
  multiple processes (usually 2).
 
  the error I get is:
 
  bind: resource busy (Address already in use)
 
  This is on application restart?  It's not out of file descriptors, it's
  just
  the system keeping the socket around (netstat will show it in TIME_WAIT,
  or
  possibly in a shutdown negotiation state such as LAST_ACK, FIN_WAIT,
  etc.
   TCP lacks *reliable* socket shutdown negotiation).
 
  You want to configure the socket with SO_REUSEADDR before trying to bind
  it
  (setSocketOption socket ReuseAddr 1).
 
  As to the portable version of sendfile, it's because not all systems
  offer a
  sendfile() system call.  Linux and *BSD do, and can use the native
  implementation; the portable version emulates sendfile() when it doesn't
  exist, at the price of additional CPU usage/system load (sendfile()
  having
  been created specifically to reduce system load in the common case for
  web
  servers).
 
  --
  brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
  system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
  electrical and computer engineering, carnegie mellon university    KF8NH
 
 
 


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


Re: [Haskell-cafe] ANN: Dungeons of Wor - a largish FRP example and a fun game, all in one!

2010-02-11 Thread Thomas Hartman
1) This is missing the obligatory youtube video.

2) AWESOME! :)

thomas.

2010/2/11 Patai Gergely patai_gerg...@fastmail.fm:
 Hello all,

 I just uploaded the first public version of Dungeons of Wor [1], a
 homage to the renowned three-decade-old arcade game, Wizard of Wor.
 While it makes a fine time killer if you have a few minutes to spare, it
 might be of special interest to the lost souls who are trying to figure
 out FRP. The game was programmed using the Simple version of the
 experimental branch of Elerea [2], which provides first-class discrete
 streams to describe time-varying quantities, and the main game logic is
 described as a composition of streams instead of a world state
 transformer. Developing in this manner was an interesting experience,
 and I'll write about it in more detail over the weekend.

 All the best,

 Gergely

 [1] http://hackage.haskell.org/package/dow
 [2]
 http://hackage.haskell.org/packages/archive/elerea/1.2.3/doc/html/FRP-Elerea-Experimental-Simple.html

 --
 http://www.fastmail.fm - The professional email service

 ___
 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] How many Haskell Engineer I/II/IIIs are there?

2010-02-11 Thread Thomas Hartman
Hear hear.

But a few successful happstack private sector startups could change that...

2010/2/10 Jason Dusek jason.du...@gmail.com:
 2010/02/10 Roderick Ford develo...@live.com:
 A U.S. president would probably subsidize such a job-creating endeavor too!

  The US government generally subsidizes these kinds of things
  through DoD spending (and a few NSF grants). That is probably
  hard to get into.

 --
 Jason Dusek
 ___
 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] Re: sendfile leaking descriptors on Linux?

2010-02-09 Thread Thomas Hartman
Matt, have you seen this thread?

Jeremy, are you saying this a bug in the sendfile library on hackage,
or something underlying?

thomas.

2010/2/9 Jeremy Shaw jer...@n-heptane.com:
 On Sun, Feb 7, 2010 at 9:22 AM, Bardur Arantsson s...@scientician.net
 wrote:

 True, it is perhaps technically not a bug, but it is certainly a
 misfeature since there is no easy way (at least AFAICT) to discover that
 something bad has happened for the file descriptor and act accordingly.
 AFAICT any solution would have to be based on a separate thread which either
 1) checks the FD periodically somehow, or 2) simply lets the thread doing
 the threadWaitWrite time out after a set period of inactivity. Neither is
 very optimal.

 Either way, I'd certainly expect the sendfile library to work around this
 somehow such that this situation doesn't occur. I'm just having a hard time
 thinking up a good solution :).

 Well, it is certainly a bug in sendfile that needs to be fixed. I'm not sure
 how to fix it either. If we can simplify the test case, we can ask Simon
 Marlow..
 - jeremy
 ___
 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] Re: sendfile leaking descriptors on Linux?

2010-02-06 Thread Thomas Hartman
me too.

2010/2/5 MightyByte mightyb...@gmail.com:
 I've been seeing a steady stream of similar resource vanished messages
 for as long as I've been running my happstack app.  This message I get
 is this:

 socket: 58: hClose: resource vanished (Broken pipe)

 I run my app from a shell script inside a while true loop, so it
 automatically gets restarted if it crashes.  This incurs no more than
 a few seconds of down time.  Since that is acceptable for my
 application, I've never put much effort into investigating the issue.
 But I don't think the resource vanished error results in program
 termination.  When I have looked into it, I've had similar trouble
 reproducing it.  Clients such as wget and firefox don't seem to cause
 the problem.  If I remember correctly it only happens with IE.

 On Fri, Feb 5, 2010 at 2:56 AM, Bardur Arantsson s...@scientician.net wrote:
 Jeremy Shaw wrote:

 Actually,

 We should start by testing if native sendfile leaks file descriptors even
 when the whole file is sent. We have a test suite, but I am not sure if it
 tests for file handle leaking...


 I should have posted this earlier, but the exact message I'm seeing in the
 case where the Bad Client disconnects is this:

   hums: Network.Socket.SendFile.Linux: resource vanished (Broken pipe)

 Oddly, I haven't been able to reproduce this using a wget client with a ^C
 during transfer. When I disconnect wget with ^C or pkill wget or even
 pkill -9 wget, I get this message:

  hums: Network.Socket.SendFile.Linux: resource vanished (Connection reset by
 peer)

 (and no leak, as observed by lsof | grep hums).

 So there appears to be some vital difference between the handling of the two
 cases.

 Another observation which may be useful:

 Before the sendfile' API change (Handle - FilePath) in sendfile-0.6.x, my
 code used withFile to open the file and to ensure that it was closed. So
 it seems that withBinaryFile *should* also be fine. Unless the Broken pipe
 error somehow escapes the scope without causing a close.

 I don't have time to dig more right now, but I'll try to see if I can find
 out more later.

 Cheers,

 ___
 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] sendfile leaking descriptors on Linux?

2010-02-04 Thread Thomas Hartman
Do you have a test script to reproduce the behavior?

I am interested in this patch-tag uses sendfile (via happstack) to
serve static data, and I'd like to know if I'm affected by this.

2010/2/4 Bardur Arantsson s...@scientician.net:
 Hi all,

 I've been using the sendfile package off Hackage, but it seems to be leaking
 file descriptors when using the Linux-native build.

 What's happening in my specific case is the following:

   1) client requests a range of a file
   2) server starts sending the range
   3) client disconnects before receiving the whole file

 This happens over and over with the client requesting different ranges of
 the file (so the client does make progress).

 If I use the portable build of the sendfile package, everything works fine
 for hours and hours of this happening.

 If I use the Linux-native build of the sendfile package, the server
 will eventually run out of file descriptors. According to lsof the files
 that are being kept open are the data files being sent in 2) above.

 This is on GHC 6.10.x (Ubuntu).

 Is anyone else seeing this? Anyone got any idea what's going on?

 Cheers,

 ___
 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] where is the eros distribution

2010-01-23 Thread Thomas Hartman
I was inspired by the google tech talk and would like to install and
play with eros, but the

http://darcs.haskell.org/packages/Eros/dist/

address pointed to at

http://www.haskell.org/haskellwiki/Eros

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


[Haskell-cafe] unexpected behavior from filterM doesFileExist = getDirectoryContents

2010-01-09 Thread Thomas Hartman
Can somebody explain this?

 getDirectoryContents inD

[..,#sanity.txt#,.,sanity.txt,etc.txt,patchTagDir.txt,jail.txt,notjail.txt,alldata.txt,allobjs.txt,namesNSizes.txt]

 filterM doesFileExist = getDirectoryContents inD

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


Re: [Haskell-cafe] unexpected behavior from filterM doesFileExist = getDirectoryContents

2010-01-09 Thread Thomas Hartman
Thanks, that was it.

Dud question.

2010/1/9 Brandon S. Allbery KF8NH allb...@ece.cmu.edu:
 On Jan 10, 2010, at 00:24 , Thomas Hartman wrote:

 Can somebody explain this?

 getDirectoryContents inD

 [..,#sanity
 .txt
 #,.,sanity
 .txt
 ,etc
 .txt
 ,patchTagDir
 .txt
 ,jail
 .txt,notjail.txt,alldata.txt,allobjs.txt,namesNSizes.txt]

 filterM doesFileExist = getDirectoryContents inD

 [sanity.txt]


 My first guess is that inD isn't .; getDirectoryContents doesn't fully
 qualify the names it returns, so doesFileExist looks in the current
 directory for the bare names returned.

 --
 brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
 system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
 electrical and computer engineering, carnegie mellon university    KF8NH



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


[Haskell-cafe] unexpected behavior / bug in try . System.FilePath.Find.findWithHandler

2010-01-05 Thread Thomas Hartman
say you want to execute a find function, but abort the computation if
it hits any snags, such as an unreadable directory (eg chmod -R a-r
dir).

Currently try . System.FilePath.Find.findWithHandler

will return an exception wrapped in Right, which seems Wrong. For sure
it will just get ignored if wrapped in an ErrorT computation and I
suspect this could lead to other glitchy/unexpected behavior when used
in sysadmin scripts.

You do get the expected exception wrapped in Left for certain errors
(such as a missing directory), which adds to the confusion.

Probable fix: you get the expected behavior if you remove
unsafeInterleaveIO from findWithHandler. Does this seem like a
reasonable thing to suggest to librar...@haskell?

Hacky fix: I haven't actually done this, but I suppose you could trap
stdout or stderr, since the exception does get printed although it's
not reflected in the result type of the computation.

demo of problem:

import qualified System.FilePath.Find as F
import System.FilePath.Find
import System.IO.Error

abort path err = fail $ path ++  ,  ++ (show err)

prot = /home/thartman/protected -- a protected (unreadable) dir

{-
want result =
  Left user error (/home/thartman/protected , user error
(/home/thartman/protected , /home/thartman/protected:
getDirectoryContents: permission denied (Permission denied)))
but get result
  Right *** Exception: user error (/home/thartman/protected ,
/home/thartman/protected: getDirectoryContents: permission denied
(Permission denied))
which means, for example, you would miss the error if you wrapped this
in an ErrorT
there is probably a workaround from reading stderr, since it does get
printed out, but this is awkward compared to just catching the error
the right way
  and certainly feels like unexpected behavior
Possible fix: you get the expected behavior if you remove
unsafeInterleaveIO from System.FilePath.Find.findWithHandlers
  don't know why this fixes the problem, I was just messing around
  I don't know if this breaks anything else, but I was unable to find
any breakage when I did a simple test on an unprotected directory
  What is the gain from unsafeInterleaveIO, and can it be nixed?
-}
tprot = try . findWithHandler abort (return True) (return True) $ prot

tunprot = return . either (error . show) (length) =  ( try $
findWithHandler abort (return True) (return True) unprot )

unprot = /home/thartman/unprot



-- 
Need somewhere to put your code? http://patch-tag.com
Want to build a webapp? http://happstack.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] What about adding a wiki for each haskell project?

2009-12-12 Thread Thomas Hartman
patch-tag.com has wikis now.

They are some buggy behaviors I still need to address so I haven't blogged
or otherwise drawn attention to it (arrrg) but my hope is that, quite soon,
this will be quite slick and quite useful.

2009/12/11 Marc Weber marco-owe...@gmx.de

 hackage is success because:
 a) many (most) people do use it (by uploading packages)
 b) it is a comprehensive list of availible packages if not the most
comprehensive one

 Duncan, can you write about your concerns briefly why some maintainers may
 dislike
 this idea ?

 Hackage is missing one feature:
 It is very static. I mean if you have a patch or a question or a comment
 you have to lookup the darcs repository, write the patch then contact
 the author and wait.. If the author replies everything is fine.
 If he doesn't you don't know what to do. And if he does your commitment
 still doesn't show up on hackage.

 Using a wiki page for each project enables anybody to add comments.
 I'm thinking about this kind of comments:

  Interlude doesn't work for me. It looks like the interlude.h file
  passes a tuple to the reportError function which doesn't expect a tuple.
  You can fix it by removing the , in the .h file.
  Try this patch:

 http://github.com/MarcWeber/haskell-nix-overlay/blob/master/patches/interlude-0.1.1.patch
  

  Of course I mailed the author. Looking at the package again I noticed
  that it was uploaded by someone else: GwernBranwen.
  gwern on #haskell told me that the author is responsive so I'll just
  wait some days, but others will try and fail as well.
  If the other person is new to haskell he may not find the fix
  fast. He just wants to know which of the heads is causing trouble..

 Another use case would be users adding
 If you're interested in this topic also have a look at XXX

 Yet another use case is someone figuring out that function X was removed
 in version Y. He could than add a note

 x vanished since v.10 and everybody who wants to update cabal dependency
 constraints doesn't have to download the darcs repo to figure out that
 he should use package = v.10 .

 Of course contents of wiki pages may be totally wrong because the
 contents were written by people knowing the package less than the
 maintainers and authors. But everyone knows this and will take care.

 This wiki can server as fail over if the maintainer is on holiday.

 This wiki page will prevent people blogging about packages and benchmark
 results anywhere on the internet. So it's much more likely that this
 information is read and maintained.
 If you use google to look for bug fixes or such you may have success.
 But very often you end up reading pages dated 3 years ago which are
 outdated.

 This wiki page would be I simple effective way letting users annotate
 packages.

 Costs: Make hackage add one link.
 It would look like this: http://mawercer.de/~marc/hackage-link-example.jpg
 This link should point to the existing haskell wiki on haskell.org:
 http://haskell.org/haskellwiki/project-name-without-version


 Even if the maintainer is availible 24/h a day he won't upload a new
 minor version to hackage for each change. But maybe he'll paste a small
 note that the darcs repo is more up to date fixing issue x/y.
 You don't want to upload a new version because you added some
 documentation.
 Why don't you want to do that ?
 It's because hackage will keep every version which was uploaded once by
 design. Having 50 versions of one package just causes much more work for
 tools such as cabal install or hack-nix. Figuring out a solution to
 install all packages is hard enough.

 Maintainers can create the wiki page and subscribe to change
 notifications. So I don't think it'll be that much work for them to keep
 an eye on those wiki pages.

 How do you think about it?
 It's about centralizing information and saving your and my time.
 Many packages aready do have a wiki page. So why not make it easier for
 all to add one?

 Thoughts ?

 Currently my goal is updating some common packages so that they use
 extensible exceptions and base4.
 But when working on some patches I'd like to tell people that I'm doing
 so. I can't in an easy way. That's why I'm starting this thread.

 Marc Weber
 ___
 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] Howto start a bigger project

2009-11-16 Thread Thomas Hartman
How about patch-tag?

It's built with haskell (happstack), and one of its founding goals is to
promote the use of haskell in real world so you're sure to be surrounded by
like minded people.

And wikis are about to go live so you could help beta test that feature too
:)

thomas.

Am 16. November 2009 12:15 schrieb Günther Schmidt gue.schm...@web.de:

 Hi all,

 I'm stuck with a problem where I need serious help from other haskellers,
 in particular those that participate here on this list. It's a rather big
 project and I will need to set it up in an organized way, something with a
 blog, web page or other means.

 I tried to solve it by myself while asking the occasional question here but
 that turned out to be ineefective. The problem as such is certainly of
 interest for just about any programmer who is using Haskell for real world
 programming too.

 In short, to get started I'd appreciate some tips how to set this up.

 Günther

 ___
 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] Re: [Haskell] ANNOUNCE: control-monad-exception 0.5 with monadic call traces

2009-11-03 Thread Thomas Hartman
When using happstack, I find it really annoying to get a Prelude.head:
null list error (or similar) in my web browser window because
somewhere, some library used something unsafe -- and of course, since
this is haskell, no stack trace.

if c-m-e can offer benefits around this, I would be very interested in
adopting it.

thomas.

2009/11/3 Henning Thielemann lemm...@henning-thielemann.de:
 Jose Iborra schrieb:
 Folks,

 I'm happy to announce a new release of control-monad-exception with
 monadic call traces,
 available in Hackage. Grab it now while it is still online!

 Monadic stack traces are described in detail in a blog post [1].

 In short, what this means for your code is the ability to generate
 errors like this:

 500 Internal Server Error
 The CGI server failed with the following error:
 DeleteException (BmPK 2009-10-26 19:39:51.031297 UTC Testing RPO)
  in deleteBenchmarkFromPK,
 NarradarBenchmarkDB(src/NarradarBenchmarkDB.hs): (186, 44)
     deleteBenchmarkFromPK,
 NarradarBenchmarkDB(src/NarradarBenchmarkDB.hs): (186, 25)
     deleteBenchmarkFromPK,
 NarradarBenchmarkDB(src/NarradarBenchmarkDB.hs): (184, 17)
     deleteBenchmarkFromPK,
 NarradarBenchmarkDB(src/NarradarBenchmarkDB.hs): (180, 90)
     deleteTests, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs):
 (108, 3)
     deleteTests, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs):
 (106, 20)
     cgiMain, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs): (52, 33)
     cgiMain, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs): (52, 30)
     cgiMain, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs): (50, 9)
     cgiMain, NarradarBenchmarkCGI(src/NarradarBenchmarkCGI.hs): (46, 11)

 Sure, this is a nice functionality. But isn't it about debugging, not
 exception handling? Internal Server Error means to me, the server has a
 bug, thus we want to know, how to reproduce it, thus the stack trace.
 For handling expected irregularites, what exceptions are, you would not
 need that, right?

 ___
 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] hackage is down.

2009-11-01 Thread Thomas Hartman
http://hackage.haskell.org
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] creating documentation links failed with cabal install --haddock-options=--hyperlink-source. is this a bug?

2009-10-31 Thread Thomas Hartman
cabal haddock -–hyperlink-source

installs documentation with links to source code, which also be on by defualt.

cabal install –haddock-options=–hyperlink source

does not install hyperlinked source.

cabal install –haddock-options=-–hyperlink sourceblehblehbleh

doesn’t throw an error, which suggests to me that the first command
might also be passing the flags with an error.

Whatever the case, seems to me the examples section in cabal --help
should really include examples using --with-PROG and --PROG-options. I
can't find a good one online.

fwiw, cabal install --haddock-option=hyperlink-source DID generate an
error in the output: target `hyperlink-source' is not a module name or
a source file

also, blogged about this here:
http://blog.patch-tag.com/2009/10/23/cabal-install-a-package-with-documentation
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Upgrading an app from happstack 0.1 to happstack 0.3

2009-10-30 Thread Thomas Hartman
Upgrading an app from happstack 0.1 to happstack 0.3?

Save yourself a few minutes and read this first.

http://blog.patch-tag.com/2009/10/30/migrating-from-happstack-0-1-to-happstack-0-3/

-- 
Need somewhere to put your code? http://patch-tag.com
Want to build a webapp? http://happstack.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] any haskellers in chicago? Impromptu lakeview meetup tomorrow (tuesday) evening.

2009-10-26 Thread Thomas Hartman
I'm visiting chicago, and found one other haskeller interested in a
haskell meetup tomorrow 7:30 pm lakeview cafe intelligentsia. email
thomashartman1 at gmail if you'd like to hook up!

this is a relaxed occasion with no fixed agenda other than birds of a
feather flocking home.

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


[Haskell-cafe] Re: systemtimmetypeable: Workaround for lack of deriveable data instance in either System.Time or Data.Time.

2009-10-21 Thread Thomas Hartman
update:

on haskell reddit, dons suggested simply patching time. reasonable
enough, but I hit a glitch where the Data.Fixed (in base lib) was
missing a Data instance, and gave up when I couldn't find the source
repo for base. Is this simply part of ghc?

Anyways, that instance seems to be added in ghc 6.12 so probably a non
issue now or closer to it.

http://www.haskell.org/ghc/dist/current/docs/html/libraries/base/Data-Fixed.html

also, aavogton #haskell suggested

http://hpaste.org/fastcgi/hpaste.fcgi/view?id=11009#a11009

as a workaround for people using time on happstack earlier than 6.12,
probably nicer than the MyTime hack I created though it comes with a
bit more baggage.

I haven't upgraded to 6.12 but I would suggest that time now be made
Data Generics friendly if it hasn't already, since this is probably a
very simple change and would be helpful to happstack. If no one has
time to do this I'll try to get around to it when I upgrade to 6.12.

Also wouter swierstra suggested that standalone deriving (
http://www.haskell.org/ghc/docs/latest/html/users_guide/deriving.html#stand-alone-deriving
) could be helpful in this case but I'm not sure why, or even whether
this was for data-izing data.time or system.time or both.

Given all this I won't be uploading anything to hackage, and hopefully
the base libs + time will be data friendly soon enough.

thomas.

2009/10/19 Thomas Hartman tphya...@gmail.com:
 At

 http://osdir.com/ml/haskell-cafe@haskell.org/2009-10/msg00197.html

 I griped that the lack of Data-Derivable time values was causing me
 headache in happstack.

 In the proposed cabal package

 http://patch-tag.com/r/tphyahoo/systemtimetypeable/snapshot/current/content/pretty/systemtimetypeable.cabal

 I submit a workaround that, while probably not the ideal thing, has
 proved helpful to me.

 Basically, I use the type MyTime, which is data-deriveable, when
 working with Macid in happstack; and convert from System.Time and/or
 Data.Time with the accompanying utility functions when necessary.
 Perhaps the utility functions are useful on their own as well. I found
 it surprisingly hard to get from Data.Time values to System.Time
 values.

 Anyways, I am interested in what others think and, of course, patches
 and suggestions welcome.

 thomas.

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


[Haskell-cafe] Re: ghci can't find Paths_ module created by cabal

2009-10-21 Thread Thomas Hartman
from my bash hints file:

thart...@ubuntu:~/haskellInstalls/gititthartman_ghci_with_data_files
  Loading a package with data files in ghci
See 
http://neilmitchell.blogspot.com/2008/02/adding-data-files-using-cabal.html
Snip:

   The above method works well after a program has been installed,
but is harder to work with while developing a program. To alleviate
these problems, we can add our own Paths module to the program, for
example:


module Paths_hoogle where

getDataFileName :: FilePath - IO FilePath
getDataFileName = return

Place this module alongside all the other modules. While
developing the program our hand-created Paths module will be invoked,
which says the data is always in the current directory. When doing a
Cabal build, Cabal will choose its custom generated Paths module over
ours, and we get the benefits of Cabal managing our data.



2009/10/21 Robin Green gree...@greenrd.org:
 I'm trying to run cabal-install in ghci so I can run it under the ghci
 debugger. However I try it, though, I always get one of these two
 errors:

 /src/greenrd/darcs/cabal-install/Main.hs:70:17:
    Could not find module `Paths_cabal_install':
      Use -v to see a list of the files searched for.
 Failed, modules loaded: none.

 or

 command line:
    Could not find module `Main':
      Use -v to see a list of the files searched for.

 --
 Robin
 ___
 Libraries mailing list
 librar...@haskell.org
 http://www.haskell.org/mailman/listinfo/libraries

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


[Haskell-cafe] debugtracehelpers Re: traceM and traceShowM

2009-10-19 Thread Thomas Hartman
I have this and a couple other handy functions in

DebugTraceHelpers:

http://patch-tag.com/r/tphyahoo/DebugTraceHelpers/snapshot/current/content/pretty

hackage:

http://hackage.haskell.org/packages/archive/DebugTraceHelpers/0.12/doc/html/Debug-Trace-Helpers.html


2009/10/16 Martijn van Steenbergen mart...@van.steenbergen.nl:
 Hello,

 I propose the addition of the following two functions to module Debug.Trace:

 traceM :: Monad m = String - m ()
 traceM msg = trace msg (return ())

 traceShowM :: (Show a, Monad m) = a - m ()
 traceShowM = traceM . show

 These functions allow tracing in any do-block. I often define them myself; I
 think they are useful in general.

 Deadline: 23 October 2009.

 Martijn.
 ___
 Libraries mailing list
 librar...@haskell.org
 http://www.haskell.org/mailman/listinfo/libraries

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


[Haskell-cafe] systemtimmetypeable: Workaround for lack of deriveable data instance in either System.Time or Data.Time.

2009-10-19 Thread Thomas Hartman
At

http://osdir.com/ml/haskell-cafe@haskell.org/2009-10/msg00197.html

I griped that the lack of Data-Derivable time values was causing me
headache in happstack.

In the proposed cabal package

http://patch-tag.com/r/tphyahoo/systemtimetypeable/snapshot/current/content/pretty/systemtimetypeable.cabal

I submit a workaround that, while probably not the ideal thing, has
proved helpful to me.

Basically, I use the type MyTime, which is data-deriveable, when
working with Macid in happstack; and convert from System.Time and/or
Data.Time with the accompanying utility functions when necessary.
Perhaps the utility functions are useful on their own as well. I found
it surprisingly hard to get from Data.Time values to System.Time
values.

Anyways, I am interested in what others think and, of course, patches
and suggestions welcome.

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


[Haskell-cafe] Why does replicateM (10^6) $ return 0 produce output in the IO monad, but overflow the maybe monad?

2009-10-14 Thread Thomas Hartman
-- Why does replicateM (10^6) $ return 0 produce output in the IO
monad, but overflow the maybe monad?

iterateNTimes i f x = foldr (.) id (replicate i f) $ x
tntIO :: IO Int
-- same as replicateM (10^6) $ return 0, same as sequence . replicate
(10^6) $ return 0
tntIO = return . head = (iterateNTimes (10^6) (mcons . return $ 0)
(return [])) -- produces output
tntMb :: Maybe Int -- overflows
tntMb = return . head = (iterateNTimes (10^6) (mcons . return $ 0)
(return [])) -- stack overflow

-- equivalently: mcons m ms = (:) $ m * ms
mcons m ms = ap (liftM (:) m) $ ms

I guess the maybe version builds up a huge chain of unevaluated thunks
somewhere, that's usually the reason. But specifically where and why,
and why doesn't IO do the same thing?

Equivalent, with 3 element list:

(mcons $ return $ 0 ) $ (mcons $ return $ 0) $ (mcons $ return $ 0) $
(return [])
(ap . liftM (:) . return $ 0 ) $ (ap . liftM (:) . return $ 0) $ (ap .
liftM (:) . return $ 0) $ (return [])
(ap $ liftM (:) $ return $ 0 ) $ (ap $ liftM (:) $ return $ 0) $ (ap $
liftM (:) $ return $ 0) $ (return [])

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


[Haskell-cafe] why does iterateNTimes (10^6) (ap . liftM (:) . return $ 0) (return []) produce output in the IO monad, but stack overflow in the maybe monad?

2009-10-13 Thread Thomas Hartman
Can someone explain why the one stack overflows and the other one doesn't?

iterateNTimes i f x = foldr (.) id (replicate i f) $ x
tntIO :: IO Int
-- same as replicateM (10^6) $ return 0 , and same as sequence .
replicate (10^6) $ return 0
tntIO = iterateNTimes (10^6) (ap . liftM (:) . return $ ) (return [])
-- produces output
tntMb :: Maybe Int -- overflows
tntMb = iterateNTimes (10^6) (ap . liftM (:) . return $ ) (return [])
-- stack overflow
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: why does iterateNTimes (10^6) (ap . liftM (:) . return $ 0) (return []) produce output in the IO monad, but stack overflow in the maybe monad?

2009-10-13 Thread Thomas Hartman
correction, should be:

iterateNTimes i f x = foldr (.) id (replicate i f) $ x
tntIO :: IO Int
-- same as replicateM (10^6) $ return 0
tntIO = return . head = (iterateNTimes (10^6) (ap . liftM (:) .
return $ 0) (return [])) -- produces output
tntMb :: Maybe Int -- overflows
tntMb = return . head = (iterateNTimes (10^6) (ap . liftM (:) .
return $ 0) (return [])) -- stack overflow

which now compiles.

2009/10/13 Thomas Hartman tphya...@gmail.com:
 Can someone explain why the one stack overflows and the other one doesn't?

 iterateNTimes i f x = foldr (.) id (replicate i f) $ x
 tntIO :: IO Int
 -- same as replicateM (10^6) $ return 0 , and same as sequence .
 replicate (10^6) $ return 0
 tntIO = iterateNTimes (10^6) (ap . liftM (:) . return $ ) (return [])
 -- produces output
 tntMb :: Maybe Int -- overflows
 tntMb = iterateNTimes (10^6) (ap . liftM (:) . return $ ) (return [])
 -- stack overflow

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


Re: [Haskell-cafe] How do I get this done in constant mem?

2009-10-10 Thread Thomas Hartman
I don't know if this counts but how about

import Control.Applicative
import Control.Monad
import Random
import Data.List

main'' i j = replicateM j $ maximum' $ (replicateM i . randomRIO $ (0,10^9))
maximum' = foldl1' max
t = main'' (10^4) 5


2009/10/9  mf-hcafe-15c311...@etc-network.de:


 Hi all,

 I think there is something about my use of the IO monad that bites me,
 but I am bored of staring at the code, so here you g.  The code goes
 through a list of records and collects the maximum in each record
 position.


 -- test.hs
 import Random
 import System.Environment (getArgs)
 import System.IO (putStr)

 samples :: Int - Int - IO [[Double]]
 samples i j = sequence . replicate i . sequence . replicate j $ randomRIO (0, 
 1000 ** 3)

 maxima :: [[Double]] - [Double]
 maxima samples@(_:_) = foldr (\ x y - map (uncurry max) $ zip x y) (head 
 samples) (tail samples)

 main = do
  args - getArgs
  x - samples (read (head args)) 5
  putStr . (++ \n) . show $ maxima x


 I would expect this to take constant memory (foldr as well as foldl),
 but this is what happens:


 $ ghc -prof --make -O9 -o test test.hs
 [1 of 1] Compiling Main             ( test.hs, test.o )
 Linking test ...
 $ ./test 100 +RTS -p
 [9.881155955344708e8,9.910336352165401e8,9.71000686630374e8,9.968532576451201e8,9.996200333115692e8]
 $ grep 'total alloc' test.prof
        total alloc =     744,180 bytes  (excludes profiling overheads)
 $ ./test 1 +RTS -p
 [9.996199711457872e8,9.998928358545277e8,9.99960283632381e8,9.999707142123885e8,9.998952151508758e8]
 $ grep 'total alloc' test.prof
        total alloc =  64,777,692 bytes  (excludes profiling overheads)
 $ ./test 100 +RTS -p
 Stack space overflow: current size 8388608 bytes.
 Use `+RTS -Ksize' to increase it.
 $


 so...

 does sequence somehow force the entire list of monads into evaluation
 before the head of the result list can be used?  what can i do to
 implement this in constant memory?

 thanks!
 matthias
 ___
 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] How do I get this done in constant mem?

2009-10-10 Thread Thomas Hartman
 Yes, you should not do this in IO.  That requires the entire
 computation to finish before the result can be used.

Not really the entire computation though... whnf, no?

main = do
  let thunks :: IO [Int]
  thunks = (sequence . replicate (10^6) $ (randomRIO (0,10^9)))
  putStrLn . show . head = thunks -- prints
  putStrLn . show . last = thunks -- overflows

In the case of [[num]] from the top post, I belive that would be the
first complete list.


2009/10/9 Luke Palmer lrpal...@gmail.com:
 On Fri, Oct 9, 2009 at 2:05 PM,  mf-hcafe-15c311...@etc-network.de wrote:
 Hi all,

 I think there is something about my use of the IO monad that bites me,
 but I am bored of staring at the code, so here you g.  The code goes
 through a list of records and collects the maximum in each record
 position.


 -- test.hs
 import Random
 import System.Environment (getArgs)
 import System.IO (putStr)

 samples :: Int - Int - IO [[Double]]
 samples i j = sequence . replicate i . sequence . replicate j $ randomRIO 
 (0, 1000 ** 3)

 Yes, you should not do this in IO.  That requires the entire
 computation to finish before the result can be used.  This computation
 should be pure and lazy.

 It is possible, using split (and I believe not without it, unless you
 use mkStdGen), to make a 2D list of randoms where the random
 generation matches exactly the structure of the list.

 splits :: (RandomGen g) = Int - g - [g]
 splits 0 _ = []
 splits n g = let (g1,g2) = split g in g1 : splits (n-1) g2

 samples :: (RandomGen g) = Int - Int - g - [[Double]]
 samples i j gen = map row (splits i gen)
    where
    row g = take j (randomRs (0, 10^9) g)

 In fact, we could omit all these counts and make an infinite 2D list,
 which you can cull in the client code.

 splits :: (RandomGen g) = g - [g]
 splits g = let (g1,g2) = split g in g1 : splits g2

 samples :: (RandomGen g) = g - [[Double]]
 samples = map row . splits
    where
    row = randomRs (0, 10^9)

 I find the latter to be more straightforward and obvious.  Maintaining
 the laziness here is a fairly subtle thing, so study, perturb, try to
 write it yourself in different ways, etc.

 maxima :: [[Double]] - [Double]
 maxima samples@(_:_) = foldr (\ x y - map (uncurry max) $ zip x y) (head 
 samples) (tail samples)

 FWIW, This function has a beautiful alternate definition:

 maxima :: [[Double]] - [Double]
 maxima = map maximum . transpose

 main = do
  args - getArgs
  x - samples (read (head args)) 5
  putStr . (++ \n) . show $ maxima x


 I would expect this to take constant memory (foldr as well as foldl),
 but this is what happens:


 $ ghc -prof --make -O9 -o test test.hs
 [1 of 1] Compiling Main             ( test.hs, test.o )
 Linking test ...
 $ ./test 100 +RTS -p
 [9.881155955344708e8,9.910336352165401e8,9.71000686630374e8,9.968532576451201e8,9.996200333115692e8]
 $ grep 'total alloc' test.prof
        total alloc =     744,180 bytes  (excludes profiling overheads)
 $ ./test 1 +RTS -p
 [9.996199711457872e8,9.998928358545277e8,9.99960283632381e8,9.999707142123885e8,9.998952151508758e8]
 $ grep 'total alloc' test.prof
        total alloc =  64,777,692 bytes  (excludes profiling overheads)
 $ ./test 100 +RTS -p
 Stack space overflow: current size 8388608 bytes.
 Use `+RTS -Ksize' to increase it.
 $


 so...

 does sequence somehow force the entire list of monads into evaluation
 before the head of the result list can be used?

 Yep.  IO is completely strict; in some sense the same as call by
 value (don't take the analogy too far).  Rule of thumb: keep your
 distance from it ;-)
 ___
 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] How do I get this done in constant mem?

2009-10-10 Thread Thomas Hartman
also, looking at the following, it does seem to me that it is sequence
that is too strict, and not IO that is to blame, as the Maybe monad
has the same behavior:

t5IO, t6IO :: IO Int
t5Maybe, t6Maybe :: Maybe Int
t5 = return . head = sequence [return 1, undefined]
t6 = return . head = return [1,undefined]
t5IO = t5
t5Maybe = t5
t6IO = t6
t6Maybe = t6

*Main t5IO
*** Exception: Prelude.undefined
*Main t5Maybe
*** Exception: Prelude.undefined
*Main t6IO
1
*Main t6Maybe
Just 1

2009/10/10 Thomas Hartman tphya...@gmail.com:
 Yes, you should not do this in IO.  That requires the entire
 computation to finish before the result can be used.

 Not really the entire computation though... whnf, no?

 main = do
  let thunks :: IO [Int]
  thunks = (sequence . replicate (10^6) $ (randomRIO (0,10^9)))
  putStrLn . show . head = thunks -- prints
  putStrLn . show . last = thunks -- overflows

 In the case of [[num]] from the top post, I belive that would be the
 first complete list.


 2009/10/9 Luke Palmer lrpal...@gmail.com:
 On Fri, Oct 9, 2009 at 2:05 PM,  mf-hcafe-15c311...@etc-network.de wrote:
 Hi all,

 I think there is something about my use of the IO monad that bites me,
 but I am bored of staring at the code, so here you g.  The code goes
 through a list of records and collects the maximum in each record
 position.


 -- test.hs
 import Random
 import System.Environment (getArgs)
 import System.IO (putStr)

 samples :: Int - Int - IO [[Double]]
 samples i j = sequence . replicate i . sequence . replicate j $ randomRIO 
 (0, 1000 ** 3)

 Yes, you should not do this in IO.  That requires the entire
 computation to finish before the result can be used.  This computation
 should be pure and lazy.

 It is possible, using split (and I believe not without it, unless you
 use mkStdGen), to make a 2D list of randoms where the random
 generation matches exactly the structure of the list.

 splits :: (RandomGen g) = Int - g - [g]
 splits 0 _ = []
 splits n g = let (g1,g2) = split g in g1 : splits (n-1) g2

 samples :: (RandomGen g) = Int - Int - g - [[Double]]
 samples i j gen = map row (splits i gen)
    where
    row g = take j (randomRs (0, 10^9) g)

 In fact, we could omit all these counts and make an infinite 2D list,
 which you can cull in the client code.

 splits :: (RandomGen g) = g - [g]
 splits g = let (g1,g2) = split g in g1 : splits g2

 samples :: (RandomGen g) = g - [[Double]]
 samples = map row . splits
    where
    row = randomRs (0, 10^9)

 I find the latter to be more straightforward and obvious.  Maintaining
 the laziness here is a fairly subtle thing, so study, perturb, try to
 write it yourself in different ways, etc.

 maxima :: [[Double]] - [Double]
 maxima samples@(_:_) = foldr (\ x y - map (uncurry max) $ zip x y) (head 
 samples) (tail samples)

 FWIW, This function has a beautiful alternate definition:

 maxima :: [[Double]] - [Double]
 maxima = map maximum . transpose

 main = do
  args - getArgs
  x - samples (read (head args)) 5
  putStr . (++ \n) . show $ maxima x


 I would expect this to take constant memory (foldr as well as foldl),
 but this is what happens:


 $ ghc -prof --make -O9 -o test test.hs
 [1 of 1] Compiling Main             ( test.hs, test.o )
 Linking test ...
 $ ./test 100 +RTS -p
 [9.881155955344708e8,9.910336352165401e8,9.71000686630374e8,9.968532576451201e8,9.996200333115692e8]
 $ grep 'total alloc' test.prof
        total alloc =     744,180 bytes  (excludes profiling overheads)
 $ ./test 1 +RTS -p
 [9.996199711457872e8,9.998928358545277e8,9.99960283632381e8,9.999707142123885e8,9.998952151508758e8]
 $ grep 'total alloc' test.prof
        total alloc =  64,777,692 bytes  (excludes profiling overheads)
 $ ./test 100 +RTS -p
 Stack space overflow: current size 8388608 bytes.
 Use `+RTS -Ksize' to increase it.
 $


 so...

 does sequence somehow force the entire list of monads into evaluation
 before the head of the result list can be used?

 Yep.  IO is completely strict; in some sense the same as call by
 value (don't take the analogy too far).  Rule of thumb: keep your
 distance from it ;-)
 ___
 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] suggestions for doing date/time values with Data.Generics ?

2009-10-05 Thread Thomas Hartman
I want to patch the time package, which I darcs got head on. Goal is
to be able to do newtype deriving for UTCTime which I reckon is the
base time value, for use in happstack applications state.


basically, need instances for UTCTime, for Data and Typeable.

**
on #haskell:

patch-tag I just darcs got time package and attempted to install.
cabal
   install didn't work because missing configure fle. there's
a .ac
   file there, so I tried first autoconf, then cabal
   install. configure file got created, but failed with
   config.status: error: cannot find input file:
   include/HsTimeConfig.h.in. now what?
patch-tag my goal is to patch time package so can do data generics deriving.

Berengal patch-tag, use System.Time instead?
* Berengal shrugs and sighs [12:20]
patch-tag could try that...
*** o-regalia (n=o-reg...@host-0-130.mimpvbg.clients.pavlovmedia.com)
has
   quit: Lost terminal
Berengal It already has a Serializeable instance defined in one of
the
  happstack modules, so there's probably a Typeable and Data
instance
  somewhere as well



Berengal patch-tag, unfortunately, UTCTime has a component of a
hidden
  datatype which isn't an instance of Typeable or Data, and
since
  it's not exported it's impossible to create the instance as well
Berengal If it were exported, it'd be pretty easy
patch-tag hw can I use UTCTime, deriving Typeable and Data? (want to
use
   UTCTime in happstack).
patch-tag http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=4278#a4278
patch-tag I guess I should have said I'd like to use newtype
deriving rather
   than define instance myself if that's possible.


Berengal patch-tag, that's possible, but could break other things.
The
  correct solution is to patch the existing package, but that
takes
  time
Berengal patch-tag, Day, or something. Can't remember off the top of my head
*** paolino (n=paol...@87.7.161.162) has quit: Leaving.
ski Philonous : if you can't implement both operations (satisfying
laws),
 though, it is probably better to make a new class [12:09]
patch-tag Berengal: a package is hidden if when you do :info in
ghci, it
   comes out as fully qualified, right?
patch-tag pity also that newtype deriving doesn't give you a nicer
error
   message like deriving choked at type blah
Berengal patch-tag, it comes fully qualified if it's not imported,
so you'll
  have to try to import it to see if it's really hidden[12:10]


*

Seems like the right thing to do is patch the time package anyway.


File Edit Options Buffers Tools Haskell Help
{-# LANGUAGE DeriveDataTypeable #-}
module TypeableTime where

import Data.Time
import Data.Data
import Data.Generics
import Data.Typeable

-- doesn't work
--data MyUTCTime = MyUTCTime UTCTime
--   deriving (Typeable,Data)

-- should I work up to UTCTime by doing this...?
data MyDay = MyDay {toMyDayModifiedJulianDay :: Integer}
 deriving (Typeable,Data)

newtype MyString = MyString String
 deriving (Read,Show,Ord,Eq,Typeable,Data)

-- should I just modify time package? is this easier?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: suggestions for doing date/time values with Data.Generics ?

2009-10-05 Thread Thomas Hartman
fwiw, this s what I'm doing till I figure out a better way:

import System.Time
data MyTime = MyTime Integer Integer
  deriving (Typeable,Data)
myTimeToClockTime (MyTime a b) = TOD a b
myTimeFromClockTime (TOD a b) = MyTime a b

and use MyTime in the happstack state.

2009/10/5 Thomas Hartman tphya...@gmail.com:
 I want to patch the time package, which I darcs got head on. Goal is
 to be able to do newtype deriving for UTCTime which I reckon is the
 base time value, for use in happstack applications state.


 basically, need instances for UTCTime, for Data and Typeable.

 **
 on #haskell:

 patch-tag I just darcs got time package and attempted to install.
 cabal
           install didn't work because missing configure fle. there's
 a .ac
           file there, so I tried first autoconf, then cabal
           install. configure file got created, but failed with
           config.status: error: cannot find input file:
           include/HsTimeConfig.h.in. now what?
 patch-tag my goal is to patch time package so can do data generics deriving.

 Berengal patch-tag, use System.Time instead?
 * Berengal shrugs and sighs                                             
 [12:20]
 patch-tag could try that...
 *** o-regalia (n=o-reg...@host-0-130.mimpvbg.clients.pavlovmedia.com)
 has
   quit: Lost terminal
 Berengal It already has a Serializeable instance defined in one of
 the
          happstack modules, so there's probably a Typeable and Data
 instance
          somewhere as well



 Berengal patch-tag, unfortunately, UTCTime has a component of a
 hidden
          datatype which isn't an instance of Typeable or Data, and
 since
          it's not exported it's impossible to create the instance as well
 Berengal If it were exported, it'd be pretty easy
 patch-tag hw can I use UTCTime, deriving Typeable and Data? (want to
 use
           UTCTime in happstack).
 patch-tag http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=4278#a4278
 patch-tag I guess I should have said I'd like to use newtype
 deriving rather
           than define instance myself if that's possible.


 Berengal patch-tag, that's possible, but could break other things.
 The
          correct solution is to patch the existing package, but that
 takes
          time
 Berengal patch-tag, Day, or something. Can't remember off the top of my head
 *** paolino (n=paol...@87.7.161.162) has quit: Leaving.
 ski Philonous : if you can't implement both operations (satisfying
 laws),
     though, it is probably better to make a new class                 [12:09]
 patch-tag Berengal: a package is hidden if when you do :info in
 ghci, it
           comes out as fully qualified, right?
 patch-tag pity also that newtype deriving doesn't give you a nicer
 error
           message like deriving choked at type blah
 Berengal patch-tag, it comes fully qualified if it's not imported,
 so you'll
          have to try to import it to see if it's really hidden        [12:10]


 *

 Seems like the right thing to do is patch the time package anyway.


 File Edit Options Buffers Tools Haskell Help
 {-# LANGUAGE DeriveDataTypeable #-}
 module TypeableTime where

 import Data.Time
 import Data.Data
 import Data.Generics
 import Data.Typeable

 -- doesn't work
 --data MyUTCTime = MyUTCTime UTCTime
 --   deriving (Typeable,Data)

 -- should I work up to UTCTime by doing this...?
 data MyDay = MyDay {toMyDayModifiedJulianDay :: Integer}
  deriving (Typeable,Data)

 newtype MyString = MyString String
  deriving (Read,Show,Ord,Eq,Typeable,Data)

 -- should I just modify time package? is this easier?

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


Re: [Haskell-cafe] Market Place for Haskell development teams?

2009-10-02 Thread Thomas Hartman
Hey, first of all, in terms of a platform for promoting haskell
commercially, happstutorial.com actually implements a job board.

Yeah, it's primitive and not feature complete, but on hackage, open
source, and ready for anyone who would like to work on it. (Currently
maintained by creighton hogg.)

This was my baby in 2008, when I was looking to foster happs for web
development, as a sort of smarter ruby on rails, which I am using in
the field in patch-tag.com.

2, the haskell-startup google group at

http://groups.google.com/group/haskell-startup

It's private, to encourage slightly more courageous business talk away
from the panoptic gaze of google, but I approve pretty much anyone who
doesn't want in and isn't a bot.

Yes. Let's create a world with more jobs for haskell developers, and
better software for everyone :)

thomas.


2009/10/1 Curt Sampson c...@starling-software.com:
 On 2009-09-29 13:18 +0200 (Tue), Alberto G. Corona  wrote:

 What is the vehicle that haskell can use to enter the mainstream?.

 Actually, I have one more thought on that: wait.

 I'd had the impression that Haskell was becoming fairly well known (if
 not yet heavily used, in comparison to languages like Java), but I just
 ran across some hard evidence for this.

 In the 32 languages ranked on http://www.langpop.com/ , Haskell
 consistently comes down near the bottom in the various rankings of
 use. (But hey, we're not so weird we're not in there!) But if you look
 down near the bottom, at the chart labeled Normalized Discussion Site
 Results, you'll notice that Haskell comes out sixth. Even trying to be
 more fair to the mainstream, and changing the weighting to drop Lambda
 the Ultimate completely (after all, they're just a bunch of academic
 wankers, right?) and bring IRC down to a contribution of 0.5 instead of
 1 (apparently those academic wankers have lots of time to chat online),
 Haskell still comes out tenth, with a score over a third that of the
 leader, Java, and close to half that of PHP and C (2nd and 3rd place,
 respectively).

 We've also got at least one undeniably good, production-quality compiler
 (which is more than PHP or Ruby can say), and have sold many tens of
 thousands, perhaps even hundreds of thousands, of books. At this point,
 I don't think many people (John A. De Goes excepted) are looking at
 people writing major applications in Haskell as if they're aliens living
 on another planet.

 Haskell is in the mainstream already as far as being taken seriously;
 most of the complaints I'm seeing seem to be grasping at the same kinds
 of straws that the anti-Java guys were back in the late '90s. (It's
 hopeless if it uses garbage collection.)

 We've even got our own over-hyped, under-utilized supposed benefit
 (it's good for multicore).

 The main whinging seems to be about libraries, of which we have only
 1585 on hackage.

 Compare with RubyForge, which has 2059 projects in beta or better
 status, or 2961 if we include alpha as well. The Ruby Application
 Archive has 1768 projects; I have no idea how much overlap there is, or
 how many of these are real.

 I think we just need to sit tight for a couple of years.

 cjs
 --
 Curt Sampson       c...@starling-software.com        +81 90 7737 2974
           Functional programming in all senses of the word:
                   http://www.starling-software.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] Market Place for Haskell development teams?

2009-10-02 Thread Thomas Hartman
correction, happstutorial is now tutorial.happstack.com.

2009/10/2 Thomas Hartman tphya...@gmail.com:
 Hey, first of all, in terms of a platform for promoting haskell
 commercially, happstutorial.com actually implements a job board.

 Yeah, it's primitive and not feature complete, but on hackage, open
 source, and ready for anyone who would like to work on it. (Currently
 maintained by creighton hogg.)

 This was my baby in 2008, when I was looking to foster happs for web
 development, as a sort of smarter ruby on rails, which I am using in
 the field in patch-tag.com.

 2, the haskell-startup google group at

 http://groups.google.com/group/haskell-startup

 It's private, to encourage slightly more courageous business talk away
 from the panoptic gaze of google, but I approve pretty much anyone who
 doesn't want in and isn't a bot.

 Yes. Let's create a world with more jobs for haskell developers, and
 better software for everyone :)

 thomas.


 2009/10/1 Curt Sampson c...@starling-software.com:
 On 2009-09-29 13:18 +0200 (Tue), Alberto G. Corona  wrote:

 What is the vehicle that haskell can use to enter the mainstream?.

 Actually, I have one more thought on that: wait.

 I'd had the impression that Haskell was becoming fairly well known (if
 not yet heavily used, in comparison to languages like Java), but I just
 ran across some hard evidence for this.

 In the 32 languages ranked on http://www.langpop.com/ , Haskell
 consistently comes down near the bottom in the various rankings of
 use. (But hey, we're not so weird we're not in there!) But if you look
 down near the bottom, at the chart labeled Normalized Discussion Site
 Results, you'll notice that Haskell comes out sixth. Even trying to be
 more fair to the mainstream, and changing the weighting to drop Lambda
 the Ultimate completely (after all, they're just a bunch of academic
 wankers, right?) and bring IRC down to a contribution of 0.5 instead of
 1 (apparently those academic wankers have lots of time to chat online),
 Haskell still comes out tenth, with a score over a third that of the
 leader, Java, and close to half that of PHP and C (2nd and 3rd place,
 respectively).

 We've also got at least one undeniably good, production-quality compiler
 (which is more than PHP or Ruby can say), and have sold many tens of
 thousands, perhaps even hundreds of thousands, of books. At this point,
 I don't think many people (John A. De Goes excepted) are looking at
 people writing major applications in Haskell as if they're aliens living
 on another planet.

 Haskell is in the mainstream already as far as being taken seriously;
 most of the complaints I'm seeing seem to be grasping at the same kinds
 of straws that the anti-Java guys were back in the late '90s. (It's
 hopeless if it uses garbage collection.)

 We've even got our own over-hyped, under-utilized supposed benefit
 (it's good for multicore).

 The main whinging seems to be about libraries, of which we have only
 1585 on hackage.

 Compare with RubyForge, which has 2059 projects in beta or better
 status, or 2961 if we include alpha as well. The Ruby Application
 Archive has 1768 projects; I have no idea how much overlap there is, or
 how many of these are real.

 I think we just need to sit tight for a couple of years.

 cjs
 --
 Curt Sampson       c...@starling-software.com        +81 90 7737 2974
           Functional programming in all senses of the word:
                   http://www.starling-software.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] Re: cabal: : openFile: does not exist (No such file or directory)

2009-07-28 Thread Thomas Hartman
did you verify parsec-2.1.0.1 exports

Text.Parsec.Language

?

This might be a parsec 2 versus parsec 3 issue

ghc-pkg describe parsec-2.1.0.1

should tell you the answer to that.



2009/7/27 Job Vranish jvran...@gmail.com:
 I tried updating to ghc-6.10.4 and have exactly the same error.
 Also ghc doesn't seem to be able to find any of the haskell platform
 packages, even though it ghc-pkg finds them just fine.

 For example (trimmed for brevity):

 ghc-pkg list
 /usr/local/lib/ghc-6.10.4/./package.conf:
     Cabal-1.6.0.3,
 ...
     parsec-2.1.0.1, pretty-1.0.1.0, process-1.0.1.1, random-1.0.0.1,
 ...

 ghci -v readModel.hs
 GHCi, version 6.10.4: http://www.haskell.org/ghc/  :? for help
 Glasgow Haskell Compiler, Version 6.10.4, for Haskell 98, stage 2 booted by
 GHC version 6.8.2
 Using package config file: /usr/local/lib/ghc-6.10.4/./package.conf
 ...

 readModel.hs:9:7:
     Could not find module `Text.Parsec.Language':
   locations searched:
     Text/Parsec/Language.hs
     Text/Parsec/Language.lhs
 Failed, modules loaded: none.
 ...


 ghc-pkg finds parsec, but ghci can't find it.

 And if I do a cabal -v3 update I get a:
 cabal: 3: openFile: does not exist (No such file or directory)

 Anybody figured it out?

 - Job Vranish

 On Fri, Jul 17, 2009 at 11:17 AM, Thomas Hartman tphya...@gmail.com wrote:

 cabal -v3 update

 will give you a more verbose version of what is going wrong.

 cabal --help

 regrettably, cabal --help doesn't tell you this but there is always
 the man page I suppose.

 2009/7/16 Tony Hannan tonyhann...@gmail.com:
  Hello,
 
  I'm on Ubuntu 8.10.
  I installed ghc 6.10.4 (from binary package:
  ghc-6.10.4-i386-unknown-linux-n.tar.bz2).
  I installed haskell-platform-2009.2.0.1 (from source package:
  haskell-platform-2009.2.0.1.tar.gz). It contains cabal-install-0.6.2.
 
  Then when I run cabal update, I get the following error:
  cabal:  : openFile: does not exist (No such file or directory)
 
  Any ideas?
 
  Thanks,
  Tony
 
  ___
  Libraries mailing list
  librar...@haskell.org
  http://www.haskell.org/mailman/listinfo/libraries
 
 
 ___
 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] Generalizing takeWhile

2009-07-22 Thread Thomas Hartman
What is the use case(s) for this function?

lements from the front of a list.  However the
 criteria are somewhat complex.

 walk f [] = []
 walk f (x:xs) = case f x
                 of Just g - x : walk g xs
                    Nothing - []

 For each item the `predicate' f either returns Nothing, when it thinks
 we should not take any more elements, or return Just another
 `predicate' to apply to the next element.

 However the type system does not like my function.  How can I mollify it?
 ___
 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] Implicit concatenation in list comprehensions

2009-07-19 Thread Thomas Hartman
I vote for tuple sections. Very nice!

I don't really see immediate places where I would use the list
comprehension improvement so I guess I don't vote for that.

2009/7/19 Neil Mitchell ndmitch...@gmail.com:
 Hi Max,

 For fun, I spent a few hours yesterday implement support for this
 syntax in GHC, originally propsed by Koen Claessen:

 [k, =, v,   | (k, v) - [(foo, 1), (bar, 2)]
 [foo, =, 1,  , bar, =, 2,  ]

 This is a generalisation of list comprehensions that allows several
 items to be concatenated onto the result list at once, by having
 several comma-separated items before the pipe.

 I like the power this feature gives, and if it was already in Haskell
 98 I'd certainly have used it a few times. I can't think of anything
 else the syntax could mean, so I don't see a potential for it stealing
 syntax that might otherwise be reused. However, it doesn't seem that
 discoverable or natural - I'm not sure I'd have ever guessed that such
 a feature might exist.

 P.S. I also implemented tuple sections
 (http://hackage.haskell.org/trac/ghc/ticket/3377#comment:3) which are
 a lot more useful:

 Yay! Discoverable, useful and really common in practice - a brilliant
 extension :-)

 Thanks

 Neil
 ___
 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] can there be (hash-table using) O(n) version of this (I think currently) n log n algo?

2009-07-18 Thread Thomas Hartman
Thanks Bulat.

FWIW, i take it that

http://www.haskell.org/haskellwiki/Shootout/Knucleotide

is what Edward was referring to, with the shootouts. It seems that a
lot of progress has been made but not much has been migrated back to
hackage.

Going back to my original question, I am now looking for a dead simple
motivating example for showing the example of using a (good) hashtable
over Data.Map, with a tangible demo of O(n) over O(n log n) running
times.  I mean, something where running an input of (10^4) size versus
(10^6) size shows a noticeably laggier run when using Set versus
hashtable.

I don't think maybe my original example quite qualifies because I
think in practice the computation is dominated by space complexity.
However, I haven't yet ported it over to a hashtable version, so not
sure.

(And the shootout example doesn't satisfy my sense of dead simple.)

2009/7/18 Bulat Ziganshin bulat.zigans...@gmail.com:
 Hello Thomas,

 Saturday, July 18, 2009, 2:24:21 AM, you wrote:

 Further, is there a hashtable implementation for haskell that doesn't
 live in IO? Maybe in ST or something?

 import Prelude hiding (lookup)
 import qualified Data.HashTable
 import Data.Array
 import qualified Data.List as List


 data HT a b = HT (a-Int) (Array Int [(a,b)])

 -- size is the size of array (we implement a closed hash)
 -- hash is the hash function (a-Int)
 -- list is assoclist of items to put in hash
 create size hash list = HT hashfunc
                           (accumArray (flip (:))
                                       []
                                       (0, arrsize-1)
                                       (map (\(a,b) - (hashfunc a,(a,b))) 
 list)
                           )

  where arrsize     =  head$ filter (size)$ iterate (\x-3*x+1) 1
        hashfunc a  =  hash a `mod` arrsize


 lookup a (HT hash arr) = List.lookup a (arr!hash a)


 main = do let assoclist = [(one, 1), (two, 2), (three, 3)]
              hash = create 10 (fromEnum . Data.HashTable.hashString) assoclist
          print (lookup one hash)
          print (lookup zero hash)


 --
 Best regards,
  Bulat                            mailto:bulat.zigans...@gmail.com


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


[Haskell-cafe] powerSet = filterM (const [True, False]) ... is this obfuscated haskell?

2009-07-17 Thread Thomas Hartman
on haskell reddit today

powerSet = filterM (const [True, False])

is said to be beautiful / mind blowing. I just don't get it. I can
play with  transformations until I get

powerSet []   = [[]]
powerSet (x:xs) =
  let pxs = powerSet xs
  in map (x:) pxs ++ pxs

which is understandable to me, but no matter how long I look at the
original filterM definition it just doesn't click.

Is this a uniquely haskell obfu, or is there a way of reading this
definition that makes sense?

If anybody agrees with me, care to throw out other examples of
obfuscated haskell considered harmful?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: cabal: : openFile: does not exist (No such file or directory)

2009-07-17 Thread Thomas Hartman
cabal -v3 update

will give you a more verbose version of what is going wrong.

cabal --help

regrettably, cabal --help doesn't tell you this but there is always
the man page I suppose.

2009/7/16 Tony Hannan tonyhann...@gmail.com:
 Hello,

 I'm on Ubuntu 8.10.
 I installed ghc 6.10.4 (from binary package:
 ghc-6.10.4-i386-unknown-linux-n.tar.bz2).
 I installed haskell-platform-2009.2.0.1 (from source package:
 haskell-platform-2009.2.0.1.tar.gz). It contains cabal-install-0.6.2.

 Then when I run cabal update, I get the following error:
 cabal:  : openFile: does not exist (No such file or directory)

 Any ideas?

 Thanks,
 Tony

 ___
 Libraries mailing list
 librar...@haskell.org
 http://www.haskell.org/mailman/listinfo/libraries


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


Re: [Haskell-cafe] laziness blowup exercise

2009-07-17 Thread Thomas Hartman
I don't have a good answer to that, and I unable to reliably solve
this type of problem, which is one reason I am posting around on
haskell cafe hoping to accumulate wisdom.

Here for instance I think I did

t = last . take (10^6) $  repeat $ S.empty

which doesn't blow up, and by process of elimination figured the
process must be in iterate.

I then looked at iterate by writing myiterate (could have also copied
from hackage prelude) and thought about it until the answer (well, an
answer, maybe not the best one) came

myiterate f x = x : myiterate f (f x)

In general, I feel like I don't do very well solving these types of problems.


Am 17. Juli 2009 08:47 schrieb Matthias Görgens
matthias.goerg...@googlemail.com:
 Thomas, if you did no know, where to look for `lazy-memory-hole', say
 in your first example, how would you go about solving that puzzle
 systematically with a Profiler (or other tools)?

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


[Haskell-cafe] can there be (hash-table using) O(n) version of this (I think currently) n log n algo?

2009-07-17 Thread Thomas Hartman
The code below is, I think, n log n, a few seconds on a million + element list.

I wonder if it's possible to get this down to O(N) by using a
hashtable implemementation, or other better data structure.

Further, is there a hashtable implementation for haskell that doesn't
live in IO? Maybe in ST or something?

import Data.HashTable
import qualified Data.Set as S
import Data.List (foldl')

testdata = [1,4,8,9,20,11,20,14,2,15] ++ [1..(10^6)]
wantedsum = 29

-- set data structure
-- findsums locates pairs of integers in a list that add up to a
wanted sum.
findsums :: [Int] - Int - S.Set (Int,Int)
findsums xs wanted = snd . foldl' f (S.empty,S.empty) $ xs
  where f (candidates,successes) next = if  S.member (wanted-next) candidates
  then (candidates, S.insert
(next,wanted-next) successes)
  else (S.insert next
candidates,successes)

-- hashtable data structure



-- result: t
-- fromList 
[(15,14),(16,13),(17,12),(18,11),(19,10),(20,9),(21,8),(22,7),(23,6),(24,5),(25,4),(26,3),(27,2),(28,1)]
-- probably O(n log n) complexity since using tree based Data.Set (a
few seconds on million+ element list)
t = findsums testdata wantedsum
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] laziness blowup exercise

2009-07-16 Thread Thomas Hartman
the strict functions seem very nice, will they eventually make their way into

http://hackage.haskell.org/packages/archive/Stream/0.3.2/doc/html/Data-Stream.html

?

where is Control.Monad.StreamT? couldn't find it.

2009/7/15 Bas van Dijk v.dijk@gmail.com:
 On Wed, Jul 15, 2009 at 3:02 AM, Thomas Hartmantphya...@gmail.com wrote:
 Please suggest more of these types of exercises if you have them and
 maybe we can collect the folk wisdom into a wiki page and/or exercise
 page for beginners.

 My 'stream' library[1] also has some examples. Look at the following
 functions in 'Data.Stream':

 * mapAccum'
 * scan'
 * iterate'
 * unfold'

 There are similar examples in 'Control.Monad.StreamT'.

 [1] http://code.haskell.org/~basvandijk/code/stream/  (Not on Hackage)

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


Re: [Haskell-cafe] laziness blowup exercise

2009-07-16 Thread Thomas Hartman
I played with this a bit, and ok, it seems the difference between
iterate' and iterate'' is

h _ = 2


tit' = head . drop 1 . iterate' h $ undefined
tit'' = head . drop 1 . iterate'' h $ undefined

 (Bas wishes for a type system that can express the different
strictness properties of these functions...)

Is this being worked on? Could you give some example of type systems
that can express differences between functions of along dimension x?
Off the top of my head, I guess (?) with dependent types can tell the
difference between total and partial functions... partials won't even
compile, right? Are there others? Pointers appreciated.

 ...seems the most lazy strict iterate.

could you expand on what you mean by this?

2009/7/16 Bas van Dijk v.dijk@gmail.com:
 On Wed, Jul 15, 2009 at 6:35 PM, Ryan Ingramryani.s...@gmail.com wrote:
 iterate' f x = x `seq` x : iterate' f (f x)
 seems better; it doesn't evaluate list elements you don't visit.

 iterate'' f x = x : (iterate'' f $! f x)

 ...seems the most lazy strict iterate.

 (Bas wishes for a type system that can express the different
 strictness properties of these functions...)

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


[Haskell-cafe] another laziness blowup (this one unsolved)

2009-07-16 Thread Thomas Hartman
Is it possible to fix alternate' (the second version), or otherwise
define a fast stepwise alternate that doesn't blow up on long lists?

alternate just breaks up [1,2,3,4,5] into ([1,3,5],[2,4])

Thanks!

{-# LANGUAGE BangPatterns #-}
import Data.List
import Control.Arrow
import Control.Parallel.Strategies

t = (last *** last) $! alternate $ [1..(10^6)]
t' = (last *** last) $! alternate' $ [1..(10^6)]
t'' = (last *** last) $! alternate'' $ [1..(10^6)]


-- finishes reasonably fast, but does a separate computation for the
list and its tail rather than just rip through it
alternate x = (skip1 x,(skip1 $ tail x))
skip1 = skip 1
skip n xs =
  let (a,b) = splitAt (n+1) xs
  in case a of
 [] - []
 x:_ - x : skip n b



-- this one overflows on million element list, even after fiddling
with strictness on input args. can this be fixed?
alternate' xs =
  let f3 :: Int - (([Int],[Int]),Int) - (([Int],[Int]),Int)
  f3 x ((a,b),n) = -- rnf (x,((a,b),n)) `seq`
let nxtn = n+1
in if n `mod` 2 == 0
then ((x:a,b),nxtn)
else ((a,x:b),nxtn)
  in fst . foldr f3 (([],[]),0) $ xs

-- no overflow, goes through the list stepwise, but it's actually
slightly slower than the first alternate because of the reverses
alternate'' xs =
  let f3 ((a,b),n) x =
(let nxtn = n+1
in if n `mod` 2 == 0
then ((x:a,b),nxtn)
else ((a,x:b),nxtn) )
  in (reverse *** reverse) . fst . foldl' f3 (([],[]),0) $ xs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: another laziness blowup (this one unsolved)

2009-07-16 Thread Thomas Hartman
solved. see the haskell wiki for spoiler:

http://haskell.org/haskellwiki/Blow_your_mind

2009/7/16 Thomas Hartman tphya...@gmail.com:
 Is it possible to fix alternate' (the second version), or otherwise
 define a fast stepwise alternate that doesn't blow up on long lists?

 alternate just breaks up [1,2,3,4,5] into ([1,3,5],[2,4])

 Thanks!

 {-# LANGUAGE BangPatterns #-}
 import Data.List
 import Control.Arrow
 import Control.Parallel.Strategies

 t = (last *** last) $! alternate $ [1..(10^6)]
 t' = (last *** last) $! alternate' $ [1..(10^6)]
 t'' = (last *** last) $! alternate'' $ [1..(10^6)]


 -- finishes reasonably fast, but does a separate computation for the
 list and its tail rather than just rip through it
 alternate x = (skip1 x,(skip1 $ tail x))
 skip1 = skip 1
 skip n xs =
  let (a,b) = splitAt (n+1) xs
  in case a of
     [] - []
     x:_ - x : skip n b



 -- this one overflows on million element list, even after fiddling
 with strictness on input args. can this be fixed?
 alternate' xs =
  let f3 :: Int - (([Int],[Int]),Int) - (([Int],[Int]),Int)
      f3 x ((a,b),n) = -- rnf (x,((a,b),n)) `seq`
        let nxtn = n+1
        in if n `mod` 2 == 0
            then ((x:a,b),nxtn)
            else ((a,x:b),nxtn)
  in fst . foldr f3 (([],[]),0) $ xs

 -- no overflow, goes through the list stepwise, but it's actually
 slightly slower than the first alternate because of the reverses
 alternate'' xs =
  let f3 ((a,b),n) x =
        (let nxtn = n+1
        in if n `mod` 2 == 0
            then ((x:a,b),nxtn)
            else ((a,x:b),nxtn) )
  in (reverse *** reverse) . fst . foldl' f3 (([],[]),0) $ xs

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


[Haskell-cafe] laziness blowup exercise

2009-07-14 Thread Thomas Hartman
Challenge: change one function in the following pipeline so that t
doesn't blow up when executed in ghci.

import qualified Data.Set as S
t = last . take (10^6) . iterate f $ S.empty
f s = S.delete 1 . S.insert 1 $ s

Please suggest more of these types of exercises if you have them and
maybe we can collect the folk wisdom into a wiki page and/or exercise
page for beginners.

spoiler for the above problem below :)

































































myiterate f x =
  let nxt = f x
  in nxt `seq` x : myiterate f nxt
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] simple state monad exercises? (besides labeling trees)

2009-07-06 Thread Thomas Hartman
Can someone give some simple common scenarios where the state monad is
useful, besides labeling trees?

References to puzzles like those in project Euler or similar would be nice.

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


Re: [Haskell-cafe] Re: Need some help with an infinite list

2009-06-20 Thread Thomas Hartman
could someone explain sharing?

In the code below, allstrings2 is 6X as fast as allstrings. I assume
because of sharing, but I don't intuitively see a reason why.

can someone give me some pointers, perhaps using debug.trace or other
tools (profiling?) to show where the first version is being
inefficient?


***

letters = ['a'..'z']

strings 0 = []
strings n = [ c : s | c - letters, s -  strings (n-1) x ]

allstrings = concat $ map strings [1..]

allstrings2 = let sss = [] : [ [ c:s | c - letters, s - ss ] | ss - sss ]
  in concat $ tail sss

t = allstrings !! wanted
t2 = allstrings2 !! wanted

wanted = (10^2)


2009/6/18 Lee Duhem lee.du...@gmail.com:
 On Fri, Jun 19, 2009 at 6:17 AM, Matthew Brecknellhask...@brecknell.org 
 wrote:
 On Thu, 2009-06-18 at 23:57 +0800, Lee Duhem wrote:
 [...] I have prepared a blog post for how
 I worked out some of these answers, here is the draft of it, I hope it
 can help you too.

 Nice post! Certainly, pen-and-paper reasoning like this is a very good
 way to develop deeper intuitions.

       Answer 1 (by Matthew Brecknell):

       concat $ tail $ iterate (map (:) ['a' .. 'z'] *) [[]]

 I actually said tail $ concat $ iterate ..., because I think the
 initial empty string is logically part of the sequence. Tacking tail
 on the front then produces the subsequence requested by the OP.

 Yes, I changed your solution from tail $ concat $ iterate ... to
 concat $ tail $ iterate ..., because I think cut useless part out early
 is good idea, forgot to mention that, sorry.


 I should have given more credit to Reid for this solution. I'm always
 delighted to see people using monadic combinators (like replicateM) in
 the list monad, because I so rarely think to use them this way. Sadly,
 my understanding of these combinators is still somewhat stuck in IO,
 where I first learned them. I never would have thought to use * this
 way if I had not seen Reid's solution first.

 Actually, I first figure out how Reid's solution works, then figure out yours.
 After that, I found, for me, your solution's logic is easier to understand,
 so I take it as my first example. As I said at the end, or as I'll
 said at the end,
 Reid' solution and yours are the same (except effective)

 lee
 ___
 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] please comment on my parser, can I do this cleaner?

2009-06-09 Thread Thomas Hartman
All I want to do is split on commas, but not the commas inside () or  tags.

I have been wanting to master parsec for a long time and this simple
exercise looked like a good place to start.

The code below does the right thing. Am I missing any tricks to make
this simpler/neater?

Thanks, thomas.

thart...@ubuntu:~/perlArenacat splitEm.
splitEm.hs   splitEm.hs~  splitEm.pl   splitEm.pl~
thart...@ubuntu:~/perlArenacat splitEm.hs
{-# LANGUAGE ScopedTypeVariables #-}
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Char
import Text.PrettyPrint (vcat, render, text)
import Data.List.Split hiding (sepBy, chunk)
import Text.ParserCombinators.Parsec.Token

import Debug.Trace
import Debug.Trace.Helpers

-- this works, but is there a neater/cleaner way?
main = ripInputsXs (toEof splitter) splitter [ goodS, badS ]

-- I need a way to split on commas, but not the commas inside '' or
'()' characters
goodS = *2FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0
badS = *2)FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0
-- the first  matches a ), so reject this


splitter = do
  chunks :: [String] - toEof (many chunk)
  let pieces = map concat $ splitOn [,] chunks
  return pieces -- chunks
  where
atom = string ,
   | ( many1 $ noneOf () )
chunk = parenExpr |  atom
parenExpr :: GenParser Char st [Char]
parenExpr = let paren p = betweenInc (char '(' ) (char ')' ) p
| betweenInc (char '' ) (char '' )
p
in paren $ option  $ do ps - many1 $ parenExpr | atom
  return . concat $ ps

betweenInc o' c' p' = do
  o - o'
  p - p'
  c - c'
  return $ [o] ++ p ++ [c]

toEof p' = do
r - p'
eof
return r






ripInputs prs prsName xs = mapM_ (putStrLn . show . parse prs prsName ) xs
ripInputsXs prs prsName xs = mapM_ (putStrLn . showXs . parse prs prsName ) xs
  where showXs v = case v of
  Left e - show e
  Right xs - render . vcat . map text $ xs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] please comment on my parser, can I do this cleaner?

2009-06-09 Thread Thomas Hartman
Thanks. It seems my original parser also works against FOO,BAR,BAZ if
you only modify

atom = string ,
           | ( many1 $ noneOf (), ) -- add ,

Indeed, what to call the thingies in a parser is a source of some
personal consternation.

What is a token, what is an atom, what is an expr? It all seems to be
somewhat ad hoc.

 2009/6/9 Daniel Fischer daniel.is.fisc...@web.de:
 Am Dienstag 09 Juni 2009 20:29:09 schrieb Thomas Hartman:
 All I want to do is split on commas, but not the commas inside () or 
 tags.

 I have been wanting to master parsec for a long time and this simple
 exercise looked like a good place to start.

 The code below does the right thing. Am I missing any tricks to make
 this simpler/neater?

 Thanks, thomas.

 thart...@ubuntu:~/perlArenacat splitEm.
 splitEm.hs   splitEm.hs~  splitEm.pl   splitEm.pl~
 thart...@ubuntu:~/perlArenacat splitEm.hs
 {-# LANGUAGE ScopedTypeVariables #-}
 import Text.ParserCombinators.Parsec
 import Text.ParserCombinators.Parsec.Char
 import Text.PrettyPrint (vcat, render, text)
 import Data.List.Split hiding (sepBy, chunk)
 import Text.ParserCombinators.Parsec.Token

 import Debug.Trace
 import Debug.Trace.Helpers

 -- this works, but is there a neater/cleaner way?
 main = ripInputsXs (toEof splitter) splitter [ goodS, badS ]

 -- I need a way to split on commas, but not the commas inside '' or
 '()' characters
 goodS = *2FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0
 badS = *2)FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0
 -- the first  matches a ), so reject this


 splitter = do
   chunks :: [String] - toEof (many chunk)
   let pieces = map concat $ splitOn [,] chunks
   return pieces -- chunks
   where
     atom = string ,
            | ( many1 $ noneOf () )
     chunk = parenExpr |  atom

 I think that does not do what you want.

 For input FOO,BAR,BAZ, chunks is [FOO,BAR,BAZ], that won't be split; as 
 far as I can
 see, it splits only on commas directly following a parenExpr (or at the 
 beginning of the
 input or directly following another splitting comma).

     parenExpr :: GenParser Char st [Char]
     parenExpr = let paren p = betweenInc (char '(' ) (char ')' ) p
                                 | betweenInc (char '' ) (char '' )
 p
                 in paren $ option  $ do ps - many1 $ parenExpr | atom
                                           return . concat $ ps

 betweenInc o' c' p' = do
   o - o'
   p - p'
   c - c'
   return $ [o] ++ p ++ [c]

 toEof p' = do
         r - p'
         eof
         return r






 ripInputs prs prsName xs = mapM_ (putStrLn . show . parse prs prsName ) xs
 ripInputsXs prs prsName xs = mapM_ (putStrLn . showXs . parse prs prsName )
 xs where showXs v = case v of
           Left e - show e
           Right xs - render . vcat . map text $ xs

 I can offer (sorry for the names, and I don't know if what that does is 
 really what you
 want):


 keepSepBy :: Parser a - Parser a - Parser [a]
 keepSepBy p sep = (do
    r - p
    (do s - sep
        xs - keepSepBy p sep
        return (r:s:xs)) | return [r])
    | return []

 twain :: Parser a - Parser a - Parser [a] - Parser [a]
 twain open close list = do
    o - open
    l - list
    c - close
    return (o:l++[c])

 comma :: Parser String
 comma = string ,

 simpleChar :: Parser Char
 simpleChar = noneOf (),

 suite :: Parser String
 suite = many1 simpleChar

 atom :: Parser String
 atom = fmap concat $ many1 (parenExp | suite)

 parenGroup :: Parser String
 parenGroup = fmap concat $ keepSepBy atom comma

 parenExp :: Parser String
 parenExp = twain (char '') (char '') parenGroup
            | twain (char '(') (char ')') parenGroup

 chunks :: Parser [String]
 chunks = sepBy atom comma

 splitter = do
    cs - chunks
    eof
    return cs

 goodS = *2FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0
 badS = *2)FOO2,1,*3(SigB8:0:2,BAR),*2Siga2:0,Sigb8,7,6,5,0

 goodRes = parse splitter splitter goodS
 badRes = parse splitter splitter badS


 ___
 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] applicative challenge

2009-05-05 Thread Thomas Hartman
That's slick, but is there some way to use interact twice in the same program?

t10 =
  let f = unlines . takeWhile (not . blank) . lines
  in  do putStrLn first time
 interact f
 putStrLn second time
 interact f

this results in *** Exception: stdin: hGetContents: illegal
operation (handle is closed) -}

I also tried

t15 =
  let grabby = unlines . takeWhile (not . blank) . lines
  top = (first time:  ++) . grabby . (second time:  ++) . grabby
  in  interact top


but that didn't work either:

thart...@ubuntu:~/haskell-learning/lazy-n-strictrunghc sequencing.hs
a
first time: second time: a
b
b

If someone can explain the subtleties of using interact when you run
out of stdio here, it would be nice to incorporate this into

http://www.haskell.org/haskellwiki/Haskell_IO_for_Imperative_Programmers#IO

where it talks about how using interact is the easy way to approach
these types of problems. Not *that* easy though, as this scenario
suggests.



2009/5/5 Thomas Davie tom.da...@gmail.com:

 On 4 May 2009, at 23:15, Thomas Hartman wrote:

 {-# LANGUAGE NoMonomorphismRestriction #-}
 import Data.List
 import Control.Monad
 import Control.Applicative

 -- Can the function below be tweaked to quit on blank input,
 provisioned in the applicative style?
 -- which function(s) needs to be rewritten to make it so?
 -- Can you tell/guess which function(s) is the problem just by looking
 at the code below?
 -- If so, can you explain what the strategy for doing so is?
 notQuiteRight = takeWhile (not . blank) $ ( sequence . repeat $ echo )

 echo = do
         l - getLine
         putStrLn l
         return l


 -- this seems to work... is there a way to make it work Applicatively,
 with lifted takeWhile?
 seemsToWork = sequenceWhile_ (not . blank) (repeat echo)

 sequenceWhile_ p [] = return ()
 sequenceWhile_ p (mx:mxs) = do
  x - mx
  if p x
   then do sequenceWhile_ p mxs
   else return ()

 Conor's already give you a comprehensive explanation of why Applicative
 can't be used to do this, but that doesn't mean you can't use applicative
 style!

 How about...

 echo = unlines . takeWhile (not . blank) . lines

 seemsToWork = interact echo

 Bob


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


Re: [Haskell-cafe] applicative challenge

2009-05-05 Thread Thomas Hartman
seems to be the same behavior whether in ghci or compiled with ghc.

2009/5/5 Ketil Malde ke...@malde.org:
 Thomas Hartman tphya...@gmail.com writes:

 That's slick, but is there some way to use interact twice in the same 
 program?

 No :-)

 t10 =
   let f = unlines . takeWhile (not . blank) . lines
   in  do putStrLn first time
          interact f
          putStrLn second time
          interact f

 this results in *** Exception: stdin: hGetContents: illegal
 operation (handle is closed) -}

 Yes. Interacting uses hGetContents, and hGetContents semi-closes (or
 fully-closes) the handle.  If you do it from GHCi, you only get to run
 your program once.

 I also tried

 t15 =
   let grabby = unlines . takeWhile (not . blank) . lines
       top = (first time:  ++) . grabby . (second time:  ++) . grabby
   in  interact top

 but that didn't work either:
 thart...@ubuntu:~/haskell-learning/lazy-n-strictrunghc sequencing.hs
 a
 first time: second time: a
 b
 b

 Well - the input to the leftmost grabby is second time prepended to
 the input from the first, and then you prepend first time - so this
 makes sense.

 Something like this, perhaps:

 interact (\s - let (first,second) = span (not . null) (lines s)
                in unlines (first:first++second:takeWhile (not.null) 
 second))

 If someone can explain the subtleties of using interact when you run
 out of stdio here, it would be nice to incorporate this into

 hGetContents - there can only be one.

 -k
 --
 If I haven't seen further, it is by standing in the footprints of giants

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


Re: [Haskell-cafe] applicative challenge

2009-05-05 Thread Thomas Hartman
 interact (\s - let (first,second) = span (not . null) (lines s)
   in unlines (first:first++second:takeWhile (not.null) second))

So, that didn't quite do the right thing, and it seemed like using
span/break wouldn't scale well for more than two iterations. Here's
another attempt, which is a little closer I think, except that it
seems to be using some sort of half-assed state without being explicit
about it:

module Main where

t17 = interact f17
f17 s = let (first,rest) = grabby s
(second,_) = grabby rest
in first\n ++ first ++ second\n ++ second

grabby :: String - (String,String)
grabby s =
  let (beg,end) = break null . lines $ s
  in (unlines beg, (unlines . drop 2 $ end))


2009/5/5 Ketil Malde ke...@malde.org:
 Thomas Hartman tphya...@gmail.com writes:

 That's slick, but is there some way to use interact twice in the same 
 program?

 No :-)

 t10 =
   let f = unlines . takeWhile (not . blank) . lines
   in  do putStrLn first time
          interact f
          putStrLn second time
          interact f

 this results in *** Exception: stdin: hGetContents: illegal
 operation (handle is closed) -}

 Yes. Interacting uses hGetContents, and hGetContents semi-closes (or
 fully-closes) the handle.  If you do it from GHCi, you only get to run
 your program once.

 I also tried

 t15 =
   let grabby = unlines . takeWhile (not . blank) . lines
       top = (first time:  ++) . grabby . (second time:  ++) . grabby
   in  interact top

 but that didn't work either:
 thart...@ubuntu:~/haskell-learning/lazy-n-strictrunghc sequencing.hs
 a
 first time: second time: a
 b
 b

 Well - the input to the leftmost grabby is second time prepended to
 the input from the first, and then you prepend first time - so this
 makes sense.

 Something like this, perhaps:

 interact (\s - let (first,second) = span (not . null) (lines s)
                in unlines (first:first++second:takeWhile (not.null) 
 second))

 If someone can explain the subtleties of using interact when you run
 out of stdio here, it would be nice to incorporate this into

 hGetContents - there can only be one.

 -k
 --
 If I haven't seen further, it is by standing in the footprints of giants

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


using interact with state, was Re: [Haskell-cafe] applicative challenge

2009-05-05 Thread Thomas Hartman
Aha!

There is in fact a way to fit this specification into the applicative paradigm.

I'm a bit muzzy as to what it all means, but I must say, aesthetically
I'm rather pleased with the result:

module Main where

import Control.Monad.State
import Control.Applicative
import Control.Applicative.State -- applicative-extras on hackage

-- works
t18 = interact $ evalState f18
  where f18 = return paint `ap` grabTillBlank `ap` grabTillBlank
paint first second = first\n ++ first ++ second\n ++ second

grabTillBlank = State $ \s -
  let (beg,end) = break null . lines $ s
  in  (unlines beg, (unlines . drop 2 $ end))

-- And, with applicative extras:
t19 = interact $ evalState f19
  where f19 = paint $ grabTillBlank * grabTillBlank
paint first second = first\n ++ first ++ second\n ++ second




2009/5/5 Thomas Hartman tphya...@gmail.com:
 interact (\s - let (first,second) = span (not . null) (lines s)
               in unlines (first:first++second:takeWhile (not.null) 
 second))

 So, that didn't quite do the right thing, and it seemed like using
 span/break wouldn't scale well for more than two iterations. Here's
 another attempt, which is a little closer I think, except that it
 seems to be using some sort of half-assed state without being explicit
 about it:

 module Main where

 t17 = interact f17
 f17 s = let (first,rest) = grabby s
            (second,_) = grabby rest
        in first\n ++ first ++ second\n ++ second

 grabby :: String - (String,String)
 grabby s =
  let (beg,end) = break null . lines $ s
  in (unlines beg, (unlines . drop 2 $ end))


 2009/5/5 Ketil Malde ke...@malde.org:
 Thomas Hartman tphya...@gmail.com writes:

 That's slick, but is there some way to use interact twice in the same 
 program?

 No :-)

 t10 =
   let f = unlines . takeWhile (not . blank) . lines
   in  do putStrLn first time
          interact f
          putStrLn second time
          interact f

 this results in *** Exception: stdin: hGetContents: illegal
 operation (handle is closed) -}

 Yes. Interacting uses hGetContents, and hGetContents semi-closes (or
 fully-closes) the handle.  If you do it from GHCi, you only get to run
 your program once.

 I also tried

 t15 =
   let grabby = unlines . takeWhile (not . blank) . lines
       top = (first time:  ++) . grabby . (second time:  ++) . grabby
   in  interact top

 but that didn't work either:
 thart...@ubuntu:~/haskell-learning/lazy-n-strictrunghc sequencing.hs
 a
 first time: second time: a
 b
 b

 Well - the input to the leftmost grabby is second time prepended to
 the input from the first, and then you prepend first time - so this
 makes sense.

 Something like this, perhaps:

 interact (\s - let (first,second) = span (not . null) (lines s)
                in unlines (first:first++second:takeWhile (not.null) 
 second))

 If someone can explain the subtleties of using interact when you run
 out of stdio here, it would be nice to incorporate this into

 hGetContents - there can only be one.

 -k
 --
 If I haven't seen further, it is by standing in the footprints of giants


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


Re: [Haskell-cafe] applicative challenge

2009-05-05 Thread Thomas Hartman
 half-assed state

for a real state solution, there's follow up here:

http://groups.google.com/group/haskell-cafe/browse_thread/thread/d6143504c0e80075

2009/5/5 Thomas Hartman tphya...@gmail.com:
 interact (\s - let (first,second) = span (not . null) (lines s)
               in unlines (first:first++second:takeWhile (not.null) 
 second))

 So, that didn't quite do the right thing, and it seemed like using
 span/break wouldn't scale well for more than two iterations. Here's
 another attempt, which is a little closer I think, except that it
 seems to be using some sort of half-assed state without being explicit
 about it:

 module Main where

 t17 = interact f17
 f17 s = let (first,rest) = grabby s
            (second,_) = grabby rest
        in first\n ++ first ++ second\n ++ second

 grabby :: String - (String,String)
 grabby s =
  let (beg,end) = break null . lines $ s
  in (unlines beg, (unlines . drop 2 $ end))


 2009/5/5 Ketil Malde ke...@malde.org:
 Thomas Hartman tphya...@gmail.com writes:

 That's slick, but is there some way to use interact twice in the same 
 program?

 No :-)

 t10 =
   let f = unlines . takeWhile (not . blank) . lines
   in  do putStrLn first time
          interact f
          putStrLn second time
          interact f

 this results in *** Exception: stdin: hGetContents: illegal
 operation (handle is closed) -}

 Yes. Interacting uses hGetContents, and hGetContents semi-closes (or
 fully-closes) the handle.  If you do it from GHCi, you only get to run
 your program once.

 I also tried

 t15 =
   let grabby = unlines . takeWhile (not . blank) . lines
       top = (first time:  ++) . grabby . (second time:  ++) . grabby
   in  interact top

 but that didn't work either:
 thart...@ubuntu:~/haskell-learning/lazy-n-strictrunghc sequencing.hs
 a
 first time: second time: a
 b
 b

 Well - the input to the leftmost grabby is second time prepended to
 the input from the first, and then you prepend first time - so this
 makes sense.

 Something like this, perhaps:

 interact (\s - let (first,second) = span (not . null) (lines s)
                in unlines (first:first++second:takeWhile (not.null) 
 second))

 If someone can explain the subtleties of using interact when you run
 out of stdio here, it would be nice to incorporate this into

 hGetContents - there can only be one.

 -k
 --
 If I haven't seen further, it is by standing in the footprints of giants


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


[Haskell-cafe] applicative challenge

2009-05-04 Thread Thomas Hartman
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.List
import Control.Monad
import Control.Applicative

-- Can the function below be tweaked to quit on blank input,
provisioned in the applicative style?
-- which function(s) needs to be rewritten to make it so?
-- Can you tell/guess which function(s) is the problem just by looking
at the code below?
-- If so, can you explain what the strategy for doing so is?
notQuiteRight = takeWhile (not . blank) $ ( sequence . repeat $ echo )

echo = do
  l - getLine
  putStrLn l
  return l


-- this seems to work... is there a way to make it work Applicatively,
with lifted takeWhile?
seemsToWork = sequenceWhile_ (not . blank) (repeat echo)

sequenceWhile_ p [] = return ()
sequenceWhile_ p (mx:mxs) = do
  x - mx
  if p x
then do sequenceWhile_ p mxs
else return ()


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


Re: [Haskell-cafe] Generating random enums

2009-05-01 Thread Thomas Hartman
see

http://www.mail-archive.com/haskell-cafe@haskell.org/msg38528.html

for some ideas, particularly antoine latter's answer.

2009/5/1 michael rice nowg...@yahoo.com:
 I'm using the code below to generate random days of the week
 [Monday..Sunday].

 Is there a better/shorter way to do this?

 Michael

 ==

 [mich...@localhost ~]$ ghci dow
 GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer ... linking ... done.
 Loading package base ... linking ... done.
 [1 of 1] Compiling Main ( dow.hs, interpreted )
 Ok, modules loaded: Main.
 *Main random (mkStdGen 100) :: (DayOfWeek, StdGen)
 Loading package old-locale-1.0.0.1 ... linking ... done.
 Loading package old-time-1.0.0.1 ... linking ... done.
 Loading package random-1.0.0.1 ... linking ... done.
 (Friday,4041414 40692)
 *Main random (mkStdGen 123) :: (DayOfWeek, StdGen)
 (Tuesday,4961736 40692)
 *Main

 ==

 import System.Random

 data DayOfWeek
     = Monday
     | Tuesday
     | Wednesday
     | Thursday
     | Friday
     | Saturday
     | Sunday
     deriving (Show, Read, Eq, Enum, Ord, Bounded)

 instance Random DayOfWeek where
   randomR (a,b) g =
   case (randomIvalInteger (toInteger (dow2Int a), toInteger (dow2Int b))
 g) of
     (x, g) - (int2Dow x, g)
    where
  dow2Int Monday    = 0
  dow2Int Tuesday   = 1
  dow2Int Wednesday = 2
  dow2Int Thursday  = 3
  dow2Int Friday    = 4
  dow2Int Saturday  = 5
  dow2Int Sunday    = 6

      int2Dow 0    = Monday
      int2Dow 1    = Tuesday
      int2Dow 2    = Wednesday
      int2Dow 3    = Thursday
      int2Dow 4    = Friday
      int2Dow 5    = Saturday
      int2Dow 6    = Sunday

   random g      = randomR (minBound,maxBound) g

 randomIvalInteger :: (RandomGen g, Num a) = (Integer, Integer) - g - (a,
 g)
 randomIvalInteger (l,h) rng
  | l  h = randomIvalInteger (h,l) rng
  | otherwise = case (f n 1 rng) of (v, rng') - (fromInteger (l + v `mod`
 k), rng')
  where
    k = h - l + 1
    b = 2147483561
    n = iLogBase b k

    f 0 acc g = (acc, g)
    f n acc g =
   let
        (x,g')   = next g
       in
       f (n-1) (fromIntegral x + acc * b) g'

 iLogBase :: Integer - Integer - Integer
 iLogBase b i = if i  b then 1 else 1 + iLogBase b (i `div` b)







 ___
 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] Generating random enums

2009-05-01 Thread Thomas Hartman
So... I must say I am rather pleased with the following code.

It allows you to use any value of type Bounded and Enum as a member of
Random, or Arbitrary, which means you can quickCheck properties on it
as well.

For quickchecking, the code below cheats by not defining the
coarbitrary funciton, which I confess I don't really understand and
never use.

Even so, I can see myself using this in a number of places... Does it
seem reasonable to add a ticket to get this added to

http://hackage.haskell.org/packages/archive/QuickCheck/2.1.0.1/doc/html/Test-QuickCheck-Arbitrary.html

perhaps modulo the definition of an appropriate coarbitrary function?


thomas.

thart...@patchwiki:~/haskell-learning/testingcat BoundedEnum.hs
{-# LANGUAGE FlexibleInstances, UndecidableInstances,
ScopedTypeVariables, OverlappingInstances #-}
module Main where

import Test.QuickCheck
import System.Random

class (Bounded a, Enum a) = BoundedEnum a
instance (Bounded a, Enum a) = BoundedEnum a

instance BoundedEnum a = Random a
  where random g =
  let min = fromEnum (minBound :: a)
  max = fromEnum (maxBound :: a)
  (i,g') = randomR (min,max) $ g
  in (toEnum i,g')
randomR (low,high) g =
  let min = fromEnum low
  max = fromEnum high
  (i,g') = randomR (min,max) $ g
  in (toEnum i,g')

instance BoundedEnum a = Arbitrary a
  where arbitrary = do
  let min = fromEnum (minBound :: a)
  max = fromEnum (maxBound :: a)
  i - arbitrary
  return . toEnum $ min + (i `mod` (max-min))
coarbitrary = undefined

data DayOfWeek
= Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
deriving (Show, Read, Eq, Enum, Ord, Bounded)

t :: IO DayOfWeek
t = randomIO

t2 :: IO Int
t2 = randomIO

pDayEqualsItself :: DayOfWeek - Bool
pDayEqualsItself day = day == day -- a trivial property, just so we can show

t3 = quickCheck pDayEqualsItself

-- show what days are being tested
t4 = verboseCheck pDayEqualsItself


2009/5/1 michael rice nowg...@yahoo.com:
 I'm using the code below to generate random days of the week
 [Monday..Sunday].

 Is there a better/shorter way to do this?

 Michael

 ==

 [mich...@localhost ~]$ ghci dow
 GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer ... linking ... done.
 Loading package base ... linking ... done.
 [1 of 1] Compiling Main ( dow.hs, interpreted )
 Ok, modules loaded: Main.
 *Main random (mkStdGen 100) :: (DayOfWeek, StdGen)
 Loading package old-locale-1.0.0.1 ... linking ... done.
 Loading package old-time-1.0.0.1 ... linking ... done.
 Loading package random-1.0.0.1 ... linking ... done.
 (Friday,4041414 40692)
 *Main random (mkStdGen 123) :: (DayOfWeek, StdGen)
 (Tuesday,4961736 40692)
 *Main

 ==

 import System.Random

 data DayOfWeek
     = Monday
     | Tuesday
     | Wednesday
     | Thursday
     | Friday
     | Saturday
     | Sunday
     deriving (Show, Read, Eq, Enum, Ord, Bounded)

 instance Random DayOfWeek where
   randomR (a,b) g =
   case (randomIvalInteger (toInteger (dow2Int a), toInteger (dow2Int b))
 g) of
     (x, g) - (int2Dow x, g)
    where
  dow2Int Monday    = 0
  dow2Int Tuesday   = 1
  dow2Int Wednesday = 2
  dow2Int Thursday  = 3
  dow2Int Friday    = 4
  dow2Int Saturday  = 5
  dow2Int Sunday    = 6

      int2Dow 0    = Monday
      int2Dow 1    = Tuesday
      int2Dow 2    = Wednesday
      int2Dow 3    = Thursday
      int2Dow 4    = Friday
      int2Dow 5    = Saturday
      int2Dow 6    = Sunday

   random g      = randomR (minBound,maxBound) g

 randomIvalInteger :: (RandomGen g, Num a) = (Integer, Integer) - g - (a,
 g)
 randomIvalInteger (l,h) rng
  | l  h = randomIvalInteger (h,l) rng
  | otherwise = case (f n 1 rng) of (v, rng') - (fromInteger (l + v `mod`
 k), rng')
  where
    k = h - l + 1
    b = 2147483561
    n = iLogBase b k

    f 0 acc g = (acc, g)
    f n acc g =
   let
        (x,g')   = next g
       in
       f (n-1) (fromIntegral x + acc * b) g'

 iLogBase :: Integer - Integer - Integer
 iLogBase b i = if i  b then 1 else 1 + iLogBase b (i `div` b)







 ___
 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] What to do when cabal dependencies are not your friend.

2009-05-01 Thread Thomas Hartman
I did a little write-up on an annoyance I frequently have when
developing patch-tag, a happs application that has a lot of
dependencies.

Basically, on a virgin linux environment with the same cabal and ghc
version as before, a cabal install that had previously worked, didn't
work anymore.

I assume this is because of changes on hackage that didn't affect my
previous version because I had not done cabal update for a while.

Luckly I had a working environment on a test box elsewehre so...

http://blog.patch-tag.com/2009/05/01/what-to-do-when-cabal-install-works-in-one-environment-but-not-another/

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


[Haskell-cafe] how can one load Prelude into ghci?

2009-04-27 Thread Thomas Hartman
One reason it would be nice to be able to do this, is you could then
get lambdabot :src style listings of prelude function definitions by
using the ghci debugger and :list for prelude functions.

is this possible? so far I have tried

thart...@ubuntu:~/haskellInstalls/ghcInstalls/source/ghc-6.10.1/libraries/basehead
Prelude.hs
{-# OPTIONS_GHC -XNoImplicitPrelude #-}
-

thart...@ubuntu:~/haskellInstalls/ghcInstalls/source/ghc-6.10.1/libraries/baseghci
-i. Prelude.hs
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
command line: module `Prelude' is not loaded

thart...@ubuntu:~/haskellInstalls/ghcInstalls/source/ghc-6.10.1/libraries/baseghci
Prelude.hs
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
command line: module `Prelude' is not loaded
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ghci debugger problem with :continue. is it broken, or is it me?

2009-04-27 Thread Thomas Hartman
Most enlightening, thanks.

The same effect can be seen with Debug.Trace.trace around the two versions of f.

I suppose this means that the points-free/pattern binding-style
version is a bit less work for ghc to execute (fewer reductions),
whereas the version with lambda bound variables is easier to debug.

On balance, I think I'll frequently write my functions with lambda
bound variables then.

Getting better use out of the ghc debugger seems worth the few extra cycles.

2009/4/26 Bernie Pope florbit...@gmail.com:
 2009/4/25 Thomas Hartman tphya...@gmail.com

 In the program below, can someone explain the following debugger output to
 me?

  After :continue, shouldn't I hit the f  breakpoint two more times?
  Why do I only hit the f breakpoint once?
  Is this a problem in the debugger?

 thart...@ubuntu:~/haskell-learning/debuggercat debugger.hs

 -- try this:
 -- ghci debugger.hs
 --  :break f
 --  :trace t
 --  :history -- should show you that f was called from h
 t = h . g . f $ hey!
 t2 = h . g . f $ heh!
 t3 = h . g . f $ wey!

 f = (f --  ++)
 g = (g --  ++)
 h = (h --  ++)

 ts = do
  putStrLn $ t
  putStrLn $ t2
  putStrLn $ t3

 What you are observing is really an artifact of the way breakpoints are
 attached to definitions in the debugger, and the way that GHCi evaluates
 code.
 f is clearly a function, but its definition style is a so-called pattern
 binding. The body contains no free (lambda bound) variables, so it is also
 a constant. GHCi arranges for f to be evaluated at most once. The breakpoint
 associated with the definition of f is fired if and when that evaluation
 takes place. Thus, in your case it fires exactly once.
 You can re-write f to use a so-called function binding instead, by
 eta-expansion (introduce a new fresh variable, and apply the function to it
 on both sides):
    f x = (f --  ++) x
 This denotes the same function, but the breakpoint on f works differently.
 In this case, a breakpoint attached to f will fire whenever an application
 of f is reduced. If you write it this way you will see that the program
 stops three times instead of one.
 You might ask: if both definitions denote the same function, why does the
 debugger behave differently? The short answer is that the debugger in GHCi
 is an operational debugger, so it exposes some of the operational details
 which may be invisible in a denotational semantics. In this case it revels
 that GHCi treats the two definitions of f differently.
 Cheers,
 Bernie.

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


Re: [Haskell-cafe] Haskell/JS -- better through typeclasses?

2009-04-25 Thread Thomas Hartman
I tried using the jhc javascript compiler back end a year or so ago.

It was too rough to use in production, but it did output javascript
from haskell.

thomas.

2009/4/25 Miguel Mitrofanov miguelim...@yandex.ru:

 On 25 Apr 2009, at 21:53, Jason Dusek wrote:

  Many Haskell/JS bridges provide libraries for writing complete
  JavaScript programs in Haskell; some of them even include
  jQuery. However, my goals are more limited -- I'd like to be
  able to take a Haskell module and turn it into a JavaScript
  object.

 Many books explain how to grow a baby hippo; some of them even include
 instructions for treating it when it's sick. However, my goals are more
 limited -- I'd like to be able to take an elephant and turn it into a
 grown-up hippo.

 ___
 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] Haskell/JS -- better through typeclasses?

2009-04-25 Thread Thomas Hartman
On second thought, it was yhc, not jhc:

http://lambda-the-ultimate.org/node/1836

2009/4/25 Thomas Hartman tphya...@gmail.com:
 I tried using the jhc javascript compiler back end a year or so ago.

 It was too rough to use in production, but it did output javascript
 from haskell.

 thomas.

 2009/4/25 Miguel Mitrofanov miguelim...@yandex.ru:

 On 25 Apr 2009, at 21:53, Jason Dusek wrote:

  Many Haskell/JS bridges provide libraries for writing complete
  JavaScript programs in Haskell; some of them even include
  jQuery. However, my goals are more limited -- I'd like to be
  able to take a Haskell module and turn it into a JavaScript
  object.

 Many books explain how to grow a baby hippo; some of them even include
 instructions for treating it when it's sick. However, my goals are more
 limited -- I'd like to be able to take an elephant and turn it into a
 grown-up hippo.

 ___
 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] ghci debugger problem with :continue. is it broken, or is it me?

2009-04-24 Thread Thomas Hartman
In the program below, can someone explain the following debugger output to me?

  After :continue, shouldn't I hit the f breakpoint two more times?
  Why do I only hit the f breakpoint once?
  Is this a problem in the debugger?

thart...@ubuntu:~/haskell-learning/debuggercat debugger.hs


-- try this:
-- ghci debugger.hs
--  :break f
--  :trace t
--  :history -- should show you that f was called from h
t = h . g . f $ hey!
t2 = h . g . f $ heh!
t3 = h . g . f $ wey!

f = (f --  ++)
g = (g --  ++)
h = (h --  ++)



ts = do
  putStrLn $ t
  putStrLn $ t2
  putStrLn $ t3

{-
Problems using :continue in the ghci debugger?

Can someone explain the following debugger output to me?
  After :continue, shouldn't I hit the f breakpoint two more times?
  Why do I only hit the f breakpoint once?
  Is this a problem in the debugger?

thart...@ubuntu:~/haskell-learning/debuggerghci debugger.hs
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( debugger.hs, interpreted )
Ok, modules loaded: Main.
*Main :break f
Breakpoint 0 activated at debugger.hs:12:4-15
*Main ts
h -- g -- Stopped at debugger.hs:12:4-15
_result :: [Char] - [Char] = _
11
12  f = (f --  ++)

13  g = (g --  ++)
[debugger.hs:12:4-15] *Main :continue
f -- hey!
h -- g -- f -- heh!
h -- g -- f -- wey!
*Main
-}
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Combining sequences

2009-04-05 Thread Thomas Hartman
It's not in hugs, nor in ghc.

It's just in hackage. However, by the looks of it, you should probably
be able to use it in hugs. I didn't actually check this, but the cabal
file didn't name any fancy extensions, so it looks pretty
cross-compiler.

You can just go to

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utility-ht-0.0.4

wget 
http://hackage.haskell.org/packages/archive/utility-ht/0.0.4/utility-ht-0.0.4.tar.gz

untar

and put them with the rest of the files your hugs compiler uses for
package import. (I don't actually know how package installation works
in hugs... isn't it just put the files into a dir?)

thomas.

2009/4/5 michael rice nowg...@yahoo.com:
 Thanks. It looks like mergeBy will do the job, but is it available in Hugs?

 Michael


 --- On Sun, 4/5/09, Henning Thielemann lemm...@henning-thielemann.de
 wrote:

 From: Henning Thielemann lemm...@henning-thielemann.de
 Subject: Re: [Haskell-cafe] Combining sequences
 To: michael rice nowg...@yahoo.com
 Cc: haskell-cafe@haskell.org
 Date: Sunday, April 5, 2009, 9:09 PM


 On Sat, 4 Apr 2009, michael rice wrote:

 Is there a simple way to combine two sequences that are in ascending order
 into a single
 sequence that's also in ascending order? An example would be the squares
 [1,4,9,16,25..]
 combined with the cubes [1,8,27,64,125..] to form [1,1,4,8,9,16,25,27..].

 http://hackage.haskell.org/packages/archive/utility-ht/0.0.4/doc/html/Data-List-HT.html#v%3AmergeBy


 ___
 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] about Haskell code written to be too smart

2009-04-04 Thread Thomas Hartman
   takeListSt' = evalState . foldr k (return []) . map (State . splitAt)
 where k m m'= cutNull $ do x-m; xs-m'; return (x:xs)
   cutNull m = do s-get; if null s then return [] else m

Not only is ths not that elegant anymore, I think it *still* has a
bug, stack overflow against

testP pf = mapM_ putStrLn  [
  show $ take 5 $ pf (repeat 0) [1,2,3]
  , show $ pf ( take 1000 [3,7..] ) [1..100]
  , show . pf [3,7,11,15] $ ( take (10^6) [1..])
  , show . head . last $ pf (take 1000 $ [3,3..]) [1..10^6]
]

where the first test (with take 5) is new.

whereas the version with explicit recursion and pattern matching
doesn't suffer from this problem

partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in  beg : ( case end of
   [] - []
   xs - partitions parts xs)

I am starting to think that the tricky part in all these functions is
that by using higher order functions from the prelude, you sweep the
failure case under the rug. Specifically, what happens when splitAt n
doesn't have a list of length n? The answer isn't in fact obvious at
all. I can think of three things that could hapen.

You coud return (list,[]) where list is however many elements there
are left. (Which is what all the partitions functions do so far, and
the default behavior of splitAt.

Or, you could print an error message.

Or, you could return ([],[])

My tentative conclusion is that good haskell style makes error
modalities explicit when error behavior isn't obvious, or when there
is arguably more than one right way to fail. So:

partitionsE = partitionsE' error
partitionsE2 = partitionsE' ( \e n xs - [])
partitionsE3 = partitionsE' (\e n xs - [take n xs]) -- corresponds to
the behavior of partitions

partitionsE' err [] xs = []
partitionsE' err (n:parts) xs =
  case splitAtE n xs of
Left e - err e n xs
Right (beg,end) -
  beg : ( case end of
[] - []
xs - partitionsE' err parts xs )
  where splitAtE n as@(x:xs) | n = length as = Right $ splitAt n as
splitAtE n ys = Left $ can't split at  ++ (show n) ++ : 
++ (show ys)



2009/3/26 Claus Reinke claus.rei...@talk21.com:
 Continuing our adventures into stylistic and semantic differences:-)

 Comparing the 'State' and explicit recursion versions

   takeListSt = evalState . mapM (State . splitAt)

   -- ..with a derivation leading to..

   takeListSt []    s = []
   takeListSt (h:t) s = x : takeListSt t s'
     where (x,s') = splitAt h s

 instead of

   takeList [] _         =  []
   takeList _ []         =  []
   takeList (n : ns) xs  =  head : takeList ns tail
       where (head, tail) = splitAt n xs

 we can see some differences, leading to different functions:

   *Main null $ takeListSt [1] undefined
   False
   *Main null $ takeList [1] undefined
   *** Exception: Prelude.undefined
   *Main takeList [0] []
   []
   *Main takeListSt [0] []
   [[]]

 and similarly for the 'scanl' version

   takeListSc ns xs = zipWith take ns $ init $ scanl (flip drop) xs ns

 Depending on usage, these differences might not matter, but what if
 we want these different styles to lead to the same function, with only
 stylistic and no semantic differences, taking the explicit recursion as
 our spec?

 In the 'State' version, the issue is that 'mapM' does not terminate
 early, while the specification requires an empty list whenever 'xs'
 (the state) is empty. Following the derivation at

 http://www.haskell.org/pipermail/haskell-cafe/2009-March/058603.html

 the first step where we have a handle on that is after unfolding
 'sequence':

   takeListSt = evalState . foldr k (return []) . map (State . splitAt)
     where k m m' = do x-m; xs-m'; return (x:xs)

 If we change that to

   takeListSt' = evalState . foldr k (return []) . map (State . splitAt)
     where k m m'    = cutNull $ do x-m; xs-m'; return (x:xs)
           cutNull m = do s-get; if null s then return [] else m

 and continue with the modified derivation, we should end up with
 the right spec (I haven't done this, so you should check!-). This
 isn't all that elegant any more, but support for 'mapM' with early
 exit isn't all that uncommon a need, either, so one might expect
 a 'mapM' variant that takes a 'cut' parameter to make it into the
 libraries.

 For the 'scanl' version, we have a more direct handle on the issue:
 we can simply drop the offending extras from the 'scanl' result,
 replacing 'init' with 'takeWhile (not.null)':

   takeListSc' ns xs = zipWith take ns $ takeWhile (not.null) $ scanl (flip
 drop) xs ns

 A somewhat abbreviated derivation at the end of this message
 seems to confirm that this matches the spec (as usual with proofs,
 writing them down doesn't mean that they are correct, but that
 readers can check whether they are).

 (btw, both 'takeListSt'' and 'takeListSc'' pass Thomas' 'testP', as does
 his 'partitions', but 'partitions' is not the same function as 'takeList':
 consider 

Re: [Haskell-cafe] happstack example code wanted

2009-04-04 Thread Thomas Hartman
Johannes,

  You'll have a better response if you post to the happs list.

  Have you had a look at tutorial.happstack.com?

  Thomas.

2009/4/4 Johannes Waldmann waldm...@imn.htwk-leipzig.de:
 Hi, I'm thinking of using happstack for a simple
 online registration system. [ Customer gives
 Name and Address and registers for certain workshops.
 Then the app server should just produce a bill.
 (Payment is handled through a different channel.)
 The store owner needs to get some overview of
 registrations. ] According to happs(tack) marketing
 department, this should be an easy exercise?
 Any code that I could use as a starting point?
 ( Or, if you do the coding, I can link to you from
 the workshop site. But I don't have a serious budget :-)
 Thanks - J.W.


 ___
 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] about Haskell code written to be too smart

2009-04-04 Thread Thomas Hartman
Thanks Claus,

  Indeed the problem was that I was using the Strict state monad, with
lazy state it does the right thing when run through testP. I will try
and get back to this thread if I manage the derivation which proves
(or at least supports) that the two versions are equivalent.



2009/4/4 Claus Reinke claus.rei...@talk21.com:
  takeListSt' = evalState . foldr k (return []) . map (State . splitAt)
    where k m m'    = cutNull $ do x-m; xs-m'; return (x:xs)
          cutNull m = do s-get; if null s then return [] else m

 |Not only is ths not that elegant anymore,
 As I was saying, sequence/mapM with early cutout is common
 enough that one might want it in the libraries, which would return
 this variant into readability again.

 |I think it *still* has a bug, stack overflow against

 That would really surprise me. Not that it is impossible - as I was
 also saying, I haven't replayed the derivation for the modified code.
 However, the modification was arrived at by taking the original
 derivation, seeing where its result deviated from the explicitly
 recursive specification, and spotting the aspect of the implicitly
 recursive version that was responsible for the deviation.
 Of course, the derivation itself could have an error, but equating the
 functions themselves gives me rather more confidence/coverage than any
 finite number of tests could. If I were to enter the derivation
 into a proof checking tool and be successful, that would further raise
 the level of confidence/coverage (leaving bugs in the proof checker).

 Note that I'm not asking whether the original spec did the right
 thing, only whether or not the variations correctly do the same
 thing as the original spec.

 |testP pf = mapM_ putStrLn  [
 |          show $ take 5 $ pf (repeat 0) [1,2,3]
 |          , show $ pf ( take 1000 [3,7..] ) [1..100]
 |          , show . pf [3,7,11,15] $ ( take (10^6) [1..])
 |          , show . head . last $ pf (take 1000 $ [3,3..]) [1..10^6]
 |        ]
 |
 |where the first test (with take 5) is new.
 |whereas the version with explicit recursion and pattern matching
 |doesn't suffer from this problem

 I get identical results for 'takeListSt'' and the original 'takeList1'
 (code repeated below).
 It took me a couple of moments to remember that you had been playing with
 Control.Monad.State.Strict instead of the default
 Control.Monad.State(.Lazy). That would invalidate the original derivation
 (different definition of '=', therefore a different end result after
 unfolding '='), let alone the modified code based on it.
 If you replay the derivation, taking the strictness variations into account,
 you should arrive at an explicitly recursive version that
 differs from the spec. Which might make it easier to see what
 the difference is.

 |partitions [] xs = []
 |partitions (n:parts) xs =
 |  let (beg,end) = splitAt n xs
 |  in  beg : ( case end of
 |               [] - []
 |               xs - partitions parts xs)

 That version cannot be transformed into the original spec, because
 it doesn't define the same function. As I mentioned:

 (btw, both 'takeListSt'' and 'takeListSc'' pass Thomas' 'testP', as does
 his 'partitions', but 'partitions' is not the same function as 'takeList':
 consider 'null $ takeList [1] undefined' and 'takeList [0] []' ;-)

 With the original spec

 takeList1 [] _         =  []
 takeList1 _ []         =  []
 takeList1 (n : ns) xs  =  h : takeList1 ns t
   where (h, t) = splitAt n xs

 and 'takeList4' being your 'partitions', we get:

 *Main null $ takeList1 [1] undefined
 *** Exception: Prelude.undefined
 *Main null $ takeList4 [1] undefined
 False
 *Main takeList1 [0] []
 []
 *Main takeList4 [0] []
 [[]]

 I am starting to think that the tricky part in all these functions is
 that by using higher order functions from the prelude, you sweep the
 failure case under the rug.

 Yes, the reason that more abstract functions are useful is that they
 hide irrelevant details, allowing us to spend our limited capacity on
 relevant details. If all abstract functions happen to hide details that
 matter, more concrete functions that expose those details can be more
 helpful.
 But even that has to be qualified: for instance, at first I found it easier
 to see the issues with the original 'State' variant in its transformed,
 explicitly recursive version, but after the derivation had convinced me that
 there was no magic going on, I realized that it was just the old 'mapM'
 doesn't stop early issue. So I could have seen the issue in the abstract
 form, but my mind (and apparently other minds, too;-) refused to think about
 the cornercases there until prompted.
 If not for this tendency to ignore details that might be relevant, the
 abstract code would provide an abstract treatment of the failure case as
 well: instead of working out the details by trying to find useful tests for
 the explicit pattern matches, we can just look at
 wether the definition uses 'mapM' or 'mapMWithCut', or whether
 

[Haskell-cafe] Is Text.XHtml.Table usable?

2009-03-29 Thread Thomas Hartman
I was playing with Text.XHtml.Table but couldn't use it to output tables.

( cell . toHtml $  a  ) `beside` (cell . toHtml $  b  )
tr
 a  b /tr


already seems wrong -- should be two cells, right? And the result
doesn't get embedded in a table tag?

Is there something I'm missing?

Working code samples would be great.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: mapM as a Space Leak (Was: [Haskell-cafe] about Haskell code written to be too smart)

2009-03-26 Thread Thomas Hartman
 I wonder if JHC
 or some other compiler might work better with these examples?

Are you saying that different compilers might give different answers?

Yikes!

Too clever indeed!

2009/3/26  rocon...@theorem.ca:
 On Wed, 25 Mar 2009, Thomas Hartman wrote:

 With the state version, there's a lot of behind-the-scenes magic, and
 as we've seen, things can go wrong.

 Also, the issue isn't infinite lists, but lists that are longer than
 the sum of the partitions provided. The state monad partition version
 goes equally as badly awry if the test is restructured as

 testP pf = mapM_ putStrLn  [
         show . pf ( take 1000 [3,7..] ) $ [1..10]
         , show . pf [3,7,11,15] $ ( take (10^6) [1..])
         , show . head . last $ pf (take 1000 $ [3,3..]) [1..10^6]
       ]

 This is interesting.  It seems to be the familiar issue that sequence does
 not play as nicely with the GC as one might imagine:
 http://www.reddit.com/r/haskell/comments/7itbi/mapm_mapm_and_monadic_statements/c06rwnb?context=1

 I suspect this may be a general problem that we will keep encountering when
 using higher-order functions, at least with this compiler.  I wonder if JHC
 or some other compiler might work better with these examples?

 --
 Russell O'Connor                                      http://r6.ca/
 ``All talk about `theft,''' the general counsel of the American Graphophone
 Company wrote, ``is the merest claptrap, for there exists no property in
 ideas musical, literary or artistic, except as defined by statute.''
 ___
 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: mapM as a Space Leak (Was: [Haskell-cafe] about Haskell code written to be too smart)

2009-03-26 Thread Thomas Hartman
Well, that's reassuring.

The reason I asked is that the testp function didn't just show poor
performance. The state monad implementation actually gave a different
answer -- nonterminating, where the pattern matching solution
terminated.

2009/3/26 Jonathan Cast jonathancc...@fastmail.fm:
 On Thu, 2009-03-26 at 12:29 -0700, Thomas Hartman wrote:
  I wonder if JHC
  or some other compiler might work better with these examples?

 Are you saying that different compilers might give different answers?

 Yikes!

 Too clever indeed!

 No, they might produce code with different performance characteristics.

 Which is very much what you want; there is no way to compile Haskell
 such that reasonable-looking code is

  a) Fast and
  b) Predictably performant.

 The idea of Haskell is to abstract away from the predictable performance
 of the code by a) using a good compiler, and b) putting absolute
 un-questioning faith in your profiler.

 jcc



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


Re: [Haskell-cafe] Really need some help understanding a solution

2009-03-26 Thread Thomas Hartman
Luke, does your explanation to Guenther have anything to do with
coinduction? -- the property that a producer gives a little bit of
output at each step of recursion, which a consumer can than crunch in
a lazy way?

I find that coinduction seems to figure frequently in algos that
process a stream.

So, Guenther, I'm not certain if coinduction figures in here yet but
it gives you another thing to google on. Co-induction seems to play
the same role for stream processing in haskell that tail recursiveness
plays in non-lazy languages
like lisp. That is, it's kind of the ideal to be striven for. Whereas
in haskell, tail recursive is frequently not the best thing because it
goes into a non-terminating state when there is an infinite data
structure which is crunched down to a finite one but at the wrong
point in the function pipeline.

see 
http://groups.google.com/group/fa.haskell/browse_thread/thread/4240bc7c7abd4d30/49f28f5a41519335?q=it+is+however+nicely+coinductive#49f28f5a41519335


2009/3/26 Luke Palmer lrpaln...@gmail.com:
 On Thu, Mar 26, 2009 at 12:21 PM, GüŸnther Schmidt gue.schm...@web.de
 wrote:y

 Hi guys,

 I tried for days now to figure out a solution that Luke Palmer has
 presented me with, by myself, I'm getting nowhere.

 Sorry, I meant to respond earlier.

 They say you don't really understand something until you can explain it to a
 six year old.  So trying to explain this to a colleague made me realize how
 little I must understand it :-).  But I'll try by saying whatever come to
 mind...

 Lazy list processing is all about right associativity.  We need to be able
 to output some information knowing that our input looks like a:b:c:...,
 where we don't know the ...  I see IntTrie [a] as an infinite collection of
 lists (well, it is [[a]], after all :-), one for each integer.  So I want to
 take a structure like this:

 (1,2):(3,4):(3,5):...

 And turn it into a structure like this:

 {
 0 - ...
 1 - 2:...
 2 - ...
 3 - 4:5:...
 ...
 }

 (This is just a list in my implementation, but I intended it to be a trie,
 ideally, which is why I wrote the keys explicitly)

 So the yet-unknown information at the tail of the list turns into
 yet-unknown information about the tails of the keys.  In fact, if you
 replace ... with _|_, you get exactly the same thing (this is no
 coincidence!)

 The spine of this trie is maximally lazy: this is key.  If the structure of
 the spine depended on the input data (as it does for Data.Map), then we
 wouldn't be able to process infinite data, because we can never get it all.
 So even making a trie out of the list _|_ gives us:

 { 0 - _|_, 1 - _|_, 2 - _|_, ... }

 I.e. the keys are still there.  Then we can combine two tries just by
 combining them pointwise (which is what infZipWith does).  It is essential
 that the pattern matches on infZipWith are lazy. We're zipping together an
 infinite sequence of lists, and normally the result would be the length of
 the shortest one, which is unknowable.  So the lazy pattern match forces the
 result ('s spine) to be infinite.

 Umm... yeah, that's a braindump.   Sorry I couldn't be more helpful.  I'm
 happy to answer any specific questions.

 Luke



 He has kindly provided me with this code:

 import Data.Monoid

 newtype IntTrie a = IntTrie [a]
    deriving Show

 singleton :: (Monoid a) = Int - a - IntTrie a
 singleton ch x = IntTrie $ replicate ch mempty ++ [x] ++ repeat mempty

 lookupTrie :: IntTrie a - Int - a
 lookupTrie (IntTrie xs) n = xs !! n

 instance (Monoid a) = Monoid (IntTrie a) where
    mempty                            = IntTrie (repeat mempty)
    mappend (IntTrie xs) (IntTrie ys) = IntTrie (infZipWith mappend xs ys)

 infZipWith f ~(x:xs) ~(y:ys) = f x y : infZipWith f xs ys

 test =  mconcat [singleton (n `mod` 42) [n] | n - [0..]] `lookupTrie` 10

 It's supposed to eventually help me group a list of key value pairs and
 then further process them in a linear (streaming like) way.

 The original list being something like [('a', 23), ('b', 18), ('a', 34)
 ...].

 There are couple of techniques employed in this solution, but I'm just
 guessing here.

 The keywords I've been looking up so far:

 Memmoization, Deforestation, Single Pass, Linear Map and some others.

 Can someone please fill me in?

 Günther

 ___
 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] Really need some help understanding a solution

2009-03-26 Thread Thomas Hartman
Re that link: search for wren's comments containing it is however
nicely coinductive

2009/3/26 Thomas Hartman tphya...@gmail.com:
 Luke, does your explanation to Guenther have anything to do with
 coinduction? -- the property that a producer gives a little bit of
 output at each step of recursion, which a consumer can than crunch in
 a lazy way?

 I find that coinduction seems to figure frequently in algos that
 process a stream.

 So, Guenther, I'm not certain if coinduction figures in here yet but
 it gives you another thing to google on. Co-induction seems to play
 the same role for stream processing in haskell that tail recursiveness
 plays in non-lazy languages
 like lisp. That is, it's kind of the ideal to be striven for. Whereas
 in haskell, tail recursive is frequently not the best thing because it
 goes into a non-terminating state when there is an infinite data
 structure which is crunched down to a finite one but at the wrong
 point in the function pipeline.

 see 
 http://groups.google.com/group/fa.haskell/browse_thread/thread/4240bc7c7abd4d30/49f28f5a41519335?q=it+is+however+nicely+coinductive#49f28f5a41519335


 2009/3/26 Luke Palmer lrpaln...@gmail.com:
 On Thu, Mar 26, 2009 at 12:21 PM, GüŸnther Schmidt gue.schm...@web.de
 wrote:y

 Hi guys,

 I tried for days now to figure out a solution that Luke Palmer has
 presented me with, by myself, I'm getting nowhere.

 Sorry, I meant to respond earlier.

 They say you don't really understand something until you can explain it to a
 six year old.  So trying to explain this to a colleague made me realize how
 little I must understand it :-).  But I'll try by saying whatever come to
 mind...

 Lazy list processing is all about right associativity.  We need to be able
 to output some information knowing that our input looks like a:b:c:...,
 where we don't know the ...  I see IntTrie [a] as an infinite collection of
 lists (well, it is [[a]], after all :-), one for each integer.  So I want to
 take a structure like this:

 (1,2):(3,4):(3,5):...

 And turn it into a structure like this:

 {
 0 - ...
 1 - 2:...
 2 - ...
 3 - 4:5:...
 ...
 }

 (This is just a list in my implementation, but I intended it to be a trie,
 ideally, which is why I wrote the keys explicitly)

 So the yet-unknown information at the tail of the list turns into
 yet-unknown information about the tails of the keys.  In fact, if you
 replace ... with _|_, you get exactly the same thing (this is no
 coincidence!)

 The spine of this trie is maximally lazy: this is key.  If the structure of
 the spine depended on the input data (as it does for Data.Map), then we
 wouldn't be able to process infinite data, because we can never get it all.
 So even making a trie out of the list _|_ gives us:

 { 0 - _|_, 1 - _|_, 2 - _|_, ... }

 I.e. the keys are still there.  Then we can combine two tries just by
 combining them pointwise (which is what infZipWith does).  It is essential
 that the pattern matches on infZipWith are lazy. We're zipping together an
 infinite sequence of lists, and normally the result would be the length of
 the shortest one, which is unknowable.  So the lazy pattern match forces the
 result ('s spine) to be infinite.

 Umm... yeah, that's a braindump.   Sorry I couldn't be more helpful.  I'm
 happy to answer any specific questions.

 Luke



 He has kindly provided me with this code:

 import Data.Monoid

 newtype IntTrie a = IntTrie [a]
    deriving Show

 singleton :: (Monoid a) = Int - a - IntTrie a
 singleton ch x = IntTrie $ replicate ch mempty ++ [x] ++ repeat mempty

 lookupTrie :: IntTrie a - Int - a
 lookupTrie (IntTrie xs) n = xs !! n

 instance (Monoid a) = Monoid (IntTrie a) where
    mempty                            = IntTrie (repeat mempty)
    mappend (IntTrie xs) (IntTrie ys) = IntTrie (infZipWith mappend xs ys)

 infZipWith f ~(x:xs) ~(y:ys) = f x y : infZipWith f xs ys

 test =  mconcat [singleton (n `mod` 42) [n] | n - [0..]] `lookupTrie` 10

 It's supposed to eventually help me group a list of key value pairs and
 then further process them in a linear (streaming like) way.

 The original list being something like [('a', 23), ('b', 18), ('a', 34)
 ...].

 There are couple of techniques employed in this solution, but I'm just
 guessing here.

 The keywords I've been looking up so far:

 Memmoization, Deforestation, Single Pass, Linear Map and some others.

 Can someone please fill me in?

 Günther

 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
What about

import Data.List

partAt n xs =
 let (beg,end) = splitAt n xs
 in beg : ( case end of
              [] - []
              xs - partAt n xs)

t = partAt 3 [1..10]


It's tail recursive (I think!) and should be pretty easy to understand
even for a beginner, no?

2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


 Manlio
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
sorry, wrong function.

should be

partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
   [] - []
   xs - partitions parts xs)


t = partitions [1,2,3] [1..10]


which is not quite as nice, I admit.

2009/3/25 Thomas Hartman tphya...@gmail.com:
 What about

 import Data.List

 partAt n xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
               [] - []
               xs - partAt n xs)

 t = partAt 3 [1..10]


 It's tail recursive (I think!) and should be pretty easy to understand
 even for a beginner, no?

 2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


 Manlio
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
 Are you saying there's a problem with this implementation? It's the

Yes, there is actually a problem with this implementation.

import Data.List
import Control.Monad.State
import Debug.Trace.Helpers


partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
   [] - []
   xs - partitions parts xs)

partitionsSimpleStupidGood = partitions

partitionsTooFrickinClever = evalState . mapM (State . splitAt)

testP pf = mapM_ putStrLn  [
  show . pf [3,7..] $ [1..10]
  , show . pf [3,7,11,15] $ [1..]
  , show . head . last $ pf [3,3..] [1..10^6]
]

*Main testP partitionsSimpleStupidGood
testP partitionsSimpleStupidGood^J[[1,2,3],[4,5,6,7,8,9,10]]
[[1,2,3],[4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20,21],[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]]
100

Now try testP partitionsTooFrickinClever

Now, I am sure there is a fix for whatever is ailing the State monad
version, and we would all learn a lesson from it about strictness,
laziness, and the State monad.

However, there is something to be said for code that just looks like a
duck and quacks like a duck. It's less likely to surprise you.

So... I insist... Easy for a beginner to read == better!


2009/3/24 Dan Piponi dpip...@gmail.com:
 Miguel Mitrofanov wrote:
 takeList = evalState . mapM (State . splitAt)

 However, ironically, I stopped using them for pretty
 much the same reason that Manlio is saying.

 Are you saying there's a problem with this implementation? It's the
 only one I could just read immediately. The trick is to see that
 evalState and State are just noise for the type inferencer so we just
 need to think about mapM splitAt. This turns a sequence of integers
 into a sequence of splitAts, each one chewing on the leftovers of the
 previous one. *Way* easier than both the zipWith one-liner and the
 explicit version. It says exactly what it means, almost in English.
 --
 Dan
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
Oh, and incidentally, if you change to Control.Monad.State.Strict

*Main testP partitionsTooFrickinClever
testP partitionsTooFrickinClever^J*** Exception: stack overflow

Don't get me wrong -- I have learned a lot from this thread, and I
think it would be really cool if there was a way to do this that is
clever, that is *right*.

But since the original point was about style, I think this underscores
the point that good style should be newbie friendly *if possible*.
Especially since being a newbie in haskell isn't like in other
languages -- might mean you have been using it for years as a hobby,
but just don't have comfort in certain monads and idioms.


2009/3/25 Thomas Hartman tphya...@gmail.com:
 Are you saying there's a problem with this implementation? It's the

 Yes, there is actually a problem with this implementation.

 import Data.List
 import Control.Monad.State
 import Debug.Trace.Helpers


 partitions [] xs = []
 partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
               [] - []
               xs - partitions parts xs)

 partitionsSimpleStupidGood = partitions

 partitionsTooFrickinClever = evalState . mapM (State . splitAt)

 testP pf = mapM_ putStrLn  [
          show . pf [3,7..] $ [1..10]
          , show . pf [3,7,11,15] $ [1..]
          , show . head . last $ pf [3,3..] [1..10^6]
        ]

 *Main testP partitionsSimpleStupidGood
 testP partitionsSimpleStupidGood^J[[1,2,3],[4,5,6,7,8,9,10]]
 [[1,2,3],[4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20,21],[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]]
 100

 Now try testP partitionsTooFrickinClever

 Now, I am sure there is a fix for whatever is ailing the State monad
 version, and we would all learn a lesson from it about strictness,
 laziness, and the State monad.

 However, there is something to be said for code that just looks like a
 duck and quacks like a duck. It's less likely to surprise you.

 So... I insist... Easy for a beginner to read == better!


 2009/3/24 Dan Piponi dpip...@gmail.com:
 Miguel Mitrofanov wrote:
 takeList = evalState . mapM (State . splitAt)

 However, ironically, I stopped using them for pretty
 much the same reason that Manlio is saying.

 Are you saying there's a problem with this implementation? It's the
 only one I could just read immediately. The trick is to see that
 evalState and State are just noise for the type inferencer so we just
 need to think about mapM splitAt. This turns a sequence of integers
 into a sequence of splitAts, each one chewing on the leftovers of the
 previous one. *Way* easier than both the zipWith one-liner and the
 explicit version. It says exactly what it means, almost in English.
 --
 Dan
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
Since this thread is ostensibly about haskell style, it should also be
about haskell style *today*.

As I think Yitz noted earlier, this is a moving target.

Adoption of haskell by the masses -- moving.
Skill of haskell hordes -- moving.
Abstractions available as part of idiomatic haskell, and correctness
of these abstractions, as the state monad for partitions cockup shows
-- also moving.

2009/3/25 Jonathan Cast jonathancc...@fastmail.fm:
 On Wed, 2009-03-25 at 12:48 -0700, Dan Weston wrote:
  However, there is something to be said for code that just looks like a
   duck and quacks like a duck. It's less likely to surprise you.
  
   So... I insist... Easy for a beginner to read == better!

 All you have said is that one building a skyscraper will need
 scaffolding, blueprints, and a good building inspector. The intended
 inhabitants of that skyscraper will not want to stare out at scaffolding
 for the rest of their lives.

 +1

 jcc



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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
Not only is your simpler function easier to read, it is also more correct.

partitionsHubris xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

partitionsBeginner :: [Int] - [a] - [[a]]
partitionsBeginner [] _ =  []
partitionsBeginner _ [] =  []
partitionsBeginner (n : ns) xs  =  head : partitionsBeginner ns tail
   where (head, tail) = splitAt n xs

Run both through testP to see why,.

testP pf = mapM_ putStrLn  [
  show . pf [3,7..] $ [1..10]
  , show . pf [3,7,11,15] $ [1..]
  , show . head . last $ pf [3,3..] [1..10^6]
]

Of course, I favor

partitions [] xs = []
partitions (n:parts) xs =
 let (beg,end) = splitAt n xs
 in beg : ( case end of
  [] - []
  xs - partitions parts xs)

which to my eyes is even easier to read (and also correct).

Pattern matching is awesome language feature. use it!


2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


 Manlio
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
s/Pattern matching is awesome language feature. use it!
 /Pattern matching is awesome language feature. Don't be ashamed to use it! /

:)


2009/3/25 Thomas Hartman tphya...@gmail.com:
 Not only is your simpler function easier to read, it is also more correct.

 partitionsHubris xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 partitionsBeginner :: [Int] - [a] - [[a]]
 partitionsBeginner [] _         =  []
 partitionsBeginner _ []         =  []
 partitionsBeginner (n : ns) xs  =  head : partitionsBeginner ns tail
   where (head, tail) = splitAt n xs

 Run both through testP to see why,.

 testP pf = mapM_ putStrLn  [
          show . pf [3,7..] $ [1..10]
          , show . pf [3,7,11,15] $ [1..]
          , show . head . last $ pf [3,3..] [1..10^6]
        ]

 Of course, I favor

 partitions [] xs = []
 partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
              [] - []
              xs - partitions parts xs)

 which to my eyes is even easier to read (and also correct).

 Pattern matching is awesome language feature. use it!


 2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


 Manlio
 ___
 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] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
 Beginner list processing code can and often does go awry when presented with 
 infinite lists.

I didn't mean code that a beginner would write, I mean code that would
be easy to understand for a beginner to read -- that is, explicit
pattern matching, explicit recursion, no gratuitous use of state
monad.

I don't think I necessarily would have written my favored version when
learning haskell, probably something a lot uglier.

What I like about the pattern matching is the totality -- you see all
the possible inputs, and you see what happens.

With the state version, there's a lot of behind-the-scenes magic, and
as we've seen, things can go wrong.

Also, the issue isn't infinite lists, but lists that are longer than
the sum of the partitions provided. The state monad partition version
goes equally as badly awry if the test is restructured as

testP pf = mapM_ putStrLn  [
  show . pf ( take 1000 [3,7..] ) $ [1..10]
  , show . pf [3,7,11,15] $ ( take (10^6) [1..])
  , show . head . last $ pf (take 1000 $ [3,3..]) [1..10^6]
]

(no infinite lists, just long lists)



2009/3/25 Dan Piponi dpip...@gmail.com:
 On Wed, Mar 25, 2009 at 12:44 PM, Thomas Hartman tphya...@gmail.com wrote:
 Are you saying there's a problem with this implementation? It's the

 Yes, there is actually a problem with this implementation.

 However, there is something to be said for code that just looks like a
 duck and quacks like a duck. It's less likely to surprise you.

 Well the problem here isn't that the code does something surprising.
 It's author was making assumptions about the type of input that it's
 going to get. I think that's an orthogonal issue.

 So... I insist... Easy for a beginner to read == better!

 Not at all. Beginner list processing code can and often does go awry
 when presented with infinite lists.

 The moral here has nothing to do with readability by beginners. It's:
 if the function you're defining could be extended naturally to
 infinite lists, and it would be useful to do so, then make it do so.
 --
 Dan

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


[Haskell-cafe] MissingH bracketCD (aka bracketCWD) bug -- this is the infamous lazy io, right?

2009-03-23 Thread Thomas Hartman
I got bitten by  a bug (well, I call it bug) in bracketCD from
HSH/MissingH demonstrated by the following code

bracketCD is very useful for sysadminny one-offs, I use it all the
time, but. I suspect that unless people are very careful, this
behavior will affect other users of bracketCD, in potentially very
subtle and tricky ways.

1) -- is there a more elegant way to deal with lazy io than the hack
below? (putStrLn the last character)
2) -- should MissingH function bracketCD be fixed, and if so how?

import System.FilePath.Find (find)
import System.Directory (getDirectoryContents, getCurrentDirectory,
setCurrentDirectory)
import System.Path (bracketCWD) -- from MissingH

-- the fixed function, a more restrictive type than bracketCWD which
lets you do any io, not just showables
myBracketCWD :: Show a = FilePath - IO a - IO a
myBracketCWD fp action =
do oldcwd - getCurrentDirectory
setCurrentDirectory fp
a - action
putStrLn $ show . last . show $ a -- force evaluation
setCurrentDirectory oldcwd
return a

-- rather than listing /, lists dir this module is in
tWrong = bracketCWD / $ return . take 2 = listCurrentWithFind

-- this lists filesystem root
tRight = myBracketCWD / $ return . take 2 = listCurrentWithFind

listCurrentWithFind = System.FilePath.Find.find (return True) (return True) .

-- for some reason, bracketCWD does the right thing with get
tGetContents = myBracketCWD / $ return . take 2 = getDirectoryContents .

Actual code for bracketCWD in MissingH:

-- this is from MissingH, seems there's a bug when attempt to wrap a
find command
bracketCWD :: FilePath - IO a - IO a
bracketCWD fp action =
do oldcwd - getCurrentDirectory
   setCurrentDirectory fp
   finally action (setCurrentDiurectory oldcwd)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Has anybody replicated =~ s/../../ or even something more basic for doing replacements with pcre haskell regexen?

2009-03-17 Thread Thomas Hartman
2009/3/16 ChrisK hask...@list.mightyreason.com:

 Let me open the discussion with all the questions I can quickly ask:

  What should the subRegex function do, exactly?
  (Single replacement,global replacement,once per line,...)

Try to do the same thing as =~ s/../../ in perl.

For a version 1: Global replacements, don't treat newlines separately,
^ and $ anchor at start and end of string.

There could be a Bool option to support multiline replacement modes.


  What should the replacement template be able to specify?
  (Can it refer to all text before a match or all text after?)
  (Can it access the start/stop offsets as numbers?)

Again, follow =~ s/../../

I'm not sure what =~ allows in this dimension though.

My instinct is

 (Can it refer to all text before a match or all text after?)

no

  (Can it access the start/stop offsets as numbers?)

no

But maybe that's just because I've never needed the above functionality.

I basically think of =~ s as quick cleanup for dirty text solution,
nothing approaching full-fledged parsing.

  Should the replacement template be specif~ied in a String?

Sure, just like it is in Text.Regex.subRegex now. No combinators,
\numbered capture references are fine.

 As an abstract
 data type or syntax tree?  With combinators?

Just a string I think.

  What happens if the referenced capture was not made?  Empty text?

Return the original string. Isn't that what subRegex already does?

  How will syntax errors in the template be handled (e.g. referring to a
 capture that does not exist in the regular expression)?

runtime error

  Will the output text be String? ByteString? ByteString.Lazy? Seq Char?
  Note: String and Strict Bytestrings are poor with concatenation.

String. Add support for others if users holler for it


  Can the output text type differ from the input text type?

Nah.

My 2c.


 --
 Chris

 ___
 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


  1   2   3   4   >