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 :
> 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 :
> 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 extracti

[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


[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] 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 :
> 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


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 :
> 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] 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 :
> 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 :
> +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  wrote:
>> On 05/29/2010 08:05 PM, Gregory Collins wrote:
>>>
>>> Matt Parker  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
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 :
> 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] 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 :
> Consider the following bash session:
>
> [ a...@kizaru:~/ ]$ which trhsx
> /home/ajs/.cabal/bin/trhsx
>
> [ a...@kizaru:~/ ]$ trhsx
> Usage: trhsx  []
>
> [ 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
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 :
>
>
> On Fri, Apr 23, 2010 at 11:34 AM, John Goerzen 
> 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


[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] 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 :
> 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  wrote:
>> Casey Hawthorne  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


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 :
> 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 :
>> 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
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 :
> 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] 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 :
> 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 :
>> 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  wrote:
>>>
>>> Thanks, I altered my top level request handler as follows
>>>
>>> mysmartserver conf h stateProxy = do
>>>      socket <- bindPort conf
>>>
>>>       
>>>       >> 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 :
>>> > 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 :
> 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  wrote:
>>
>> Thanks, I altered my top level request handler as follows
>>
>> mysmartserver conf h stateProxy = do
>>      socket <- bindPort conf
>>
>>       
>>       > 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 :
>> > 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
Thanks, I altered my top level request handler as follows

mysmartserver conf h stateProxy = do
  socket <- bindPort conf

   
   :
> 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 :
> 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] How many "Haskell Engineer I/II/III"s 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 :
> 2010/02/10 Roderick Ford :
>> 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] 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 :
> 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] 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 :
> On Sun, Feb 7, 2010 at 9:22 AM, Bardur Arantsson 
> 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 :
> 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:
>
> : 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  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 :
> 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


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 :
> 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 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


[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 

> 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 :

> 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 :
> 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: ghci can't find Paths_ module created by cabal

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

thart...@ubuntu:~/haskellInstalls/gitit>thartman_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 :
> 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
>
> :
>    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] 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 :
> 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] 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] 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 :
> 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] 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] 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 :
> 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] 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


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 :
>> 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 :
>> On Fri, Oct 9, 2009 at 2:05 PM,   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
> 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 :
> On Fri, Oct 9, 2009 at 2:05 PM,   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
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  :
>
>
> 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


[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 :
> 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:
>
>  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?
>  my goal is to patch time package so can do data generics deriving.
>
>  patch-tag, use System.Time instead?
> * Berengal shrugs and sighs                                             
> [12:20]
>  could try that...
> *** o-regalia (n=o-reg...@host-0-130.mimpvbg.clients.pavlovmedia.com)
> has
>   quit: "Lost terminal"
>  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
>
>
>
>  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
>  If it were exported, it'd be pretty easy
>  hw can I use UTCTime, deriving Typeable and Data? (want to
> use
>           UTCTime in happstack).
>  http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=4278#a4278
>  I guess I should have said I'd like to use newtype
> deriving rather
>           than define instance myself if that's possible.
>
>
>  patch-tag, that's possible, but could break other things.
> The
>          correct solution is to patch the existing package, but that
> takes
>          time
>  patch-tag, Day, or something. Can't remember off the top of my head
> *** paolino (n=paol...@87.7.161.162) has quit: "Leaving."
>  Philonous : if you can't implement both operations (satisfying
> laws),
>     though, it is probably better to make a new class                 [12:09]
>  Berengal: a package is hidden if when you do :info in
> ghci, it
>           comes out as fully qualified, right?
>  pity also that newtype deriving doesn't give you a nicer
> error
>           message like "deriving choked at type blah"
>  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] 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:

 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?
 my goal is to patch time package so can do data generics deriving.

 patch-tag, use System.Time instead?
* Berengal shrugs and sighs [12:20]
 could try that...
*** o-regalia (n=o-reg...@host-0-130.mimpvbg.clients.pavlovmedia.com)
has
   quit: "Lost terminal"
 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



 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
 If it were exported, it'd be pretty easy
 hw can I use UTCTime, deriving Typeable and Data? (want to
use
   UTCTime in happstack).
 http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=4278#a4278
 I guess I should have said I'd like to use newtype
deriving rather
   than define instance myself if that's possible.


 patch-tag, that's possible, but could break other things.
The
  correct solution is to patch the existing package, but that
takes
  time
 patch-tag, Day, or something. Can't remember off the top of my head
*** paolino (n=paol...@87.7.161.162) has quit: "Leaving."
 Philonous : if you can't implement both operations (satisfying
laws),
 though, it is probably better to make a new class [12:09]
 Berengal: a package is hidden if when you do :info in
ghci, it
   comes out as fully qualified, right?
 pity also that newtype deriving doesn't give you a nicer
