ajb | 1 May 2006 09:19
Favicon
Gravatar

Re: Newbie: Haskell Sine Oddities

G'day all.

Aditya Siram wrote:

> > Prelude> sin pi
> > 1.22460635382238e-16  --WRONG!

Quoting Scott Turner <p.turner <at> computer.org>:

> This value, the computer's pi, differs from true pi by
>    0.000000000000000122...

Exercise for those doing numeric analysis 101: Explain why
these two numbers are approximately the same.

And if you found that one too easy, show how quickly
following iteration converges to pi.

    iterate (\x -> x + sin x) 1

Cheers,
Andrew Bromage
Brian Hulley | 2 May 2006 01:12

Code review: efficiency question

Hi -
I started off writing the following piece of monadic code:

    let
          drawModal :: Control -> ManagerM ()
          drawModal c = do -- details omitted

          -- Prolog style coding...
          drawModals :: [Control] -> ManagerM ()
          drawModals [] = return ()
          drawModals (c:cs) = do
                                               drawModals cs
                                               drawModal c
    drawModals cs

then it struck me that I should have not bothered with drawModals and 
instead should just have used:

    mapM_ drawModal (reverse cs)

However, while this looks more elegant, it is less efficient?
In other words, how much optimization can one assume when writing Haskell 
code?
I'm trying to get a rough idea so I can decide whether to write helper 
functions such as drawModals in future or whether I should always just use 
the most elegant code instead.

Any ideas?

Thanks, Brian. 
(Continue reading)

ajb | 2 May 2006 01:44
Favicon
Gravatar

Re: Code review: efficiency question

G'day all.

Quoting Brian Hulley <brianh <at> metamilk.com>:

> Hi -
> I started off writing the following piece of monadic code:
>
>     let
>           drawModal :: Control -> ManagerM ()
>           drawModal c = do -- details omitted
>
>           -- Prolog style coding...
>           drawModals :: [Control] -> ManagerM ()
>           drawModals [] = return ()
>           drawModals (c:cs) = do
>                                                drawModals cs
>                                                drawModal c
>     drawModals cs
>
> then it struck me that I should have not bothered with drawModals and
> instead should just have used:
>
>     mapM_ drawModal (reverse cs)
>
> However, while this looks more elegant, it is less efficient?

I suspect it depends how long the list is.  The original drawModals
would probably be more efficient for small lists, because it doesn't
require creating an intermediate list.  OTOH, it may well be less
efficient for longer lists because it can't take advantage of tail
(Continue reading)

Brian Hulley | 2 May 2006 03:08

Re: Code review: efficiency question

ajb <at> spamcop.net wrote:
> I suspect it depends how long the list is.  The original drawModals
> would probably be more efficient for small lists, because it doesn't
> require creating an intermediate list.  OTOH, it may well be less
> efficient for longer lists because it can't take advantage of tail
> recursion.

Thanks for pointing this out - I'd forgotten all about the impact of having 
non-tail recursion, so my original Prolog-style code was not necessarily 
more efficient anyway, since it may be cheaper to allocate list elements 
than to allocate activation records for recursion.

>> I'm trying to get a rough idea so I can decide whether to write
>> helper functions such as drawModals in future or whether I should
>> always just use the most elegant code instead.
>
> This is a question that is independent of Haskell. You should ALWAYS
> write the most elegant code first, and only make it uglier if it's not
> fast enough.
> [snip]

The scales have tipped in balance of the elegant mapM_ version! :-)

Thanks, Brian. 
Evan Martin | 2 May 2006 03:43

Re: Code review: efficiency question

I remember reading a tutorial that pointed out that you can often
avoid explicit recusion in Haskell and instead use higher-level
operators.

For your code, I think
  drawModals = foldr (flip (>>)) (return ()) . map drawModal
works(?).

On 5/2/06, Brian Hulley <brianh <at> metamilk.com> wrote:
> Hi -
> I started off writing the following piece of monadic code:
>
>     let
>           drawModal :: Control -> ManagerM ()
>           drawModal c = do -- details omitted
>
>           -- Prolog style coding...
>           drawModals :: [Control] -> ManagerM ()
>           drawModals [] = return ()
>           drawModals (c:cs) = do
>                                                drawModals cs
>                                                drawModal c
>     drawModals cs
>
> then it struck me that I should have not bothered with drawModals and
> instead should just have used:
>
>     mapM_ drawModal (reverse cs)
>
> However, while this looks more elegant, it is less efficient?
(Continue reading)