error
   message like "deriving choked at type blah"
 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
correction, happstutorial is now tutorial.happstack.com.

2009/10/2 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 :
>> 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               +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
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 :
> 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               +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 :
> 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  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 :
>> > 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 :
> 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] uncommon IMO problem - toilet management

2009-07-18 Thread Thomas Hartman
I enjoyed learning from this app and seeing monad transformers in
action. One nit, the parsing seems a bit wonky

It would be nice to use parsec here, perhaps, rather than this hand
rolled, and complain about input that can't be parsed rather than just
say "toilet free" or whatever is going on here.

thart...@ubuntu:~/tmp>toilet
asdf 123
   ASDF 123 enters toilet at 21:08
asdf 123 123
   toilet blocked by ASDF123 since 21:08
asdf 124 123
   toilet blocked by ASDF123 since 21:08
asdf 123
   ASDF 123 leaves toilet at 21:09
asdf 124 123
   toilet free
asdf 124
   ASDF 124 enters toilet at 21:09
1234 124 124
   toilet free
asdf 124
   ASDF 124 leaves toilet at 21:09


2009/7/17 Henning Thielemann :
>
> In the last two days I was invigilator at the International Mathematic
> Olympics 2009 in Bremen, Germany. There we got a problem different from the
> official math problems. :-) Eventually I solved it using Haskell. Read the
> detailed description at
>  http://hackage.haskell.org/package/toilet-0.0.1
>
> I think the problem is simple enough to be used in education of programming.
>
> (I also think it would have been better to avoid monads and use lazy list
> processing.)
> ___
> 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 :
> 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] 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-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
:
> 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] 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 :
> 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] 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: 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 :
> 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] 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


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 :
> On Wed, Jul 15, 2009 at 6:35 PM, Ryan Ingram 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


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 :
> On Wed, Jul 15, 2009 at 3:02 AM, Thomas Hartman 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


[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 :
> On Fri, Jun 19, 2009 at 6:17 AM, Matthew Brecknell 
> 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


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 :
>> 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:~/perlArena>cat splitEm.
>>> splitEm.hs   splitEm.hs~  splitEm.pl   splitEm.pl~
>>> thart...@ubuntu:~/perlArena>cat 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 = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>"
>>> badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,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 = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>"
>> badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,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


[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:~/perlArena>cat splitEm.
splitEm.hs   splitEm.hs~  splitEm.pl   splitEm.pl~
thart...@ubuntu:~/perlArena>cat 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 = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>"
badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,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] 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 :
>> 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 :
>> Thomas Hartman  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: : 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-strict>runghc 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 :
>> 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 :
>> Thomas Hartman  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: : 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-strict>runghc 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 :
> Thomas Hartman  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: : 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-strict>runghc 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
seems to be the same behavior whether in ghci or compiled with ghc.

2009/5/5 Ketil Malde :
> Thomas Hartman  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: : 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-strict>runghc 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
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: : 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-strict>runghc 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 :
>
> 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


[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


[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


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/testing>cat 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 :
> 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
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 :
> 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] 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 :
> 2009/4/25 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/debugger>cat 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


[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/base>head
Prelude.hs
{-# OPTIONS_GHC -XNoImplicitPrelude #-}
-

thart...@ubuntu:~/haskellInstalls/ghcInstalls/source/ghc-6.10.1/libraries/base>ghci
-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.
: module `Prelude' is not loaded

thart...@ubuntu:~/haskellInstalls/ghcInstalls/source/ghc-6.10.1/libraries/base>ghci
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.
: module `Prelude' is not loaded
___
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 :
> 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 :
>>
>> 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
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 :
>
> 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/debugger>cat 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/debugger>ghci 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 :
> Thanks. It looks like mergeBy will do the job, but is it available in Hugs?
>
> Michael
>
>
> --- On Sun, 4/5/09, Henning Thielemann 
> wrote:
>
> From: Henning Thielemann 
> Subject: Re: [Haskell-cafe] Combining sequences
> To: "michael rice" 
> 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
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 :
>>  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 explic

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 :
> 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
>   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 :
> 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

[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 " )
 a  b 

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: [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 :
> 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 :
>> On Thu, Mar 26, 2009 at 12:21 PM, GüŸnther Schmidt 
>> 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

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 :
> On Thu, Mar 26, 2009 at 12:21 PM, GüŸnther Schmidt 
> 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: 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 :
> 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: 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  :
> 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: [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 :
> On Wed, Mar 25, 2009 at 12:44 PM, Thomas Hartman  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


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 :
> 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 :
>> 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
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 :
> 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
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 :
> 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
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 :
>> 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 :
>>> 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
> 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 :
>> 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
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 :
> 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 :
>> 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
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 :
> 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


[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


  1   2   3   4   >