Brian Hulley | 2 May 2006 09:45

Re: Code review: efficiency question

Evan Martin wrote:
> I remember reading a tutorial that pointed out that you can often
> avoid explicit recusion in Haskell and instead use higher-level
> operators.
>
> For your code, I think
>   drawModals = foldr (flip (>>)) (return ()) . map drawModal
> works(?).

I think it would be foldl so that the (return()) would be nested as the 
leftmost element.
Thanks for pointing out this point-free version of drawModals, although for 
readability at the moment I think I still prefer just to use mapM_ drawModal 
(reverse cs)

Best regards, Brian. 
Bulat Ziganshin | 2 May 2006 10:30
Picon

Re: Code review: efficiency question

Hello Brian,

Tuesday, May 2, 2006, 3:12:48 AM, you wrote:

>           -- Prolog style coding...
>           drawModals :: [Control] -> ManagerM ()
>           drawModals [] = return ()
>           drawModals (c:cs) = do
>                                                drawModals cs
>                                                drawModal c

imho, it's typical functional style, but without using higher-level
functions

>     mapM_ drawModal (reverse cs)

> However, while this looks more elegant, it is less efficient?
> In other words, how much optimization can one assume when writing Haskell
> code?

ghc will don't translate your later code into the former one. although
in general ghc (but not other haskell compilers, afaik) is very good
in replacing one code with another faster one and in particular in
translating "list producer + list consumer" into straightforward loop

how about this solution:

reverseMapM_ f (x:xs) = do reverseMapM_ f xs; f x
reverseMapM_ f []     = return ()

(Continue reading)

Simon Marlow | 2 May 2006 14:27
Picon

Re: database access recommendation

Bulat Ziganshin wrote:
> Hello Donald,
> 
> Friday, April 28, 2006, 12:29:38 PM, you wrote:
> 
> 
>>>>I looked at http://www.haskell.org/haskellwiki/Libraries_and_tools, and
>>>
>>>suffice it to say that this page don't reflects current state of the
>>>art. during many years it was not updated and when it was moved to the
>>>wiki half-year ago it's contents remains the stone-age
> 
> 
>>About a month ago I went through the entire HWN archives, the haskell <at> 
>>archives back to 1990 (Check the Old_news page!) and the last HCAR,
>>adding over 100 entries to the libraries page.
> 
> 
>>So, I argue it is the most complete list we have.
> 
> 
> GREAT! but you don't announced this work on the haskell list, so noone
> can know about it

Point your favourite RSS reader at  	

  http://haskell.org/haskellwiki/?title=Special:Recentchanges&feed=atom

and watch the changes!

(Continue reading)

Mirko Rahn | 2 May 2006 14:27
Picon
Favicon

Re: GetOpt

Tomasz Zielonka wrote:

>>and handle options as functions from Config to Config:

> I find this approach very convenient, but I push it a bit further. Some
> time ago I wrote a small article about this:

>     http://www.haskell.org/pipermail/haskell/2004-January/013412.html

[from there]

 > -- Here we thread startOptions through all supplied option actions
 > opts <- foldl (>>=) (return startOptions) actions

So the order in actions is important and therefore the order of options 
on the commandline is important.

But how to handle dependencies between options using this technique? I 
can image two solutions:
1: Every dependency 'a implies b' has to be checked in both functions, 
the one for a and the one for b.
2: An order for the actions has to be specified, maybe by decorating the 
option list with priorities.

But both solutions seems to be tedious and error prone.

In contrast the sum-type technique first reads all options and then 
post-processes the complete set. Here the order of options on the 
commandline has no impact on the final result.

(Continue reading)

Paolo Martini | 2 May 2006 18:27
Picon

Summer of Code - Student Application Form

Hi,

it was just published the student application form, you can find it at:

<http://code.google.com/soc/student_step1.html>

I hope we will be collecting good Haskell applications from students :-)

I am very happy to see how many did signed up on the People page as now:

<http://hackage.haskell.org/trac/summer-of-code/>

Keep on writing!
Paolo.
--

Gmane