Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Donn Cave
Quoth Duncan Coutts duncan.cou...@worc.ox.ac.uk:

 You must not do this. It breaks the semantics of the language.

 Other people have given practical reasons why you should not but a
 theoretical reason is that you've defined a non-continuous function.
 That is impossible in the normal semantics of pure functional languages.
 So you're breaking a promise which we rely on.

Could you elaborate a little, in what sense are we (?) relying on it?

I actually can't find any responses that make a case against it on a
really practical level - I mean, it seems to be taken for granted that
it will work as intended, and we're down to whether we ought to have
such intentions, as a matter of principle.  If you've identified a
problem here with semantics that would break normal evaluation, from
the perspective of the programmer's intention, then this would be
the first practical reason?

Donn

 It is not safe. It's almost as bad as a function isBottom, which is
 the canonical non-continuous function. It's defined by:

 isBottom _|_ = True
 isBottom _   = False

 Of course your tryArith only tests for certain kinds of _|_ value, but
 in principle the problem is the same.

 It is not safe because it distinguishes values that are not supposed to
 be distinguishable. This invalidates many properties and
 transformations.

 Duncan

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jake McArthur

Donn Cave wrote:

Could you elaborate a little, in what sense are we (?) relying on it?

I actually can't find any responses that make a case against it on a
really practical level - I mean, it seems to be taken for granted that
it will work as intended, and we're down to whether we ought to have
such intentions, as a matter of principle.  If you've identified a
problem here with semantics that would break normal evaluation, from
the perspective of the programmer's intention, then this would be
the first practical reason?


Off the top of my head, here is a possible case:

foo :: Int - Int
foo x = ... -- something that might throw an exception

bar :: Int - Blah
bar x = ... -- internally use foo and catch the exception

baz :: Int - Blah
baz = bar . foo

In this case, if the foo in baz throws an exception, I think bar may 
catch it and attempt to handle it as if the foo in bar had thrown it, 
but we probably would have expected this exception to go all the way to 
the top level and halt the program since exceptions are usually due to 
programmer error.


But I didn't test this, and since this isn't something I've ever done 
before I can't be 100% sure of its behavior.


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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jonathan Cast
On Tue, 2009-03-24 at 23:13 -0700, Donn Cave wrote:
 Quoth Duncan Coutts duncan.cou...@worc.ox.ac.uk:
 
  You must not do this. It breaks the semantics of the language.
 
  Other people have given practical reasons why you should not but a
  theoretical reason is that you've defined a non-continuous function.
  That is impossible in the normal semantics of pure functional languages.
  So you're breaking a promise which we rely on.
 
 Could you elaborate a little, in what sense are we (?) relying on it?
 
 I actually can't find any responses that make a case against it on a
 really practical level - I mean, it seems to be taken for granted that
 it will work as intended,

It shouldn't be.

Consider:

loop = loop
blam = error blam
notReallyTry = unsafePerformIO . try . evaluate

Now, normally, we have, for all x, y,

  x `seq` y `seq` x
= y `seq` x

But we clearly do *not* have this for x = blam, y = loop, since the
equality isn't preserved by notReallyTry:

notReallyTry $ blam `seq` loop `seq` blam = Left (ErrorCall blam)
notReallyTry $ loop `seq` blam= loop

Now, say a compiler sees the definition

foo x y = x `seq` y `seq` x

in one module, and then in a later one

expectToBeTotal = notReallyTry $ foo blam loop

?  What happens if the compiler, while compiling foo, notices that x is
going to be evaluated eventually anyway, and decides against forcing it
before y?

What if foo was written as

foo (!x) (!y) = x

?  Which order are the evaluations performed in?  In a purely functional
language, it doesn't matter; but all of a sudden with impure operations
like notReallyTry popping up, it does.

jcc


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


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Heinrich Apfelmus
Manlio Perillo wrote:
 Conal Elliott ha scritto:
 Manlio,

 We live in the age of participation -- of co-education.  Don't worry
 about text-books.  Contribute to some wiki pages  blogs today that
 share these smart techniques with others.

 
 When I started learning Haskell (by my initiative), what I did was:
 
 [steps 1) - 9), mostly internet tutorials ]

I think you'd have had a much easier time by starting with a proper book
right away, like Richard Bird's Introduction to Functional Programming
in Haskell, accompanied by Real World Haskell. You see, the reason that
books cost money is (should be) high quality content. :)


Regards,
apfelmus

--
http://apfelmus.nfshost.com

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


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Heinrich Apfelmus
Dan Piponi wrote:
 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.

I couldn't agree more. In other words,  splitAt  is really to be thought
of as a function that lives in the state monad.


Regards,
apfelmus

--
http://apfelmus.nfshost.com

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


[Haskell-cafe] Definition of tail recursive wrt Folds

2009-03-25 Thread Mark Spezzano
Hi,

 

Just looking at the definitions for foldr and foldl I see that foldl is
(apparently) tail recursive while foldr is not.

 

Why?

 

Is it because foldl defers calling itself until last whereas foldr evaluates
itself as it runs?

 

What, strictly speaking, is the definition of ”tail recursive” as opposed to
just “recursive”?

 

Cheers,

 

Mark Spezzano

 


No virus found in this outgoing message.
Checked by AVG. 
Version: 7.5.557 / Virus Database: 270.11.27/2021 - Release Date: 24/03/2009
4:00 PM
 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Definition of tail recursive wrt Folds

2009-03-25 Thread 司馬泰
wikipedia is your friend...

http://en.wikipedia.org/wiki/Fold_(higher-order_function)

Tammo

2009/3/25 Mark Spezzano mark.spezz...@chariot.net.au:
 Hi,



 Just looking at the definitions for foldr and foldl I see that foldl is
 (apparently) tail recursive while foldr is not.



 Why?



 Is it because foldl defers calling itself until last whereas foldr evaluates
 itself as it runs?



 What, strictly speaking, is the definition of ”tail recursive” as opposed to
 just “recursive”?



 Cheers,



 Mark Spezzano



 No virus found in this outgoing message.
 Checked by AVG.
 Version: 7.5.557 / Virus Database: 270.11.27/2021 - Release Date: 24/03/2009
 4:00 PM

 ___
 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 Colin Adams
2009/3/24 Jonathan Cast jonathancc...@fastmail.fm:
 On Tue, 2009-03-24 at 22:33 +0300, Eugene Kirpichov wrote:
 Pretty cool once you know what the function does, but I must admit I
 wouldn't immediately guess the purpose of the function when written in
 this way.

 I wouldn't immediately guess the purpose of the function written in any
 way.

 I think, in general, the best way to document the purpose of the
 function is

    -- | Split a function into a sequence of partitions of specified
 lenth
    takeList :: [Int] - [a] - [[a]]

Thank-you Jonathan.

That's the first message in this thread I've manage to understand.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
What about

import Data.List

partAt n xs =
 let (beg,end) = splitAt n xs
 in beg : ( case end of
              [] - []
              xs - partAt n xs)

t = partAt 3 [1..10]


It's tail recursive (I think!) and should be pretty easy to understand
even for a beginner, no?

2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


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

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


RE: [Haskell-cafe] Are there performant mutable Arrays in Haskell?

2009-03-25 Thread Brettschneider, Matthias
  To make a long story short, here is the library code:
  elems arr = case bounds arr of
(_l, _u) - [unsafeAt arr i | i - [0 .. numElements arr - 1]
 
  And my version:
  boundedElems arr = case bounds arr of
(_l, _u) - [unsafeAt arr i | i - [1737 .. 1752]]
 
  Is there a reason, why the library version is 4 times faster, than
 mine?
 
 There shouldn't be any reason.  Try putting
 
 {-# INLINE boundedElems #-}
 
 to make it inline, it might be faster.


Ah, ok, did that, but no difference. :) 
If I got it right, for the library version exists a C-translation while
for my version there isn't. 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
sorry, wrong function.

should be

partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
   [] - []
   xs - partitions parts xs)


t = partitions [1,2,3] [1..10]


which is not quite as nice, I admit.

2009/3/25 Thomas Hartman tphya...@gmail.com:
 What about

 import Data.List

 partAt n xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
               [] - []
               xs - partAt n xs)

 t = partAt 3 [1..10]


 It's tail recursive (I think!) and should be pretty easy to understand
 even for a beginner, no?

 2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


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


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


Re: [Haskell-cafe] The votes are in!

2009-03-25 Thread Loup Vaillant
2009/3/24 John Van Enk vane...@gmail.com:
 If any one seconds the motion, i'm picking up this part of the thread and
 putting it in the humor section of the haskell wiki.
 /jve

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


Re: [Haskell-cafe] Re: Grouping - Map / Reduce

2009-03-25 Thread Martin Huschenbett

Dear Günther,

the map can't be consumed while it is constructed. At any point during 
its construction you don't know for any key in the map if it will appear 
in the not cosumed rest of the list again. This means you can't process 
any entry of the map because it may change later. The only point when 
nothing will change anymore is when the map is completely constructed.


Regards,

Martin.


GüŸnther Schmidt schrieb:

Hi Ketil,

Ketil Malde schrieb:

Gü?nther Schmidt gue.schm...@web.de writes:


let say I got an unordered lazy list of key/value pairs like

[('a', 99), ('x', 42), ('a', 33) ... ]

and I need to sum up all the values with the same keys.

So far I wrote a naive implementation, using Data.Map, foldl and 
insertWith.


Data.Map.fromListWith (+)


The building of this map is of course a bottleneck, the successive
processing needs to wait until the entire list is eventually consumed
the Map is built and flattened again.


Sure this is not an artifact of the laziness of foldl?


well I can't really see how the map could be consumed *while* it's still 
being built, I just don't see it. (I'm using foldl' and insertWith', sry 
for not saying so initially).





Is there another way of doing this, something more streaming
architecture like?


I don't see how you can do this much better - for a small, fixed set
of keys, you could use an (STU) array for the sums, but it depends if
the added complexity is worth it.  You're already doing a single pass
over the data.

-k



___
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] STM orElse semantics

2009-03-25 Thread Tom Davies

I'm not 100% clear on the behaviour of the STM function orElse. The
documentation says:

Compose two alternative STM actions (GHC only). If the first action
completes without retrying then it forms the result of the orElse.
Otherwise, if the first action retries, then the second action is
tried in its place. If both actions retry then the orElse as a whole
retries.

What is the definition of retrying in If the first action completes
without retrying then... -- does it mean only explicitly retrying via
the retry function, or does it include a retry caused by a write
conflict at commit time of the first action?

That is, if the first action could complete, but doesn't simply due to  
interference from another transaction, does orElse run the second  
action, or rerun the first?

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


Re: [Haskell-cafe] STM orElse semantics

2009-03-25 Thread Peter Robinson
 Compose two alternative STM actions (GHC only). If the first action
 completes without retrying then it forms the result of the orElse.
 Otherwise, if the first action retries, then the second action is
 tried in its place. If both actions retry then the orElse as a whole
 retries.

 What is the definition of retrying in If the first action completes
 without retrying then... -- does it mean only explicitly retrying via
 the retry function, or does it include a retry caused by a write
 conflict at commit time of the first action?

I'm quite sure orElse only concerns explicit retries, it wouldn't make
much sense otherwise.

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Xiao-Yong Jin
Jonathan Cast jonathancc...@fastmail.fm writes:

 On Tue, 2009-03-24 at 23:13 -0700, Donn Cave wrote:
 Quoth Duncan Coutts duncan.cou...@worc.ox.ac.uk:
 
  You must not do this. It breaks the semantics of the language.
 
  Other people have given practical reasons why you should not but a
  theoretical reason is that you've defined a non-continuous function.
  That is impossible in the normal semantics of pure functional languages.
  So you're breaking a promise which we rely on.
 
 Could you elaborate a little, in what sense are we (?) relying on it?
 
 I actually can't find any responses that make a case against it on a
 really practical level - I mean, it seems to be taken for granted that
 it will work as intended,

 It shouldn't be.

 Consider:

 loop = loop
 blam = error blam
 notReallyTry = unsafePerformIO . try . evaluate

 Now, normally, we have, for all x, y,

   x `seq` y `seq` x
 = y `seq` x

 But we clearly do *not* have this for x = blam, y = loop, since the
 equality isn't preserved by notReallyTry:

 notReallyTry $ blam `seq` loop `seq` blam = Left (ErrorCall blam)
 notReallyTry $ loop `seq` blam= loop

 Now, say a compiler sees the definition

 foo x y = x `seq` y `seq` x

 in one module, and then in a later one

 expectToBeTotal = notReallyTry $ foo blam loop

 ?  What happens if the compiler, while compiling foo, notices that x is
 going to be evaluated eventually anyway, and decides against forcing it
 before y?

 What if foo was written as

 foo (!x) (!y) = x

 ?  Which order are the evaluations performed in?  In a purely functional
 language, it doesn't matter; but all of a sudden with impure operations
 like notReallyTry popping up, it does.

Could you elaborate more about why this kind of breakage
wouldn't happen if 'try' is used in an IO monad as intended?

Thanks.
-- 
c/*__o/*
\ * (__
*/\  
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Lennart Augustsson
Some examples of what might happen:

If you have more than one possible exception in your code, you don't
know which one you will get.
It can vary between compilers, optimization levels, program runs, or
even evaluating the same expression within one program.

If you have code that have both an infinite loop and an exception you
don't know if you'll get the loop or the exception.

Breaking the deterministic behaviour can lead to strange consequences,
because the compiler relies on it.
For instance, the following code
   let x = someExpression
   print x
   print x
could print different values for x the two times you print it.
(This is somewhat unlikely, but could happen when evaluating in
parallel with ghc, because there is a small window where two threads
might start evaluating x and later update x with two different
values.)

  -- Lennart

On Wed, Mar 25, 2009 at 11:39 AM, Xiao-Yong Jin xj2...@columbia.edu wrote:
 Jonathan Cast jonathancc...@fastmail.fm writes:

 On Tue, 2009-03-24 at 23:13 -0700, Donn Cave wrote:
 Quoth Duncan Coutts duncan.cou...@worc.ox.ac.uk:

  You must not do this. It breaks the semantics of the language.
 
  Other people have given practical reasons why you should not but a
  theoretical reason is that you've defined a non-continuous function.
  That is impossible in the normal semantics of pure functional languages.
  So you're breaking a promise which we rely on.

 Could you elaborate a little, in what sense are we (?) relying on it?

 I actually can't find any responses that make a case against it on a
 really practical level - I mean, it seems to be taken for granted that
 it will work as intended,

 It shouldn't be.

 Consider:

     loop = loop
     blam = error blam
     notReallyTry = unsafePerformIO . try . evaluate

 Now, normally, we have, for all x, y,

       x `seq` y `seq` x
     = y `seq` x

 But we clearly do *not* have this for x = blam, y = loop, since the
 equality isn't preserved by notReallyTry:

     notReallyTry $ blam `seq` loop `seq` blam = Left (ErrorCall blam)
     notReallyTry $ loop `seq` blam            = loop

 Now, say a compiler sees the definition

     foo x y = x `seq` y `seq` x

 in one module, and then in a later one

     expectToBeTotal = notReallyTry $ foo blam loop

 ?  What happens if the compiler, while compiling foo, notices that x is
 going to be evaluated eventually anyway, and decides against forcing it
 before y?

 What if foo was written as

     foo (!x) (!y) = x

 ?  Which order are the evaluations performed in?  In a purely functional
 language, it doesn't matter; but all of a sudden with impure operations
 like notReallyTry popping up, it does.

 Could you elaborate more about why this kind of breakage
 wouldn't happen if 'try' is used in an IO monad as intended?

 Thanks.
 --
    c/*    __o/*
    \     * (__
    */\      
 ___
 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: Exception handling in numeric computations

2009-03-25 Thread John Lato
 Jake McArthur j...@pikewerks.com writes:

 Xiao-Yong Jin wrote:
 | The problem is that there will be many functions using such
 | a function to invert a matrix, making this inversion
 | function return Either/Maybe or packing it in a monad is
 | just a big headache.

 I disagree. If you try to take the inverse of a noninvertable matrix,
 this is an *error* in your code. Catching an error you created in pure
 code and patching it with chewing gum it is just a hack. A monadic
 approach (I'm putting Either/Maybe under the same umbrella for brevity)
 is the only solution that makes any sense to me, and I don't think it's
 ugly as you are making it out to be.


 Then, why is 'div' not of type 'a - a - ArithExceptionMonad a' ?
 Why does it throws this /ugly/ /error/ when it is applied to
 0?  Why is it not using some beautiful
 'ArithExceptinoMonad'?  Is 'Control.Exception' just pure
 /ugly/ and doesn't make any sense?


 | It is impractical to use method (a),
 | because not every function that uses 'invMat' knows how to
 | deal with 'invMat' not giving an answer.  So we need to use
 | method (b), to use monad to parse our matrix around.
 |
 |  invMat :: Matrix - NumericCancerMonad Matrix
 |
 | It hides the exceptional nature of numerical computations
 | very well, but it is cancer in the code.  Whenever any
 | function wants to use invMat, it is mutated.  This is just
 | madness.  You don't want to make all the code to be monadic
 | just because of singularities in numeric calculation.

 For functions that don't know or don't care about failure, just use fmap
 or one of its synonyms.

 ~    scalarMult 2 $ invMat x

 See? The scalarMult function is pure, as it should be. There is no
 madness here.

 Of course, 'scalarMult' is invulnerable and free of monad.
 But take a look at the following functions,

 f1 = scalarMult 2 . invMat
 f2 l r = l `multMat` invMat r
 ff :: Matrix - Matrix - YetAnotherBiggerMonad Matrix
 ff x y = do let ff' = f1 x + f2 y
             put . (addMat ff') . f1  get
             tell $ f2 ff'
             when (matrixWeDontLike (f1 ff') $
                  throwError MatrixWeDontLike
             return $ scalarMult (1/2) ff'

 Yes, I know, it's not really complicate to rewrite the above
 code.  But, what do I really gain from this rewrite?

Apologies if this discussion has moved on, but I wanted to comment on this.

You gain correctness.  Any functions that need to be rewritten in this
case should be rewritten anyway, because they're already wrong.  Your
function ff can fail for certain inputs.  This statement:
 | It is impractical to use method (a),
 | because not every function that uses 'invMat' knows how to
 | deal with 'invMat' not giving an answer.  So we need to use
 | method (b), to use monad to parse our matrix around.

is conceptually wrong.  What does it mean to multiply the inverse of a
non-invertible matrix by a scalar?  Obviously this is nonsensical.  If
a computation can fail (as this can), the type of the function should
reflect it.  The above functions

 f1 = scalarMult 2 . invMat
 f2 l r = l `multMat` invMat r

should be

f1 :: Matrix - Maybe Matrix
f1 = fmap (scalarMult 2) . invMat

f2 :: Matrix - Matrix - Maybe Matrix
f2 l r = fmap (multMat l) $ invMat r

Of course these could be written with Control.Applicative as well:

f1 m = scalarMult 2 $ invMat m
f2 l r = multMat l $ invMat r


 ff :: Matrix - Matrix - YetAnotherBiggerMonad Matrix
 ff x y = let ff' = f1 x + f2 y
 ...
 in scalarMult (1/2) ff'

(I think you may be missing an argument to f2 here.)

This computation can fail as well, if the constituent parts fail.  The
separate parts can be combined with applicative style:

ff :: Matrix - Matrix - Maybe Matrix
ff x y = scalarMult (1/2) $ ( (+) $ f1 x * f2 y)

Compare this to the same code using monadic Maybe:

ff :: Matrix - Matrix - Maybe Matrix
ff x y = do
  x' - f1 x
  y' - f2 y
  scalarMult (1/2) $ x' + y'

You gain clarity and brevity.  Both examples are shorter and easier to
understand because you aren't messing with all the plumbing of error
handling using exceptions, although I find the Applicative version
especially clear.  If you would like to keep track of why a
computation failed, then use Either instead of Maybe with the Left
carrying a reason for failure (e.g. NonInvertibleMatrix)

Finally, you gain safety.  When you use a function f1 :: Matrix -
Matrix, you can be assured that you will get an actual, meaningful
answer.  If you use a function f2 :: Matrix - Maybe Matrix, you know
that you may not get a meaningful answer, and it is simple to handle
at the appropriate level of your code.  I (and many other Haskell
users) find this to be conceptually cleaner than throwing dynamic
exceptions or using undefined.

Incidentally, this is one reason why many experienced Haskellers like
the applicative style.  It allows you to express your computations
without obtrusive error handling mixed in.  It's also more general
than monads, so can be applied in 

[Haskell-cafe] Re: generalized shuffle

2009-03-25 Thread Manlio Perillo

o...@okmij.org ha scritto:

Hello!


The reason is that in a project I need to extract random elements
from a list (and I need to extract a lot of them), and using normal
methods [1] seems to be rather inefficient.


Note that I have used an incorrect term, sorry.
What I need, in detail, is to:
Given a population of 100480507 elements, extract 17770 random samples, 
where each sample has a size between 1 and 480189.


Yes, it is again my Netflix Prize project; here I'm trying to write a 
program to generate the entire training data set using random data.



[1] by normal method I mean: extract a random number, in the range
 [0, n] (where n is the length of the sequence), and get the element
 indexed by that number.


BTW, have you tried to use Data.IntMap? That is, put the sequence into
an IntMap (each element being indexed by its index) and then extract
elements at random; IntMap seems to be quite efficient...



This should be ok if I need independent random choices from a 
population, but I need random samples, instead, sorry for the confusion.


Do you think that it is possible to further optimize your tree 
structure? Or to use IntMap, instead?



Cheers,
Oleg


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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Manlio Perillo

Heinrich Apfelmus ha scritto:

Manlio Perillo wrote:

Conal Elliott ha scritto:

Manlio,

We live in the age of participation -- of co-education.  Don't worry
about text-books.  Contribute to some wiki pages  blogs today that
share these smart techniques with others.


When I started learning Haskell (by my initiative), what I did was:

[steps 1) - 9), mostly internet tutorials ]


I think you'd have had a much easier time by starting with a proper book
right away, like Richard Bird's Introduction to Functional Programming
in Haskell, accompanied by Real World Haskell. 


Unfortunately, one year ago Real World Haskell was not here.
And note that I have no problems with basic functional programming concepts.
My problems are specific to Haskell.


You see, the reason that
books cost money is (should be) high quality content. :)




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


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Achim Schneider
Alberto G. Corona  agocor...@gmail.com wrote:

 However, reusability of source code and maintainability has never
 been taken seriously by haskell programmers, simply because there are
 no industrial projects in Haskell with dozens of people with
 different skills that come and go.

Now that's a claim.

In the sense that I don't do commercial haskell coding, but know what
maintainability is, anyway: I've maintained everything from utterly
atrocious to mindboggingly elegant java code for a living. I can tell
you with 110% confidence that maintainability is about composibility,
_on_every_level_: Not just on statement-level. Otherwise, I wouldn't
have cussed that much. Curiously enough, as soon as the code
didn't make you whince, it was easily maintainable. This is closely
related to Linus' observation that good [imperative] code is
data-structure centred, and Greenspun's Tenth Rule.


With Haskell, there's finally a language that makes large-scale changes
as easy as small-scale changes without having to resort to implement an
interpreter for a functional language. As the position of changes tends
to travel upwards in a bottom-up approach and small-scale changes are
easy to pull off (you already understand what you need to do since
otherwise you wouldn't have identified the need for a small-scale
change and continued to add onion layers), caring about editability on
function level just doesn't pay off.


That's why I don't care whether or not I have to re-write a whole
function to change it: If it's going to change, which isn't all that
likely, I can cope with renaming it and write another say 160
characters directly below it. Adding a proper quickcheck property (if
it didn't exist, yet, or the semantics changed) is usually more work:
You don't only need to get the preposition right, but also the test
case generator.


-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


___
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 Manlio Perillo

wren ng thornton ha scritto:

Manlio Perillo wrote:
[...]
Following directly from the Rule of Least Power, if you can get away 
with foreach then that's what you should use. Why? Because the less 
power the construct has, the fewer corner cases and generalizations a 
reader of the code needs to consider. Now, just because iterators exist 
does not mean that one should never use the more general tool. If you're 
fighting to break out of your chosen straitjacket, then chances are it's 
the wrong one to use in the first place; it'd be clearer to use more 
power and have less fighting.




 [...]


Note that, as I have already written, I agree with you.
And this is one of the reasons i like Haskell.

The main problem, here, is that:
- recursion and pattern matching are explained in every tutorial about
  functional programming and Haskell.

  This is the reason why I find them more natural.

- high level, Haskell specific, abstractions, are *not* explained in
  normal tutorials or books.
  The libraries where these concepts are implemented, are not well
  documented.
  Most of the documentation is in research papers, and a normal
  programmer don't want to read these papers.

  Only in the recent Real World Haskell, all these high level
  abstraction have been properly documented


Manlio
___
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 Claus Reinke


The beauty of functional programming is that there doesn't have
to be a conflict between those who prefer explicit and those
who prefer implicit recursion. Think of them as different views
on the same functions - just as with graphical visualizations,
pick the view best suited to your purpose and use equational
reasoning to transform one view into another, as needed.

Improving your experience in reasoning about code is going to
help at every level of abstraction, and since you've already
paid the price (using a pure language, to make reasoning easier)
you might as well avail yourself of the facilities;-)

While developing, I might prefer abstraction, as fewer details
mean that I can hold more of the problem in my head at any
point, increasing my chances of seeing all the way to a
solution; if optimizing, or when I haven't found the right
abstractions yet, I might have to resort to less abstract code
until I've sorted out those details or until GHC deals with
the more abstract forms as well as with the less abstract ones.

Fine, you say, but I'd never would have thought of abstract
views like splitAt as a state transformer. Okay, before this
thread, I might not have thought of using that, either. But
after this thread, I'd hope for it to become part of my
thinking about Haskell code. And the way I do that is by
taking the abstract code and unfold it (replacing instances
of left-hand sides with instances of right-hand sides of
definitions - the source links in the Haddock documentation
are very useful for that) until I get to some less abstract
code that I might have come up with.

That doesn't mean that I'd have had the insights to play the
derivation backwards, but by breaking the transformation from
less abstract to more abstract view into smaller steps, starting
from the abstract form that incorporates the additional insights
I was missing, I can increase my understanding of what is going
on, and my chances of noticing the opportunities next time. It
also confirms whether or not the two solutions really are the
same (as has been pointed out, that wasn't the case here).

Paraphrasing and tweaking Sjur Gjøstein Karevoll's remark
a little: clever Perl code is what you hope you understood in
the past, when you wrote it; clever Haskell code is what you
hope you'll understand in the future, when you'll write it yourself!-)

The derivation below is best followed by replaying it yourself
in your editor, but I hope you'll find it helpful anyway.

Claus

-- view transformation: reducing the level of abstraction
-- by turning implicit to explict recursion

takeList = evalState . mapM (State . splitAt)

-- unfold 'mapM'

takeList = evalState . sequence . map (State . splitAt)

-- unfold 'sequence'

takeList = evalState . foldr k (return []) . map (State . splitAt)
 where k m m' = do x-m; xs-m'; return (x:xs)
   foldr op n []= n
   foldr op n (h:t) = h `op` foldr op n t

-- specialize 'foldr' for the call paramenters 'k' and 'return []'

takeList = evalState . foldrkn . map (State . splitAt)
 where k m m' = do x-m; xs-m'; return (x:xs)
   foldrkn []= return []
   foldrkn (h:t) = h `k` foldrkn t

-- unfold 'k'

takeList = evalState . foldrkn . map (State . splitAt)
 where foldrkn []= return []
   foldrkn (h:t) = do x-h; xs-foldrkn t; return (x:xs)

-- foldr op n . map f = foldr (op.f) n

takeList = evalState . foldrkn
 where foldrkn []= return []
   foldrkn (h:t) = do x-State (splitAt h); xs-foldrkn t; return (x:xs)

-- unfold 'return' for 'State', eta-expand 'splitAt h'

takeList = evalState . foldrkn
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = do x-State (\s-splitAt h s); xs-foldrkn t; State 
(\s-(x:xs,s))

-- eta-expand body of 'takeList'

takeList ns xs = evalState (foldrkn ns) xs
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = do x-State (\s-splitAt h s); xs-foldrkn t; State 
(\s-(x:xs,s))

-- unfold the second '=' for 'State'

takeList ns xs = evalState (foldrkn ns) xs
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = do x-State (\s-splitAt h s)
  State (\s-let (xs,s') = runState (foldrkn t) s
 in runState (State (\s-(x:xs,s))) s')

-- runState . State = id

takeList ns xs = evalState (foldrkn ns) xs
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = do x-State (\s-splitAt h s)
  State (\s-let (xs,s') = runState (foldrkn t) s
 in (\s-(x:xs,s)) s')

-- beta-reduce

takeList ns xs = evalState (foldrkn ns) xs
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = do x-State (\s-splitAt h s)
  State (\s-let (xs,s') = runState (foldrkn t) s
 in (x:xs,s'))

-- unfold the remainign '=' for 'State'

takeList ns xs = evalState (foldrkn ns) xs
 where foldrkn []= State (\s-([],s))
   foldrkn (h:t) = State (\s-let (x,s') = 

Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Zachary Turner
On Tue, Mar 24, 2009 at 10:32 PM, wren ng thornton w...@freegeek.orgwrote:

 Both of these conclusions seem quite natural to me, even from before
 learning Haskell. It seems, therefore, that naturality is not the proper
 metric to discuss. It's oft overlooked, but the fact is that expressivity
 comes not from more formal power, but from _less_.

 * Natural language has a limited range of words and syntactic constructs,
 but gives the larger-enough building blocks to enable unconstrained
 communication; whereas a language with a unique word for every utterance
 (arguably simpler) is impossible to learn.


On the other hand, -certain- languages are more expressive than others.  As
an example, I personally find English far more expressive than both
Vietnamese and Japanese, yet English is far more complicated.  Japanese, for
example, has exactly 1 pronunciation for each alphabet letter.  Hence
you'll never find words in English like lead and lead, where the first
means to guide someone or something, or to give direction, and the second is
a chemical element.  Words that are spelled the same in Japanese are
pronounced the same 100% of the time.  Furthermore, I find that you are far
more limited in your choices of how to form ideas into sentences.  In
English there might be 20 different ways to phrase the exact same sentence
for use in a certain context, where the sentences end up being almost
identical with the exception of 1 or 2 words changed or shuffled around.  In
Japanese there would probably be far fewer.  In Vietnamese there's a similar
problem, in that there are not very many synonyms at all, and NO
conjugations.  It is complicated by the fact that it's a tonal language, but
on the other hand the tonality independent of the expressivity in my
experience.  Similar to Chinese, although I can't speak for the expressivity
of Chinese I would not be surprised at all if written Chinese was extremely
expressive, but spoken not so much.

Anyway the point of all this is that in English you have more freedom and
more power, and hence you use (abuse?) the syntax of the language to create
words, sentences, and phrases that express very powerful things.
Furthermore, they are things that almost all English speakers would be able
to grasp the full meaning of what you've said.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Haddock GSoC project

2009-03-25 Thread Isaac Dupree
I'm interested in being a GSoC student, and the Haddock-related tickets looked 
like a good place to start
http://hackage.haskell.org/trac/summer-of-code/ticket/1567
http://hackage.haskell.org/trac/summer-of-code/ticket/1568
http://hackage.haskell.org/trac/summer-of-code/ticket/1569

... haddock could use some love!  And I love documentation.

I think I'd start by hacking on some relatively easy Haddock tickets to find my 
way around the code and the hacking process.  Then it might be time to move 
into one of the bigger projects (I'm tempted to say #1567, Haddock: allow 
documentation to propagate between packages), depending on priorities; 
probably still working on some smaller but important Haddock tickets.  Then it 
depends how much time we have left in the summer, there's a lot that can be 
done!

- I've hacked on the GHC lexing/parsing code a bit, and I know darcs, haskell, 
etc., and I've been around watching on mailing-lists since before Haddock 2.x, 
so I feel like I have a fair amount of context with which to approach this 
project.

What do you think, is this a good project to look towards?  What's the next 
step... should I elaborate my proposal by looking at Haddock tickets and their 
priorities?  But I should have your feedback first; what do the mentors, or the 
Haskell community, want most to be improved about Haddock?

-Isaac

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


Re: [Haskell-cafe] Definition of tail recursive wrt Folds

2009-03-25 Thread Brent Yorgey
On Wed, Mar 25, 2009 at 05:54:17PM +1030, Mark Spezzano wrote:
 
 What, strictly speaking, is the definition of ”tail recursive” as opposed to
 just “recursive”?

A recursive function is tail recursive if the final result of the
recursive call is the final result of the function itself.  If the
result of the recursive call must be further processed (say, by adding
1 to it, or consing another element onto the beginning of it), it is
not tail recursive.

With that said, tail recursion is not that useful of a concept in a
lazy language like Haskell.  The important concept to know in Haskell
is 'guarded recursion', where any recursive calls occur within a data
constructor (such as foldr, where the recursive call to foldr occurs
as an argument to (:)).  This allows the result of the function to be
consumed lazily, since it can be evaluated up to the data constructor
and the recursive call delayed until needed.

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


Re: [Haskell-cafe] Haddock GSoC project

2009-03-25 Thread John Van Enk
Having cross-package links would be pure awesome.

On Wed, Mar 25, 2009 at 10:04 AM, Isaac Dupree 
m...@isaac.cedarswampstudios.org wrote:

 I'm interested in being a GSoC student, and the Haddock-related tickets
 looked
 like a good place to start
 http://hackage.haskell.org/trac/summer-of-code/ticket/1567
 http://hackage.haskell.org/trac/summer-of-code/ticket/1568
 http://hackage.haskell.org/trac/summer-of-code/ticket/1569

 ... haddock could use some love!  And I love documentation.

 I think I'd start by hacking on some relatively easy Haddock tickets to
 find my
 way around the code and the hacking process.  Then it might be time to move
 into one of the bigger projects (I'm tempted to say #1567, Haddock: allow
 documentation to propagate between packages), depending on priorities;
 probably still working on some smaller but important Haddock tickets.  Then
 it
 depends how much time we have left in the summer, there's a lot that can be
 done!

 - I've hacked on the GHC lexing/parsing code a bit, and I know darcs,
 haskell,
 etc., and I've been around watching on mailing-lists since before Haddock
 2.x,
 so I feel like I have a fair amount of context with which to approach this
 project.

 What do you think, is this a good project to look towards?  What's the next
 step... should I elaborate my proposal by looking at Haddock tickets and
 their
 priorities?  But I should have your feedback first; what do the mentors, or
 the
 Haskell community, want most to be improved about Haddock?

 -Isaac

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




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


[Haskell-cafe] a cabal package with both a library and executable programs

2009-03-25 Thread Manlio Perillo

Hi.

This example is taken from the Cabal documentation:

Name:TestPackage
...

Library
  Build-Depends:   HUnit
  Exposed-Modules: A, B, C

Executable program1
  Main-Is: Main.hs
  Hs-Source-Dirs:  prog1
  Other-Modules:   A, B

Executable program2
  Main-Is: Main.hs
  Hs-Source-Dirs:  prog2
  Other-Modules:   A, C, Utils


Here I see a small problem.
Why should I explicitly declare modules from the library that are used 
in the executables?


I would like to do, instead

...

Executable program1
  Main-Is: Main.hs
  Hs-Source-Dirs:  prog1
  build-depends:   TestPackage

Executable program2
  Main-Is: Main.hs
  Hs-Source-Dirs:  prog2
  build-depends:   TestPackag
  Other-Modules:   Utils


I tried this, but configuration fails, since Cabal does not find the 
TestPackage.

It is true that it does not yet exists, but we are going to build it!


Should I fill a feature request ticket, or this is how it is supposed to 
work?




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


[Haskell-cafe] Re: a cabal package with both a library and executable programs

2009-03-25 Thread Achim Schneider
Manlio Perillo manlio_peri...@libero.it wrote:

 Should I fill a feature request ticket, or this is how it is supposed
 to work?

I would like to be able to do that, too. I also don't want cabal to
recompile a thousand modules just for a demo program, and don't want to
see hackage being polluted by thousands of foo-lib and foo-bin packages
to circumvent the current behaviour, either.

That is, feel yourself seconded.

-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


[Haskell-cafe] Re: Exception handling in numeric computations

2009-03-25 Thread Xiao-Yong Jin
John Lato jwl...@gmail.com writes:

 Yes, I know, it's not really complicate to rewrite the above
 code.  But, what do I really gain from this rewrite?

 Apologies if this discussion has moved on, but I wanted to comment on this.


Thanks for elaborating it more.


 You gain correctness.  Any functions that need to be
rewritten in this
 case should be rewritten anyway, because they're already wrong.  Your
 function ff can fail for certain inputs.  This statement:
 | It is impractical to use method (a),
 | because not every function that uses 'invMat' knows how to
 | deal with 'invMat' not giving an answer.  So we need to use
 | method (b), to use monad to parse our matrix around.

 is conceptually wrong.  What does it mean to multiply the inverse of a
 non-invertible matrix by a scalar?  Obviously this is nonsensical.  If
 a computation can fail (as this can), the type of the function should
 reflect it.  The above functions

 f1 = scalarMult 2 . invMat
 f2 l r = l `multMat` invMat r

 should be

 f1 :: Matrix - Maybe Matrix
 f1 = fmap (scalarMult 2) . invMat

 f2 :: Matrix - Matrix - Maybe Matrix
 f2 l r = fmap (multMat l) $ invMat r

 Of course these could be written with Control.Applicative as well:

 f1 m = scalarMult 2 $ invMat m
 f2 l r = multMat l $ invMat r


 ff :: Matrix - Matrix - YetAnotherBiggerMonad Matrix
 ff x y = let ff' = f1 x + f2 y
  ...
  in scalarMult (1/2) ff'

 (I think you may be missing an argument to f2 here.)

 This computation can fail as well, if the constituent parts fail.  The
 separate parts can be combined with applicative style:

 ff :: Matrix - Matrix - Maybe Matrix
 ff x y = scalarMult (1/2) $ ( (+) $ f1 x * f2 y)

 Compare this to the same code using monadic Maybe:

 ff :: Matrix - Matrix - Maybe Matrix
 ff x y = do
   x' - f1 x
   y' - f2 y
   scalarMult (1/2) $ x' + y'

 You gain clarity and brevity.  Both examples are shorter and easier to
 understand because you aren't messing with all the plumbing of error
 handling using exceptions, although I find the Applicative version
 especially clear.  If you would like to keep track of why a
 computation failed, then use Either instead of Maybe with the Left
 carrying a reason for failure (e.g. NonInvertibleMatrix)

 Finally, you gain safety.  When you use a function f1 :: Matrix -
 Matrix, you can be assured that you will get an actual, meaningful
 answer.  If you use a function f2 :: Matrix - Maybe Matrix, you know
 that you may not get a meaningful answer, and it is simple to handle
 at the appropriate level of your code.  I (and many other Haskell
 users) find this to be conceptually cleaner than throwing dynamic
 exceptions or using undefined.

 Incidentally, this is one reason why many experienced Haskellers like
 the applicative style.  It allows you to express your computations
 without obtrusive error handling mixed in.  It's also more general
 than monads, so can be applied in more instances.

 div (and other non-total functions in the Prelude like head), are also
 frequently considered ugly hacks.  Just because we're stuck with
 something from H98 doesn't mean that it's necessarily good or elegant
 (the fail monad method and Functor not being a superclass of Monad
 come to mind).  In some ways FP has moved on since Haskell was
 formalized.

 There is an alternative approach that I believe was suggested by
 somebody else on the list:

 newtype InvMatrix = Invert {unWrap :: Matrix}

 then you can do
 invertMatrix :: Matrix - Maybe InvMatrix
 invertMatrix = fmap Invert . invMat

 If you put these in a separate module and export InvMatrix, unwrap,
 and invertMatrix, but not Invert, then the only way to create an
 InvMatrix is with invertMatrix, so any data of type InvMatrix is
 guaranteed to be invertible (and inverted from what you used to create
 it).

 Then your ff function becomes:

 ff :: InvMatrix - InvMatrix - Matrix

 the final value of the function could be InvMatrix if you can prove
 that it's invertible after your operations (although to be efficient,
 this would require exporting the Invert constructor and a proof from
 the programmer).  This keeps ff pure; you don't even have to deal with
 Maybe (although there are other ramifications to doing this that
 should be considered).

 John




-- 
c/*__o/*
\ * (__
*/\  
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Achim Schneider
Manlio Perillo manlio_peri...@libero.it wrote:

 The main problem, here, is that:
 - recursion and pattern matching are explained in every tutorial about
functional programming and Haskell.
 
This is the reason why I find them more natural.
 
Well, you're going to have a hard time writing a BASIC tutorial without
mentioning GOTO. While surely it has to be there, for the sake of
completeness of fundamentals, I completely agree that...

 - high level, Haskell specific, abstractions, are *not* explained in
normal tutorials or books.
The libraries where these concepts are implemented, are not well
documented.
Most of the documentation is in research papers, and a normal
programmer don't want to read these papers.
 
Only in the recent Real World Haskell, all these high level
abstraction have been properly documented

...GOTO alone doesn't teach you how to write a loop, trust me, I was
stuck there for a good while, eons ago.

The prelude, as well as commonly used functions that should be in
there, utterly lack accompanying documentation. There should be no
function without a usage, as in foldl/sum/product, and no usage without
explanation why foldl is chosen over foldl' and foldr. Think of a
Preludopedia, accompanying the Typeclassopedia: Documentation where you
don't have to snatch understanding out of assem^H^H^H^H^H^H code
written using primitive recursion, to make it a bit easier to see the
wood despite of all those trees.

PS: Shouldn't zipWith be defined in terms of zip, uncurry and map
instead of 
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _  _  = []
?

-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


[Haskell-cafe] Re: Haddock GSoC project

2009-03-25 Thread Isaac Dupree
Simon Marlow wrote:
 Obviously I think these tickets are important, since I wrote them :-)  In
 terms of priority, I think #1567 is at the top: not having this harms our
 ability to reorganise and abstract things, it puts an arbitrary barrier
 between packages.  It's possible my perspective is slightly skewed though,
 since most of the packages that are affected by this are in GHC's core
 package collection.

still,
-reorganization happens in others' packages too, and we want to encourage 
this!
-everyone uses GHC's core packages and complains when the documentation is 
broken (and unfixable!) :-)

but sure, we should find out if other people have higher priorities elsewhere. 
(cafe citizens and hackers, tell us what you think!)

 #1568 is just refactoring, but it's a high priority: we need to get this
 code out of GHC and back into Haddock.  This is important for Haddock's
 long term future and general maintainability, though it won't have any
 visible effect on the way Haddock works.

yes, I agree, things will keep being a little unpleasant until we do this.  My 
intuition says that with 2-3 months I should have time to do this refactoring 
too, but then, I haven't actually spent a week figuring out just how difficult 
it 
is :-).  Probably needs some refactoring the data-types that GHC emits 
comments as, and then possibly-more-complicated having Haddock parse and 
structure the Haddock-syntax within the comments (and as it relates to the 
actual code!)

 The index page really isn't working right now, since we added the
 search-box functionality it has become unusable for the GHC library docs
 (small libraries are ok).  Thank goodness we have Hoogle and Hayoo.  We
 should really just revert to the old A-Z links, I'm not sure if there's a
 Haddock ticket for this.

maybe http://trac.haskell.org/haddock/ticket/70 is related?

 There's lot of other stuff that could be done.  For instance I'd really
 like someone with some CSS expertise to have another go at Haddock's HTML
 layout.

I've done some manual HTML/CSS on my own website (W3C validated!)... don't 
know if it comes anywhere near expertise though :-)

One random haddock problem I remember bothering me recently is: no view 
source link on each instance in the list of instances for a data-type (so I 
clicked a nearby view source and scrolled to find the instance source, which 
was in the same module)

-Isaac

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


[Haskell-cafe] Re: Haddock GSoC project

2009-03-25 Thread Simon Marlow

Isaac Dupree wrote:
I'm interested in being a GSoC student, and the Haddock-related tickets looked 
like a good place to start

http://hackage.haskell.org/trac/summer-of-code/ticket/1567
http://hackage.haskell.org/trac/summer-of-code/ticket/1568
http://hackage.haskell.org/trac/summer-of-code/ticket/1569

 haddock could use some love!  And I love documentation.

I think I'd start by hacking on some relatively easy Haddock tickets to find my 
way around the code and the hacking process.  Then it might be time to move 
into one of the bigger projects (I'm tempted to say #1567, Haddock: allow 
documentation to propagate between packages), depending on priorities; 
probably still working on some smaller but important Haddock tickets.  Then it 
depends how much time we have left in the summer, there's a lot that can be 
done!


- I've hacked on the GHC lexing/parsing code a bit, and I know darcs, haskell, 
etc., and I've been around watching on mailing-lists since before Haddock 2.x, 
so I feel like I have a fair amount of context with which to approach this 
project.


What do you think, is this a good project to look towards?  What's the next 
step... should I elaborate my proposal by looking at Haddock tickets and their 
priorities?  But I should have your feedback first; what do the mentors, or the 
Haskell community, want most to be improved about Haddock?


Obviously I think these tickets are important, since I wrote them :-)  In 
terms of priority, I think #1567 is at the top: not having this harms our 
ability to reorganise and abstract things, it puts an arbitrary barrier 
between packages.  It's possible my perspective is slightly skewed though, 
since most of the packages that are affected by this are in GHC's core 
package collection.


#1568 is just refactoring, but it's a high priority: we need to get this 
code out of GHC and back into Haddock.  This is important for Haddock's 
long term future and general maintainability, though it won't have any 
visible effect on the way Haddock works.


The index page really isn't working right now, since we added the 
search-box functionality it has become unusable for the GHC library docs 
(small libraries are ok).  Thank goodness we have Hoogle and Hayoo.  We 
should really just revert to the old A-Z links, I'm not sure if there's a 
Haddock ticket for this.


There's lot of other stuff that could be done.  For instance I'd really 
like someone with some CSS expertise to have another go at Haddock's HTML 
layout.


Cheers,
Simon

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


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Simon Marlow

Dan Piponi wrote:

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.


But it only works out nicely because the ordering of the components of the 
pair returned by splitAt matches the ordering that the state monad expects 
(and I can never remember which way around they are in Control.Monad.State).


Try doing it with mapAccumL, which is arguably the right abstraction, but 
has the components the other way around.


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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 07:39 -0400, Xiao-Yong Jin wrote:
 Jonathan Cast jonathancc...@fastmail.fm writes:
 
  On Tue, 2009-03-24 at 23:13 -0700, Donn Cave wrote:
  Quoth Duncan Coutts duncan.cou...@worc.ox.ac.uk:
  
   You must not do this. It breaks the semantics of the language.
  
   Other people have given practical reasons why you should not but a
   theoretical reason is that you've defined a non-continuous function.
   That is impossible in the normal semantics of pure functional languages.
   So you're breaking a promise which we rely on.
  
  Could you elaborate a little, in what sense are we (?) relying on it?
  
  I actually can't find any responses that make a case against it on a
  really practical level - I mean, it seems to be taken for granted that
  it will work as intended,
 
  It shouldn't be.
 
  Consider:
 
  loop = loop
  blam = error blam
  notReallyTry = unsafePerformIO . try . evaluate
 
  Now, normally, we have, for all x, y,
 
x `seq` y `seq` x
  = y `seq` x
 
  But we clearly do *not* have this for x = blam, y = loop, since the
  equality isn't preserved by notReallyTry:
 
  notReallyTry $ blam `seq` loop `seq` blam = Left (ErrorCall blam)
  notReallyTry $ loop `seq` blam= loop
 
  Now, say a compiler sees the definition
 
  foo x y = x `seq` y `seq` x
 
  in one module, and then in a later one
 
  expectToBeTotal = notReallyTry $ foo blam loop
 
  ?  What happens if the compiler, while compiling foo, notices that x is
  going to be evaluated eventually anyway, and decides against forcing it
  before y?
 
  What if foo was written as
 
  foo (!x) (!y) = x
 
  ?  Which order are the evaluations performed in?  In a purely functional
  language, it doesn't matter; but all of a sudden with impure operations
  like notReallyTry popping up, it does.
 
 Could you elaborate more about why this kind of breakage
 wouldn't happen if 'try' is used in an IO monad as intended?

It would.  But it would happen in IO, which is allowed to be
non-deterministic.  Pure Haskell is not allowed to be non-deterministic.

jcc


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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 15:09 +, Simon Marlow wrote:
 the ordering that the state monad expects 
 (and I can never remember which way around they are in Control.Monad.State).

Really?  I found it obvious once I figured out it how simple it made
(=).  With the order from Control.Monad.State (with constructors
ignored):

a = f = \ s - case s a of
   (x, s') - f x s'

Reversing the order of the components of the result gives you

a = f = \ s - case s a of
(s', x) - f x s'

which just looks weird.

 Try doing it with mapAccumL, which is arguably the right abstraction,
 but 
 has the components the other way around.

Define

swap (a, b) = (b, a)

You'll never worry about the order of components of a pair again.  This
function is as indispensable as flip.

jcc


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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Simon Marlow

Jonathan Cast wrote:

On Wed, 2009-03-25 at 15:09 +, Simon Marlow wrote:
the ordering that the state monad expects 
(and I can never remember which way around they are in Control.Monad.State).


Really?  I found it obvious once I figured out it how simple it made
(=).  With the order from Control.Monad.State (with constructors
ignored):

a = f = \ s - case s a of
   (x, s') - f x s'

Reversing the order of the components of the result gives you

a = f = \ s - case s a of
(s', x) - f x s'

which just looks weird.


It might look weird to you, but that's the way that GHC's IO and ST monads 
do it.  It looks perfectly natural to me!  (and you have the a and s the 
wrong way around in 'case s a', BTW).



Try doing it with mapAccumL, which is arguably the right abstraction,
but 
has the components the other way around.


Define

swap (a, b) = (b, a)


ew, that's far too crude.  I think you mean

  swap = uncurry $ flip (,)

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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Peter Verswyvelen
On Wed, Mar 25, 2009 at 4:09 PM, Simon Marlow marlo...@gmail.com wrote:

 But it only works out nicely because the ordering of the components of the
 pair returned by splitAt matches the ordering that the state monad expects
 (and I can never remember which way around they are in Control.Monad.State).


Now you mention this, I often had to write a little function

swap :: (a,b) - (b,a)

It seems many other authors have done the same in their own modules. Maybe
this should be part of the Prelude?




 Try doing it with mapAccumL, which is arguably the right abstraction, but
 has the components the other way around.

 Cheers,
Simon

 ___
 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: about Haskell code written to be too smart

2009-03-25 Thread Jake McArthur

Simon Marlow wrote:

Jonathan Cast wrote:

Define

swap (a, b) = (b, a)


ew, that's far too crude.  I think you mean

  swap = uncurry $ flip (,)


I think I would prefer something that mirrors flip more closely:

swap :: ((a,b) - c) - (b,a) - c
swap = uncurry . flip . curry

- Jake
___
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 Gregg Reynolds
2009/3/25 Zachary Turner divisorthe...@gmail.com:

 On the other hand, -certain- languages are more expressive than others.  As
 an example, I personally find English far more expressive than both
 Vietnamese and Japanese, yet English is far more complicated.  Japanese, for

Way off topic, but for what it's worth, you can take it as axiomatic
that all natural languages are equally expressive, qua languages.
They're also equally easy/hard overall.  The areas of difficulty are
just in different places.  Japanese grammar is extraordinarily simple,
but achieving mastery of the spoken language *in Japanese society* is
next to impossible, because usage reflects social constructions.  As
you no doubt know, what is not said is sometimes just as expressive as
what is said in Japanese; very maddening to a logorrheic American,
just as an English speaker's need to explicitly articulate
*everything* is no doubt annoying to Japanese.

Regarding spelling and phonology: the idea that one symbol, one
sound is somehow optimal is the Myth That Will Not Die.  None other
than Chomsky himself argued that English orthography is near-optimal
for the English language.  All writing systems are designed to serve
speakers of the language, and many languages are poorly modeled by a
one symbol, one sound system.

I'm not sure there's a lesson there for formal language designers and
programmers, except maybe that the expressiveness (elegance?) of a
text usually depends to a great extent on the writer more than the
language.

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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Robin Green
On Wed, 25 Mar 2009 08:25:40 -0700
Jonathan Cast jonathancc...@fastmail.fm wrote:

 Define
 
 swap (a, b) = (b, a)

By the way, if you want to be too smart, there's a generalised
version of swap in Control.Category.Braided in the category-extras
package.

That might be a bit overkill though.
-- 
Robin
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 03:01 +, Robin Green wrote:
 On Wed, 25 Mar 2009 08:25:40 -0700
 Jonathan Cast jonathancc...@fastmail.fm wrote:
 
  Define
  
  swap (a, b) = (b, a)
 
 By the way, if you want to be too smart, there's a generalised
 version of swap in Control.Category.Braided in the category-extras
 package.

Thanks, I'll check it out.

 That might be a bit overkill though.

What is this word `overkill' you use?

jcc


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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Donn Cave
Quoth Lennart Augustsson lenn...@augustsson.net:

 Some examples of what might happen:

OK, these are interesting phenomena.  From a practical point of view,
though, I could see someone weighing the potential costs and benefits
of a exception handler outside IO like this, and these effects might
not even carry all that much weight.  Does that make sense, or is the
problem really more dire than I understand?

I mean, it isn't the first time I've seen this explained in terms of
predictability in a case where there are two possible exceptions, so
I have to take for granted that this is a compelling argument to some,
but it is evidently a matter of perspective.

Donn

 If you have more than one possible exception in your code, you don't
 know which one you will get.
 It can vary between compilers, optimization levels, program runs, or
 even evaluating the same expression within one program.

 If you have code that have both an infinite loop and an exception you
 don't know if you'll get the loop or the exception.

 Breaking the deterministic behaviour can lead to strange consequences,
 because the compiler relies on it.
 For instance, the following code
let x = someExpression
print x
print x
 could print different values for x the two times you print it.
 (This is somewhat unlikely, but could happen when evaluating in
 parallel with ghc, because there is a small window where two threads
 might start evaluating x and later update x with two different
 values.)

   -- Lennart

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 09:15 -0700, Donn Cave wrote:
 Quoth Lennart Augustsson lenn...@augustsson.net:
 
  Some examples of what might happen:
 
 OK, these are interesting phenomena.  From a practical point of view,
 though, I could see someone weighing the potential costs and benefits
 of a exception handler outside IO like this, and these effects might
 not even carry all that much weight.

Well, sure.  From a purely `practical' point of view, I don't know why
you would even use a purely functional language (as opposed to trying to
minimize side effects in an impure language).  But if you're not
concerned about purity, or ease of equational reasoning, or accuracy of
a wide range of compiler transformations/optimizations/because it makes
the generated code pretty to sort the formal parameters by name before
forcing them-implementation decisions, then please do not use Haskell.
There are many other languages that are suitable for what you want to
do, and it would be a courtesy to those of us who *do* use Haskell
because it is purely functional, not to have to explicitly exclude your
library from our picture of the language's capabilities.

jcc


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


Re: [Haskell-cafe] Re: Learning Haskell

2009-03-25 Thread Lanny Ripple
Learning the syntax, a day or two.
Learning major idioms (many of which are encapsulated in modules),
ongoing (it's been about two years of off and on).

Sadly I can't use it for my $work language.  If I could then the
time available for learning haskell and paying the mortgage would
not be disjoint.  On the other hand I'm using what I'm learning at
work and it's making for better code.  (And scaring some of my
coworkers doing my code-reviews. :)

  -ljr

Jon Fairbairn wrote:
 Tom.Amundsen tomamund...@gmail.com writes:
 
 How long did it take you to become proficient in Haskell?
 
 Something more than twenty years.
 
 By that, I mean - how long until you were just as
 comfortable with Haskell as you were with your strongest
 language at that time?
 
 Oh, Haskell was my strongest language during all that time! ;-)
 
 If I have a serious point, it's that going from writing
 imperative programmes to writing properly functional ones
 takes a lot longer than it takes to learn every facet of the
 language.
 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Grouping - Map / Reduce

2009-03-25 Thread Gü?nther Schmidt

Dear Luke,

I'm at a loss trying to figure out what is happening here, I'd sincerely 
appreciate it if you could find the time to give me more clues on this, 
I'm deeply impressed. If I think that what is happening *is* happening 
that would mean that this is a way to group in almost constant space.


Günther

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Lennart Augustsson
If you think non-determinstic programs are acceptable, then you can
use unsafePerformIO this way.
But future versions of compilers may make them even more
unpredictable, so beware.

I think that if the exception handler does not look at exactly what
exception was thrown, then the program will just vary in definedness
(i.e., comparable in the domain approximation ordering).
Many people consider this acceptable.

  -- Lennart

On Wed, Mar 25, 2009 at 4:15 PM, Donn Cave d...@avvanta.com wrote:
 Quoth Lennart Augustsson lenn...@augustsson.net:

 Some examples of what might happen:

 OK, these are interesting phenomena.  From a practical point of view,
 though, I could see someone weighing the potential costs and benefits
 of a exception handler outside IO like this, and these effects might
 not even carry all that much weight.  Does that make sense, or is the
 problem really more dire than I understand?

 I mean, it isn't the first time I've seen this explained in terms of
 predictability in a case where there are two possible exceptions, so
 I have to take for granted that this is a compelling argument to some,
 but it is evidently a matter of perspective.

        Donn

 If you have more than one possible exception in your code, you don't
 know which one you will get.
 It can vary between compilers, optimization levels, program runs, or
 even evaluating the same expression within one program.

 If you have code that have both an infinite loop and an exception you
 don't know if you'll get the loop or the exception.

 Breaking the deterministic behaviour can lead to strange consequences,
 because the compiler relies on it.
 For instance, the following code
    let x = someExpression
    print x
    print x
 could print different values for x the two times you print it.
 (This is somewhat unlikely, but could happen when evaluating in
 parallel with ghc, because there is a small window where two threads
 might start evaluating x and later update x with two different
 values.)

   -- Lennart

 ___
 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: about Haskell code written to be too smart

2009-03-25 Thread David Menendez
On Wed, Mar 25, 2009 at 11:32 AM, Simon Marlow marlo...@gmail.com wrote:
 Jonathan Cast wrote:

 Define

    swap (a, b) = (b, a)

 ew, that's far too crude.  I think you mean

  swap = uncurry $ flip (,)

On the theme of using monads where you might not expect,

swap = liftA2 (,) snd fst

-- 
Dave Menendez d...@zednenem.com
http://www.eyrie.org/~zednenem/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 15:32 +, Simon Marlow wrote:
 Jonathan Cast wrote:
  On Wed, 2009-03-25 at 15:09 +, Simon Marlow wrote:
  the ordering that the state monad expects 
  (and I can never remember which way around they are in 
  Control.Monad.State).
  
  Really?  I found it obvious once I figured out it how simple it made
  (=).  With the order from Control.Monad.State (with constructors
  ignored):
  
  a = f = \ s - case s a of
 (x, s') - f x s'
  
  Reversing the order of the components of the result gives you
  
  a = f = \ s - case s a of
  (s', x) - f x s'
  
  which just looks weird.
 
 It might look weird to you, but that's the way that GHC's IO and ST monads 
 do it.  It looks perfectly natural to me!

Right.  Consider this an argument for fixing IO/ST(/STM?) to conform to
the self-evidently correct ordering of Control.Monad.State :)

 (and you have the a and s the 
 wrong way around in 'case s a', BTW).

Um, yes.  /Mea culpa/.

  Try doing it with mapAccumL, which is arguably the right abstraction,
  but 
  has the components the other way around.
  
  Define
  
  swap (a, b) = (b, a)
 
 ew, that's far too crude.  I think you mean
 
swap = uncurry $ flip (,)

Ah, yes.

jcc


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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Donn Cave
Quoth Jonathan Cast jonathancc...@fastmail.fm:
 On Wed, 2009-03-25 at 09:15 -0700, Donn Cave wrote:

 OK, these are interesting phenomena.  From a practical point of view,
 though, I could see someone weighing the potential costs and benefits
 of a exception handler outside IO like this, and these effects might
 not even carry all that much weight.

 Well, sure.  From a purely `practical' point of view, I don't know why
 you would even use a purely functional language (as opposed to trying to
 minimize side effects in an impure language).  But if you're not
 concerned about purity, or ease of equational reasoning, or accuracy of
 a wide range of compiler transformations/optimizations/because it makes
 the generated code pretty to sort the formal parameters by name before
 forcing them-implementation decisions, then please do not use Haskell.
 There are many other languages that are suitable for what you want to
 do, and it would be a courtesy to those of us who *do* use Haskell
 because it is purely functional, not to have to explicitly exclude your
 library from our picture of the language's capabilities.

Concerned about purity, ease of equational reasoning, etc.?  Sure ...
but I guess hoping we can agree on practical reasons for interest in
these things, as opposed to, or at least in addition to, their esthetic
or religious appeal.  I'm guessing you would likewise, if only because
a solely esthetic appeal is difficult angle to pursue because people's
esthetic sensibilities aren't guaranteed to line up very well.  And in
fact the way I read the responses so far in this thread, the range of
attitudes towards the matter seems pretty wide to me, among people whose
views I respect.

So I thought it would be interesting to explore statements like you
must not do this, and pure Haskell is not allowed to be
non-deterministic, in terms of practical effects.  No one would
make a statement like that and not hope to be challenged on it?

Donn

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


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Jake McArthur

Simon Marlow wrote:
 Jonathan Cast wrote:
 Define

 swap (a, b) = (b, a)

 ew, that's far too crude.  I think you mean

   swap = uncurry $ flip (,)

I think I would prefer something that mirrors flip more closely:

swap :: ((a,b) - c) - (b,a) - c
swap = uncurry . flip . curry

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Benja Fallenstein
Hi Duncan and all,

On Wed, Mar 25, 2009 at 3:52 AM, Duncan Coutts
duncan.cou...@worc.ox.ac.uk wrote:
 On Mon, 2009-03-23 at 08:11 -0400, Xiao-Yong Jin wrote:
  tryArith :: a - Either ArithException a
  tryArith = unsafePerformIO . try . evaluate

 You must not do this. It breaks the semantics of the language.

 Other people have given practical reasons why you should not but a
 theoretical reason is that you've defined a non-continuous function.
 That is impossible in the normal semantics of pure functional languages.
 So you're breaking a promise which we rely on.
...
 Of course your tryArith only tests for certain kinds of _|_ value, but
 in principle the problem is the same.

That's not *quite* how the semantics of Haskell exceptions are
defined, actually, unless I'm misunderstanding something or the
thinking about it has changed since the original paper on the topic:

Simon Peyton Jones, Alastair Reid, Tony Hoare, Simon Marlow, Fergus
Henderson: A semantics for imprecise exceptions. SIGPLAN Conference
on Programming Language Design and Implementation, 1999.

http://www.haskell.org/~simonmar/papers/except.ps.gz

In the semantics given by that paper, the value of an expression of type Int is

(a) an actual number, or
(b) a set of exceptions that the expression might raise when evaluated, or
(c) bottom, which means: when evaluated, the expression may not
terminate, or may terminate and raise some arbitrary exception.

(The semantic ordering is: everything is larger than bottom; a set of
expressions A is larger than a set of expressions B iff A is a proper
subset of B; numbers are not comparable to sets.)

tryArith is still noncontinuous, though, and nondeterministic, too. Consider:

divzero = 1/0
overflow = 2**1000
loop = loop - 1

* What is (tryArith (divzero + overflow))? The denotational value of
(divzero + overflow) is the set {DivideByZero, Overflow}, so tryArith
can return either (Left DivideByZero) or (Left Overflow) --
nondeterminism.

* What is (tryArith (overflow + loop))? The denotational value of
(overflow + loop) is bottom, so tryArith can theoretically return any
arithmetic exception, or propagate any non-arithmetic exception, or
loop forever. In practice, of course, it will either return (Left
Overflow), or loop forever, or error out if the compiler notices the
loop. However, this still means that it *may* return (Left Overflow)
even though the semantical value of (overflow + loop) is bottom, which
means that the function is not monotone and thus not continuous.

All the best,
- Benja
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Learning Haskell

2009-03-25 Thread jean-christophe mincke
I discovered Haskell about a year and half ago, along with F#.

Beginning with both languages was relatively easy but I already had
experience of FP in lisp and scheme.
And some years ago I took a course in FP (learning CAML which F# is closely
based on).

My study of haskell went smooth up to the point I came across monads (that
is, the honey moon did not last very long).

I must admit that it took me about 3 months of (intermittent) work to first
understand monads and then to be able to use them correctly.

What also helped me a lot was the parallel study of both F# and Haskell.
Indeed, I often tried to understand how some constructs in Haskell could or
could not be implemented in F# (i.e type classes).
I.e. that really helped me understand the higher order types in Haskell.

After the monad episode, I found myself quite interested in FRP and all its
lot of new concepts (applicative functors, arrows, ...).
I tried to read as much as I could on the subject and finally decided that
if I wanted to really understand all this, one of the best solution was
trying to implement a small FRP myself. That's what I did in F#.
After a few weeks, I think I now understand arrows, application functors and
other curiosities.

I think that working on more or less real problems (or on real applications)
is definitively the best way to learn such languages. It is not a matter of
writing thousands of lines of code but rather to pick up a specific
aspect/feature of a language and  to apply it to a concrete example, just to
understand what problem it is supposed to solve and how well it solves it.

Although I am not making a living on Haskell/F# (specially in my country),
it gave me quite a lot of good idea in my day to day work both in terms of
development techniques and in terms of analysis/specifications.

So learning Haskell was not the easiest thing I did in my life but so far,
it does pay off.

J-C



On Wed, Mar 25, 2009 at 5:28 PM, Lanny Ripple la...@cisco.com wrote:

 Learning the syntax, a day or two.
 Learning major idioms (many of which are encapsulated in modules),
 ongoing (it's been about two years of off and on).

 Sadly I can't use it for my $work language.  If I could then the
 time available for learning haskell and paying the mortgage would
 not be disjoint.  On the other hand I'm using what I'm learning at
 work and it's making for better code.  (And scaring some of my
 coworkers doing my code-reviews. :)

  -ljr

 Jon Fairbairn wrote:
  Tom.Amundsen tomamund...@gmail.com writes:
 
  How long did it take you to become proficient in Haskell?
 
  Something more than twenty years.
 
  By that, I mean - how long until you were just as
  comfortable with Haskell as you were with your strongest
  language at that time?
 
  Oh, Haskell was my strongest language during all that time! ;-)
 
  If I have a serious point, it's that going from writing
  imperative programmes to writing properly functional ones
  takes a lot longer than it takes to learn every facet of the
  language.
 
 ___
 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] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 10:00 -0700, Donn Cave wrote:
 Quoth Jonathan Cast jonathancc...@fastmail.fm:
  On Wed, 2009-03-25 at 09:15 -0700, Donn Cave wrote:
 
  OK, these are interesting phenomena.  From a practical point of view,
  though, I could see someone weighing the potential costs and benefits
  of a exception handler outside IO like this, and these effects might
  not even carry all that much weight.
 
  Well, sure.  From a purely `practical' point of view, I don't know why
  you would even use a purely functional language (as opposed to trying to
  minimize side effects in an impure language).  But if you're not
  concerned about purity, or ease of equational reasoning, or accuracy of
  a wide range of compiler transformations/optimizations/because it makes
  the generated code pretty to sort the formal parameters by name before
  forcing them-implementation decisions, then please do not use Haskell.
  There are many other languages that are suitable for what you want to
  do, and it would be a courtesy to those of us who *do* use Haskell
  because it is purely functional, not to have to explicitly exclude your
  library from our picture of the language's capabilities.
 
 Concerned about purity, ease of equational reasoning, etc.?  Sure ...
 but I guess hoping we can agree on practical reasons for interest in
 these things, as opposed to, or at least in addition to, their esthetic
 or religious appeal.  I'm guessing you would likewise,

Nope.  You must not have been following my positions in previous
discussions.  I am committed to functional purity for its own sake (just
as I am committed to software development for its own sake; don't you
*dare* suggest using Global Script!)

 if only because
 a solely esthetic appeal is difficult angle to pursue because people's
 esthetic sensibilities aren't guaranteed to line up very well.  And in
 fact the way I read the responses so far in this thread, the range of
 attitudes towards the matter seems pretty wide to me, among people whose
 views I respect.

 So I thought it would be interesting to explore statements like you
 must not do this, and pure Haskell is not allowed to be
 non-deterministic, in terms of practical effects.  No one would
 make a statement like that and not hope to be challenged on it?

What?  Challenged by people who think Haskell should not be a purely
functional language?  I mean, that's kind of what it is.  Again, if you
don't want to use a purely functional language, there are *lots* of
impure languages out there.  There's no need to turn Haskell into one of
them.

jcc


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


[Haskell-cafe] central european functional programming school

2009-03-25 Thread Roman Cheplyaka
Hi,

I'm interested in 3rd central european functional programming school[1].

Maybe some haskellers attended previous CEFPs and want to share (or
already shared) some experience?

Who also is going to attend or participate in this year's CEFP?

  1. http://plcportal.inf.elte.hu/en/tfp_cefp_2009/Pages/default.aspx
-- 
Roman I. Cheplyaka :: http://ro-che.info/
Don't let school get in the way of your education. - Mark Twain
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Whats the use of !

2009-03-25 Thread Harsh Verma

I have seen ! added in front of many values, is it related to strict 
evaluation? Please elaborate on it.
TIA,
gimli

_
Windows Live Messenger. Multitasking at its finest.
http://www.microsoft.com/india/windows/windowslive/messenger.aspx___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Whats the use of !

2009-03-25 Thread Neil Mitchell
Hi

A quick Hoogle for ! : http://haskell.org/hoogle/?hoogle=!

Gives the first answer as: http://www.haskell.org/haskellwiki/Keywords#.21

If that isn't clear, someone should expand on it or give further links
to useful resources.

Thanks

Neil

2009/3/25 Harsh Verma hjve...@hotmail.com:
 I have seen ! added in front of many values, is it related to strict
 evaluation? Please elaborate on it.
 TIA,
 gimli

 
 Windows Live Messenger. Multitasking at its finest.
 ___
 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: about Haskell code written to be too smart

2009-03-25 Thread Conal Elliott
or via Arrow:

swap = snd  fst

On Wed, Mar 25, 2009 at 9:16 AM, David Menendez d...@zednenem.com wrote:

 On Wed, Mar 25, 2009 at 11:32 AM, Simon Marlow marlo...@gmail.com wrote:
  Jonathan Cast wrote:
 
  Define
 
 swap (a, b) = (b, a)
 
  ew, that's far too crude.  I think you mean
 
   swap = uncurry $ flip (,)

 On the theme of using monads where you might not expect,

 swap = liftA2 (,) snd fst

 --
 Dave Menendez d...@zednenem.com
 http://www.eyrie.org/~zednenem/ http://www.eyrie.org/%7Ezednenem/
 ___
 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] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Donn Cave
Quoth Jonathan Cast jonathancc...@fastmail.fm:

 On Wed, 2009-03-25 at 10:00 -0700, Donn Cave wrote:

 So I thought it would be interesting to explore statements like you
 must not do this, and pure Haskell is not allowed to be
 non-deterministic, in terms of practical effects.  No one would
 make a statement like that and not hope to be challenged on it?

 What?  Challenged by people who think Haskell should not be a purely
 functional language?  I mean, that's kind of what it is.  Again, if you
 don't want to use a purely functional language, there are *lots* of
 impure languages out there.  There's no need to turn Haskell into one of
 them.

OK.  You may note that I didn't actually pose any questions to you
until engaged directly, having already surmised that answers were not
forthcoming.

But for the record, I should note that I haven't proposed any changes
to Haskell, recently or that I recall even in the distant past except
for one idea I had about pattern matching in a lambda expression.

Donn

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


[Haskell-cafe] How to increment an Int in Haskell (stack overflow issue)

2009-03-25 Thread Tim Bauer

I have a program that is currently blowing out the stack,
   Stack space overflow: current size 8388608 bytes.
   Use `+RTS -Ksize' to increase it.
I am pretty sure I get to the end of the computation that
increments various statistic counters (lazily?) and only
when I go to print them out at the end, do things fail.

I have state monad transformer (StateT) that is keeping the counters
among other things. The counters are stored in a pair within a larger
data structure.

 data AState s a = AS { ...
   asStats :: (Int,Int)
   ...
 }

to increment them I initially just simply applied either of
 incFst, incSnd :: (Int,Int) - (Int,Int)
 incFst (x,y) = (x + 1,y)
 incSnd (x,y) = (x, y + 1)

to the current pair. I thought this was safe since primitive
arithmetic was strict, but when I go to print the counter
out (evaluate it), it blows apart.

I first decided this was because the addition was somehow not
strict and I was getting:
  (0 + 1 + 1 ...millions of times..., )
and the evaluation of that first coordinate blew things apart.
So I tried was adding a strictness annotation to the arguments.
 incFst (!x,y) = (x + 1,y)
 incSnd (x,!y) = (x, y + 1)

No dice (I also tried using seq manually all over the place
to no avail). Just for fun, I tried both of

 incFst _ = (0,0)
 incSnd _ = (0,0)

and

 incFst (x,y) = (x,y)
 incSnd (x,y) = (x,y)

The problem goes away. But maybe an optimization is covering
up the crime. So I tried

 incFst (x,y) = (y,x)
 incSnd (x,y) = (y,x)

And indeed this again crashes. Any hints as to what is going on?

If it is relevant, here is my code to access the counter within
the state monad

 countFst :: StateT (AState s a) IO ()
 countFst = modify $ \as - as{asStats = incFst (asStats as)}

and the monad transformer I am using is

 import Control.Monad.State.Strict
___
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 wren ng thornton

Thomas Hartman wrote:

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)



It's not tail recursive, FWIW. The recursive expression has (:) as it's 
head before it hits `partitions`. It is however nicely coinductive, 
which has other good properties.


We could make it tail-recursive easily,

  partitions = go id
  where
  go k [] xs = k []
  go k (n:ns) xs =
  let (beg,end) = splitAt n xs
  k'= k . (beg:)
  in  case end of
  []  - k' []
  xs' - go k' ns xs'

(Note how this version has `go` as the head of the recursive expression.)

...however this version has different strictness properties. In 
particular, let both input lists be infinite (and take a finite portion 
of the result). The original version works fine because it gives a 
little bit of output (beg:) at each step of the recursion ---which is 
all coinductive means. The tail-recursive version hits _|_ however, 
because we've delayed giving any input (k []) until one of the two lists 
hits [] ---we've tried doing induction on co-data and so we hit an 
infinite loop.


This dichotomy between coinduction and tail-recursion is quite common. 
It's another example of the recently discussed problem of defining foldr 
in terms of foldl. Whether the termination differences matter depends on 
how the function is to be used.



Another nice property of coinduction is that it means we can do 
build/fold fusion easily:


  partitions = \ns xs - build (\cons nil - go cons nil ns xs)
  where
  go cons nil = go'
  where
  go' [] xs = nil
  go' (n:ns) xs =
   let (beg,end) = splitAt n xs
   in  beg `cons` case end of
  []  - nil
  xs' - go' ns xs'

By using the GHC.Exts.build wrapper the fusion rules will automatically 
apply. The second wrapper, go, is just so that the worker, go', doesn't 
need to pass cons and nil down through the recursion.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Making videos of your project

2009-03-25 Thread Duane Johnson

Cool!  Thanks, Don.  I enjoyed the show :)

Duane Johnson

On Mar 24, 2009, at 2:20 AM, Don Stewart wrote:


Hey guys,

I've been making quick youtube videos of projects to convey what they
do. Here, for example, using Tim Docker's Charts library in ghci:

   http://www.youtube.com/watch?v=2Lqzygxvus0

(Click on the HD button for higher res).

Or one of Neil Brown's SG OpenGL graphics library,

   http://www.youtube.com/watch?v=tJ6AtfcorkY

You can create your own really simply:

   1. install 'recordmydesktop'
   I use: recordmydesktop --no-sound --v_bitrate 200
   2. type 'recordmydesktop'
   3. do something with haskell
   4. hit control-C
   5. upload out.ogv to youtube

If you're a library author of one of the 2 or 3D packages, please
consider video along with other why I want to use this material.

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


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


Re: [Haskell-cafe] How to increment an Int in Haskell (stack overflow issue)

2009-03-25 Thread Lennart Augustsson
Make an AState with two !Int fields and increment those.

On Wed, Mar 25, 2009 at 8:00 PM, Tim Bauer bauer...@eecs.orst.edu wrote:
 I have a program that is currently blowing out the stack,
   Stack space overflow: current size 8388608 bytes.
   Use `+RTS -Ksize' to increase it.
 I am pretty sure I get to the end of the computation that
 increments various statistic counters (lazily?) and only
 when I go to print them out at the end, do things fail.

 I have state monad transformer (StateT) that is keeping the counters
 among other things. The counters are stored in a pair within a larger
 data structure.

 data AState s a = AS { ...
                       asStats :: (Int,Int)
                       ...
                     }

 to increment them I initially just simply applied either of
 incFst, incSnd :: (Int,Int) - (Int,Int)
 incFst (x,y) = (x + 1,y)
 incSnd (x,y) = (x, y + 1)

 to the current pair. I thought this was safe since primitive
 arithmetic was strict, but when I go to print the counter
 out (evaluate it), it blows apart.

 I first decided this was because the addition was somehow not
 strict and I was getting:
  (0 + 1 + 1 ...millions of times..., )
 and the evaluation of that first coordinate blew things apart.
 So I tried was adding a strictness annotation to the arguments.
 incFst (!x,y) = (x + 1,y)
 incSnd (x,!y) = (x, y + 1)

 No dice (I also tried using seq manually all over the place
 to no avail). Just for fun, I tried both of

 incFst _ = (0,0)
 incSnd _ = (0,0)

 and

 incFst (x,y) = (x,y)
 incSnd (x,y) = (x,y)

 The problem goes away. But maybe an optimization is covering
 up the crime. So I tried

 incFst (x,y) = (y,x)
 incSnd (x,y) = (y,x)

 And indeed this again crashes. Any hints as to what is going on?

 If it is relevant, here is my code to access the counter within
 the state monad

 countFst :: StateT (AState s a) IO ()
 countFst = modify $ \as - as{asStats = incFst (asStats as)}

 and the monad transformer I am using is

 import Control.Monad.State.Strict
 ___
 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 + hopengl

2009-03-25 Thread Duane Johnson
Neat, thanks for that tip Peter.  It looks like mkbundl does  
everything I do manually, and more.  But just for the record, in case  
anyone (Scott?) wants to do it the hard way... :)


1. Download the macosx-app shell script from wxhaskell.  Make it  
executable (i.e. chmod a+x macosx-app)

2. Run macosx-app [executable-filename], e.g. macosx-app Playground
3. Run open [generated app directory], e.g. open Playground.app

I also blogged about it here.

Duane Johnson
http://blog.inquirylabs.com/

On Mar 24, 2009, at 4:48 PM, Peter Verswyvelen wrote:




On Tue, Mar 24, 2009 at 11:35 PM, Scott A. Waterman tswater...@gmail.com 
 wrote:

Duane -

yes, please.  I've been wondering how to compile to a Mac .app  
structure.


http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mkbndl

Also, anyone have any hints about distributing Haskell apps for mac,  
when you know the target will certianly *not* have a GHC environment  
on it?


GHC statically links everything, so you don't need the GHC  
environment to run the app.



Thanks
--ts


On Mar 21, 2009, at 2:18 PM, Duane Johnson wrote:

I've had issues with ghci and opengl... I usually have to compile my  
programs before they will run.  I'm not sure why that's the case,  
but I too get strange window behavior (sometimes it freezes, other  
times it doesn't even show up).


If you're on a Mac and would like help compiling to a .app folder,  
let me know and I can post how I did that.


Regards,
Duane Johnson
http://blog.inquirylabs.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] about Haskell code written to be too smart

2009-03-25 Thread Dan Weston

So to be clear with the terminology:

inductive   = good consumer?
coinductive = good producer?

So fusion should be possible (automatically? or do I need a GHC rule?) with
  inductive . coinductive

Or have I bungled it?

Dan

wren ng thornton wrote:

Thomas Hartman wrote:

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)



It's not tail recursive, FWIW. The recursive expression has (:) as it's 
head before it hits `partitions`. It is however nicely coinductive, 
which has other good properties.


We could make it tail-recursive easily,

   partitions = go id
   where
   go k [] xs = k []
   go k (n:ns) xs =
   let (beg,end) = splitAt n xs
   k'= k . (beg:)
   in  case end of
   []  - k' []
   xs' - go k' ns xs'

(Note how this version has `go` as the head of the recursive expression.)

...however this version has different strictness properties. In 
particular, let both input lists be infinite (and take a finite portion 
of the result). The original version works fine because it gives a 
little bit of output (beg:) at each step of the recursion ---which is 
all coinductive means. The tail-recursive version hits _|_ however, 
because we've delayed giving any input (k []) until one of the two lists 
hits [] ---we've tried doing induction on co-data and so we hit an 
infinite loop.


This dichotomy between coinduction and tail-recursion is quite common. 
It's another example of the recently discussed problem of defining foldr 
in terms of foldl. Whether the termination differences matter depends on 
how the function is to be used.



Another nice property of coinduction is that it means we can do 
build/fold fusion easily:


   partitions = \ns xs - build (\cons nil - go cons nil ns xs)
   where
   go cons nil = go'
   where
   go' [] xs = nil
   go' (n:ns) xs =
let (beg,end) = splitAt n xs
in  beg `cons` case end of
   []  - nil
   xs' - go' ns xs'

By using the GHC.Exts.build wrapper the fusion rules will automatically 
apply. The second wrapper, go, is just so that the worker, go', doesn't 
need to pass cons and nil down through the recursion.




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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
 Are you saying there's a problem with this implementation? It's the

Yes, there is actually a problem with this implementation.

import Data.List
import Control.Monad.State
import Debug.Trace.Helpers


partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
   [] - []
   xs - partitions parts xs)

partitionsSimpleStupidGood = partitions

partitionsTooFrickinClever = evalState . mapM (State . splitAt)

testP pf = mapM_ putStrLn  [
  show . pf [3,7..] $ [1..10]
  , show . pf [3,7,11,15] $ [1..]
  , show . head . last $ pf [3,3..] [1..10^6]
]

*Main testP partitionsSimpleStupidGood
testP partitionsSimpleStupidGood^J[[1,2,3],[4,5,6,7,8,9,10]]
[[1,2,3],[4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20,21],[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]]
100

Now try testP partitionsTooFrickinClever

Now, I am sure there is a fix for whatever is ailing the State monad
version, and we would all learn a lesson from it about strictness,
laziness, and the State monad.

However, there is something to be said for code that just looks like a
duck and quacks like a duck. It's less likely to surprise you.

So... I insist... Easy for a beginner to read == better!


2009/3/24 Dan Piponi dpip...@gmail.com:
 Miguel Mitrofanov wrote:
 takeList = evalState . mapM (State . splitAt)

 However, ironically, I stopped using them for pretty
 much the same reason that Manlio is saying.

 Are you saying there's a problem with this implementation? It's the
 only one I could just read immediately. The trick is to see that
 evalState and State are just noise for the type inferencer so we just
 need to think about mapM splitAt. This turns a sequence of integers
 into a sequence of splitAts, each one chewing on the leftovers of the
 previous one. *Way* easier than both the zipWith one-liner and the
 explicit version. It says exactly what it means, almost in English.
 --
 Dan
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Dan Weston


 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.


Put the simple version in a QuickCheck predicate. That is the ideal 
place for it.


All the better if through this process we all learn a lesson about 
strictness, laziness, and the State monad.


Dan

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.

import Data.List
import Control.Monad.State
import Debug.Trace.Helpers


partitions [] xs = []
partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
   [] - []
   xs - partitions parts xs)

partitionsSimpleStupidGood = partitions

partitionsTooFrickinClever = evalState . mapM (State . splitAt)

testP pf = mapM_ putStrLn  [
  show . pf [3,7..] $ [1..10]
  , show . pf [3,7,11,15] $ [1..]
  , show . head . last $ pf [3,3..] [1..10^6]
]

*Main testP partitionsSimpleStupidGood
testP partitionsSimpleStupidGood^J[[1,2,3],[4,5,6,7,8,9,10]]
[[1,2,3],[4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20,21],[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]]
100

Now try testP partitionsTooFrickinClever

Now, I am sure there is a fix for whatever is ailing the State monad
version, and we would all learn a lesson from it about strictness,
laziness, and the State monad.

However, there is something to be said for code that just looks like a
duck and quacks like a duck. It's less likely to surprise you.

So... I insist... Easy for a beginner to read == better!


2009/3/24 Dan Piponi dpip...@gmail.com:

Miguel Mitrofanov wrote:

takeList = evalState . mapM (State . splitAt)

However, ironically, I stopped using them for pretty
much the same reason that Manlio is saying.

Are you saying there's a problem with this implementation? It's the
only one I could just read immediately. The trick is to see that
evalState and State are just noise for the type inferencer so we just
need to think about mapM splitAt. This turns a sequence of integers
into a sequence of splitAts, each one chewing on the leftovers of the
previous one. *Way* easier than both the zipWith one-liner and the
explicit version. It says exactly what it means, almost in English.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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




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


Re: [Haskell-cafe] How to increment an Int in Haskell (stack overflow issue)

2009-03-25 Thread Daniel Fischer
Am Mittwoch 25 März 2009 20:00:40 schrieb Tim Bauer:
 I have a program that is currently blowing out the stack,
 Stack space overflow: current size 8388608 bytes.
 Use `+RTS -Ksize' to increase it.
 I am pretty sure I get to the end of the computation that
 increments various statistic counters (lazily?)

Far too lazily.

 and only
 when I go to print them out at the end, do things fail.

 I have state monad transformer (StateT) that is keeping the 
counters
 among other things. The counters are stored in a pair within a larger
 data structure.

   data AState s a = AS { ...
 asStats :: (Int,Int)
 ...
   }

 The problem goes away. But maybe an optimization is covering
 up the crime. So I tried

   incFst (x,y) = (y,x)
   incSnd (x,y) = (y,x)

 And indeed this again crashes. Any hints as to what is going on?

 If it is relevant, here is my code to access the counter within
 the state monad

   countFst :: StateT (AState s a) IO ()
   countFst = modify $ \as - as{asStats = incFst (asStats as)}

This is where the strictness you added to incFst is hidden again.
countFst writes the thunk (\as - as{asStats = incFst (asStats as)}) to 
the state, incFst isn't even called yet.

To force the evaluation,
a) make the stats two strict (!Int) fields
b) evaluate the state, like in

countFst = do
as - get
let a = asStats1 as
as1 = as{asStats1 = a+1}
put $! as1


 and the monad transformer I am using is

   import Control.Monad.State.Strict


___
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 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 tphya...@gmail.com:
 Are you saying there's a problem with this implementation? It's the

 Yes, there is actually a problem with this implementation.

 import Data.List
 import Control.Monad.State
 import Debug.Trace.Helpers


 partitions [] xs = []
 partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
               [] - []
               xs - partitions parts xs)

 partitionsSimpleStupidGood = partitions

 partitionsTooFrickinClever = evalState . mapM (State . splitAt)

 testP pf = mapM_ putStrLn  [
          show . pf [3,7..] $ [1..10]
          , show . pf [3,7,11,15] $ [1..]
          , show . head . last $ pf [3,3..] [1..10^6]
        ]

 *Main testP partitionsSimpleStupidGood
 testP partitionsSimpleStupidGood^J[[1,2,3],[4,5,6,7,8,9,10]]
 [[1,2,3],[4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20,21],[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]]
 100

 Now try testP partitionsTooFrickinClever

 Now, I am sure there is a fix for whatever is ailing the State monad
 version, and we would all learn a lesson from it about strictness,
 laziness, and the State monad.

 However, there is something to be said for code that just looks like a
 duck and quacks like a duck. It's less likely to surprise you.

 So... I insist... Easy for a beginner to read == better!


 2009/3/24 Dan Piponi dpip...@gmail.com:
 Miguel Mitrofanov wrote:
 takeList = evalState . mapM (State . splitAt)

 However, ironically, I stopped using them for pretty
 much the same reason that Manlio is saying.

 Are you saying there's a problem with this implementation? It's the
 only one I could just read immediately. The trick is to see that
 evalState and State are just noise for the type inferencer so we just
 need to think about mapM splitAt. This turns a sequence of integers
 into a sequence of splitAts, each one chewing on the leftovers of the
 previous one. *Way* easier than both the zipWith one-liner and the
 explicit version. It says exactly what it means, almost in English.
 --
 Dan
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
Since this thread is ostensibly about haskell style, it should also be
about haskell style *today*.

As I think Yitz noted earlier, this is a moving target.

Adoption of haskell by the masses -- moving.
Skill of haskell hordes -- moving.
Abstractions available as part of idiomatic haskell, and correctness
of these abstractions, as the state monad for partitions cockup shows
-- also moving.

2009/3/25 Jonathan Cast jonathancc...@fastmail.fm:
 On Wed, 2009-03-25 at 12:48 -0700, Dan Weston wrote:
  However, there is something to be said for code that just looks like a
   duck and quacks like a duck. It's less likely to surprise you.
  
   So... I insist... Easy for a beginner to read == better!

 All you have said is that one building a skyscraper will need
 scaffolding, blueprints, and a good building inspector. The intended
 inhabitants of that skyscraper will not want to stare out at scaffolding
 for the rest of their lives.

 +1

 jcc



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


Re: [Haskell-cafe] How to increment an Int in Haskell (stack overflow issue)

2009-03-25 Thread Don Stewart
bauertim:
 I have a program that is currently blowing out the stack,
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize' to increase it.
 I am pretty sure I get to the end of the computation that
 increments various statistic counters (lazily?) and only
 when I go to print them out at the end, do things fail.

 I have state monad transformer (StateT) that is keeping the counters
 among other things. The counters are stored in a pair within a larger
 data structure.

  data AState s a = AS { ...
asStats :: (Int,Int)
...
  }

I would always, always write this as:

data AState s a = AS { ...
 , asStatsX, asStatsY :: !Int
 , ...  }

and compile with:

ghc -O2 -funbox-strict-fields

Simple heuristic: unless otherwise specified, atomic types should always
be strict fields.

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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
Not only is your simpler function easier to read, it is also more correct.

partitionsHubris xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

partitionsBeginner :: [Int] - [a] - [[a]]
partitionsBeginner [] _ =  []
partitionsBeginner _ [] =  []
partitionsBeginner (n : ns) xs  =  head : partitionsBeginner ns tail
   where (head, tail) = splitAt n xs

Run both through testP to see why,.

testP pf = mapM_ putStrLn  [
  show . pf [3,7..] $ [1..10]
  , show . pf [3,7,11,15] $ [1..]
  , show . head . last $ pf [3,3..] [1..10^6]
]

Of course, I favor

partitions [] xs = []
partitions (n:parts) xs =
 let (beg,end) = splitAt n xs
 in beg : ( case end of
  [] - []
  xs - partitions parts xs)

which to my eyes is even easier to read (and also correct).

Pattern matching is awesome language feature. use it!


2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


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

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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
s/Pattern matching is awesome language feature. use it!
 /Pattern matching is awesome language feature. Don't be ashamed to use it! /

:)


2009/3/25 Thomas Hartman tphya...@gmail.com:
 Not only is your simpler function easier to read, it is also more correct.

 partitionsHubris xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 partitionsBeginner :: [Int] - [a] - [[a]]
 partitionsBeginner [] _         =  []
 partitionsBeginner _ []         =  []
 partitionsBeginner (n : ns) xs  =  head : partitionsBeginner ns tail
   where (head, tail) = splitAt n xs

 Run both through testP to see why,.

 testP pf = mapM_ putStrLn  [
          show . pf [3,7..] $ [1..10]
          , show . pf [3,7,11,15] $ [1..]
          , show . head . last $ pf [3,3..] [1..10^6]
        ]

 Of course, I favor

 partitions [] xs = []
 partitions (n:parts) xs =
  let (beg,end) = splitAt n xs
  in beg : ( case end of
              [] - []
              xs - partitions parts xs)

 which to my eyes is even easier to read (and also correct).

 Pattern matching is awesome language feature. use it!


 2009/3/24 Manlio Perillo manlio_peri...@libero.it:
 Tim Newsham ha scritto:

 These friends are very interested in Haskell, but it seems that the main
 reason why they don't start to seriously learning it, is that when they
 start reading some code, they feel the Perl syndrome.

 That is, code written to be too smart, and that end up being totally
 illegible by Haskell novice.

 I too have this feeling, from time to time.

 Since someone is starting to write the Haskell coding style, I really
 suggest him to take this problem into strong consideration.

 When you think about it, what you are saying is that Haskell programmers
 shouldn't take advantage of the extra tools that Haskell provides.

 No, I'm not saying this.

 But, as an example, when you read a function like:

 buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

 that can be rewritten (argument reversed) as:

 takeList :: [Int] - [a] - [[a]]
 takeList [] _         =  []
 takeList _ []         =  []
 takeList (n : ns) xs  =  head : takeList ns tail
    where (head, tail) = splitAt n xs

 I think that there is a problem.

 The buildPartition contains too many blocks.
 And I have read code with even more blocks in one line.

 It may not be a problem for a seasoned Haskell programmer, but when you
 write some code, you should never forget that your code will be read by
 programmers that can not be at your same level.

 I think that many Haskell programmers forget this detail, and IMHO this is
 wrong.

 Haskell provides the ability to abstract code beyond what many other
 programming systems allow.  This abstraction gives you the ability to
 express things much more tersely.  This makes the code a lot harder to read
 for people who are not familiar with the abstractions being used.

 The problem is that I have still problems at reading and understanding code
 that is too much terse...
 Because I have to assemble in my mind each block, and if there are too many
 blocks I have problems.

 [...]


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


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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread wren ng thornton

Manlio Perillo wrote:

The main problem, here, is that:
- recursion and pattern matching are explained in every tutorial about
  functional programming and Haskell.

  This is the reason why I find them more natural.

- high level, Haskell specific, abstractions, are *not* explained in
  normal tutorials or books.
  The libraries where these concepts are implemented, are not well
  documented.


This latter point is indeed the problem. But it may be worth rephrasing 
a bit. The big problem with the Haskell tutorials I've seen is that they 
aim to teach orthodoxy rather than orthopraxy. Or to put it less 
religiously, they teach the nuts and bolts of how the language is 
_constructed_, instead of teaching the idioms and ideas of how the 
language is _used_. It's like learning C from KernighanRitchie ---a 
fine book, don't get me wrong, but it teaches the words of the language 
instead of the community of the speakers. If you've memorized KR you're 
still a novice C programmer.


Given our history, this approach made sense. Haskell's been around for a 
long time, but most of that history has been in academia where it's 
assumed that people will know what to do if only they knew how to do it. 
More recently Haskell has been moving from academic toy to industrial 
tool, and that shift necessitates a similar shift from teaching the 
language as a collection of interesting features to teaching the 
language as a collection of interesting libraries. History hinders this 
transition--- both the internal history of those who know Haskell (and 
thus can teach it but only as they know it), and also the external 
history of the mainstream which understands imperativistic thinking but 
not functional declarative thinking (and thus we must teach the features 
in order to give the understanding necessary for teaching the libraries).



Recently Galois has been focusing on developing the infrastructure 
necessary for having easy access to libraries. To this day CPAN is the 
reason why Perl is one of the best languages out there. Other languages 
have tried emulating that repository, but the only one I've seen that 
has the community necessary to make it fly has been Hackage; and the 
development of Cabal/Hackage is very recent and still very bleeding edge 
(with the scars to prove it). With Galois' support, I think most 
Haskellers are aware of Hackage now, however it still hasn't made it 
into the tutorials in the same way that CPAN is integral to the teaching 
of Perl.


Real World Haskell is another groundbreaking, but recent, development. 
It's a great book in itself and groundbreaking for embracing 
open-development in the publishing industry, but it's also the first of 
this shift from teaching Haskell = Patterns + Recursion + Laziness + 
Class to teaching modern Haskell in a more holistic community-oriented 
way. It's worth reiterating that RWH was not the cause of the shift in 
the community, but is rather a result of the ongoing shift. The 
Typeclassopedia is another drop in this river: excellent, recent.


So I agree that most of the tutorials are lagging behind the modern form 
of Haskell, but I think this is due in part to a very recent change in 
the growth and direction of the community. As always with avoiding 
success at all costs, whether we end up the better for it in the end 
will depend on holding onto enough newcomers who have only ever known 
this modern Haskell, because they are the ones who will have the proper 
perspective to write tutorials and teach the language as if it's always 
been this way. You must be the change you wish to see in the world.




  Most of the documentation is in research papers, and a normal
  programmer don't want to read these papers.


Yes, and no. There is quite a bit of documentation in research papers, 
and mainstream programmers don't read research. However, this is a big 
part of what makes the Haskell community what it is. There are plenty of 
non-academics here, but they have the willingness to read these papers 
(even if it's out of the ordinary) and the desire to learn radical new 
things (because they're out of the ordinary). A good deal of the papers 
these days are eminently readable by the laity, moreso than other 
research papers in computer science or programming languages IMO.


This is one of the big things that separates Haskell from the 
mainstream, but it's not something I see going away any time soon. Given 
the recent surge of interest from the mainstream, I think it's finally 
time that we take a more proactive approach in trying to teach this 
aspect as one of the tenants of our community. Presently there's still a 
take it or leave it tenor to these discussions, and that needs to be 
dispelled before it poisons the relations between the old guard and the 
young turks. New tutorials need to find some way of introducing 
non-academics to the idea that the academy is not an ivory tower and 
that part of what makes Haskell cool is the fact that it 

Re: [Haskell-cafe] [ANN] ansi-terminal, ansi-wl-pprint - ANSI terminal support for Haskell

2009-03-25 Thread Andrew Coppin

Max Bolingbroke wrote:

These two packages allow Haskell programs to produce much richer
console output by allowing colorisation, emboldening and so on.

Both Unix-like (OS X, Linux) and Windows operating systems are
supported (via a pure Haskell ANSI emulation layer for Windows).

Examples, screenshots, and lots more information about how to get the
packages are available at the freshly-minted homepages:
http://batterseapower.github.com/ansi-terminal/
http://batterseapower.github.com/ansi-wl-pprint/

These two packages have actually been in stealth release mode on
Hackage for some time. However, they seem to be getting some use and
I'm not getting any bug reports, so I figure that they /must/ be
stable enough to make a proper announcement :-)
  


I use ANSI-Terminal all the time - AND I'M ON WINDOWS! ;-)

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


Re: [Haskell-cafe] [ANN] ansi-terminal, ansi-wl-pprint - ANSI terminal support for Haskell

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 21:18 +, Andrew Coppin wrote:
 I'M ON WINDOWS! ;-)

We've noticed...

jcc


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


Re: [Haskell-cafe] [ANN] I/O library for Windows

2009-03-25 Thread Andrew Coppin

Felix Martini wrote:

Hi all,

winio is an I/O library for Windows using Windows API functions and
has I/O completion port support. The main goal of this library is to
support Simon Marlow's new Handle API once he has added that to GHC.
The library also has a compatibility module for socket functions from
the network-bytestring package. Because the library uses IOCP instead
of select it is not limited to 1024 open sockets. Try for example the
thread-ring program where each Haskell thread passes a UDP message
around (Change the MaxUserPort field in
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
to 65534 to enable all ports).

The winio package is available on Hackage. Notice that it uses a
development version of the network package which is available at
http://darcs.haskell.org/packages/network/. The library has not been
tested much and should be considered experimental so please try it if
you use Windows and notify me of any issue or corner case.
  


As I understand it, programs compiled with GHC currently use MSYS for 
all I/O operations, resulting in all kinds of strange behaviour in 
corner cases. (E.g., if you use System.Directory and ask whether C:\\ 
is a directory, it says no, yet you can read the contents of that 
directory.) I would have thought that calling the Win32 API directly 
would probably fix most of these minor glitches. Is that what this 
package is intending to do?


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


Re: [Haskell-cafe] ANNOUNCE: WinGhci, a GUI for GHCI on Windows

2009-03-25 Thread Andrew Coppin

Pepe Gallardo wrote:

Hi, I am pleased to announce the first release of WinGhci.
 
WinGhci is a simple GUI for GHCI on Windows. It is closely based on 
WinHugs, and provides similar functionality.


This is now #1 on my list of things that must be tried.

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


Re: [Haskell-cafe] Learning Haskell

2009-03-25 Thread Andrew Coppin

Tom.Amundsen wrote:

How long did it take you to become proficient in Haskell? By that, I mean -
how long until you were just as comfortable with Haskell as you were with
your strongest language at that time?
  


I probably shouldn't even answer that. I keep thinking I only just found 
out about Haskell, but I have PDF files containing Haskell tutorials, 
written by me, dated 2005 and earlier. o_O


How long did it take to be comfortable with Haskell? A few weeks, I think.

How long did it take to become an expert? Ask me when I become an expert!

It seems to me that Haskell is like Go: The rules are easy. The 
strategies for using them... are not.



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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Henning Thielemann


On Wed, 25 Mar 2009, Jonathan Cast wrote:


On Wed, 2009-03-25 at 07:39 -0400, Xiao-Yong Jin wrote:


Could you elaborate more about why this kind of breakage
wouldn't happen if 'try' is used in an IO monad as intended?


It would.  But it would happen in IO, which is allowed to be
non-deterministic.  Pure Haskell is not allowed to be non-deterministic.


In my opinion, 'try' catching 'error's is still a hack, since 'error's aka 
bottom mean programming error. Thus catching them is debugging, bug hiding 
or something worse, but not exception handling. 'try' and friends should 
be limited to exceptional outcomes of IO actions, e.g. disk full, file 
read protected etc. There might be a variant 'unsafeTry' which can also 
block 'error's.

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Jonathan Cast
On Wed, 2009-03-25 at 22:32 +0100, Henning Thielemann wrote:
 On Wed, 25 Mar 2009, Jonathan Cast wrote:
 
  On Wed, 2009-03-25 at 07:39 -0400, Xiao-Yong Jin wrote:
 
  Could you elaborate more about why this kind of breakage
  wouldn't happen if 'try' is used in an IO monad as intended?
 
  It would.  But it would happen in IO, which is allowed to be
  non-deterministic.  Pure Haskell is not allowed to be non-deterministic.
 
 In my opinion, 'try' catching 'error's is still a hack, since 'error's aka 
 bottom mean programming error. Thus catching them is debugging, bug hiding 
 or something worse, but not exception handling.

100% agreed.  The nice thing about the extensible exceptions is that you
*can* decline to handle ErrorCall `exceptions'; but errors caught by try
should be viewed analogously to signals or asynchronous exceptions.  The
RTS sometimes detects a bug and (sometimes!) stops execution with an
exception; the user sometimes detects the bug and (sometimes!) stops
execution with SIGINT.  The most you can do is try to limit the amount
of secondary damage and give the programmer the best clue where to start
hunting.

jcc


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


[Haskell-cafe] Data Structures with Haskell

2009-03-25 Thread Rohit Agrawalla
I am a beginner haskell programmer. I am interested  in data structures
implementation (all from basic ones like stack, queues etc. to advance ones
like balanced binary trees, graphs etc.)  in haskell. It would be really
helpful if someone can point some good references for the same.

Regards ,
Rohit
___
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 wren ng thornton

Dan Weston wrote:

So to be clear with the terminology:

inductive   = good consumer?
coinductive = good producer?

So fusion should be possible (automatically? or do I need a GHC rule?) with
  inductive . coinductive

Or have I bungled it?


Not quite. Induction means starting from base cases and building things 
upwards from those. Coinduction is the dual and can be thought of as 
starting from the ceiling and building your way downwards (until you hit 
the base cases, or possibly forever).


So, if you have potentially infinite data (aka co-data) coming in, then 
you need to use coinduction because you may never see the basis but you 
want to make progress anyways. In formal terms, coinduction on co-data 
gives the same progress guarantees as induction on data, though 
termination is no longer a conclusion of progress (since coinduction may 
produce an infinite output from infinite input).


Haskell doesn't distinguish data and co-data, but you can imagine data 
as if all the data constructors are strict, and co-data as if all the 
constructors are lazy. Another way to think of it is that finite lists 
(ala OCaml and SML) are data, but streams are co-data.




For fusion there's the build/fold type and its dual unfold/destroy, 
where build/unfold are producers and fold/destroy are consumers. To 
understand how fusion works, let's look at the types of build and fold.


GHC.Exts.build  :: (forall b. (a - b - b) - b - b) - [a]
flip (flip . foldr) :: [a] - ( (a - b - b) - b - b )

Together they give an isomorphism between lists as an ADT [a] and as a 
catamorphism (forall b. (a - b - b) - b - b), aka Church encoding. 
When we have build followed by foldr, we can remove the intermediate 
list and pass the F-algebra down directly:


foldr cons nil (build k) = k cons nil

For unfold/destroy fusion the idea is the same except that we use unfold 
(an anamorphism on the greatest fixed point) instead of fold (a 
catamorphism on the least fixed point). The two fixed points coincide in 
Haskell.


Since Haskell does build/fold fusion, good producer requires that the 
function was written using build, and good consumer requires it's 
written using foldr. Using these functions allows us to apply the rule, 
though it's not sufficient for good fusion. Why the functions have the 
particular types they do and why this is safe has to do with induction 
and coinduction, but the relationship isn't direct.




The reason a coinductive function is easy to make into a good producer 
has to do with that relationship. Take a canonically coinductive 
function like


f [] = []
f (x:xs) = x : f xs

Once we've made one step of recursion, we've generated (x:) and then 
have a thunk for recursing. Most importantly is that no matter how we 
evaluate the rest of the list, the head of the return value is already 
known to be (:) thus we can get to WHNF after one step. Whatever 
function is consuming this output can then take x and do whatever with 
it, and then pull on f xs which then takes a single step and returns 
(x':) along with a thunk f xs'. Because all of those (:) are being 
produced immediately, it's easy to abstract it out as a functional 
argument--- thus we can use build.


Coinduction doesn't need to do 1-to-1 mapping of input to output, there 
just needs to be the guarantee that we only need to read a finite amount 
of input before producing a non-zero finite amount of output. These 
functions are also coinductive:


p []   = []
p [x]  = [x]
p (x:y:ys) = y : x : p ys

q []   = []
q [x]  = []
q (x:y:ys) = y : q ys

r [] = []
r (x:xs) = x : x : r xs

They can also be written using build, though they're chunkier about 
reading input or producing output. These functions are not coinductive 
because there's no finite bound on how long it takes to reach WHNF:


bad [] = []
bad (x:xs) = bad xs

reverse [] = []
reverse (x:xs) = reverse xs ++ [x]

Because build/fold is an isomorphism, we can technically use build for 
writing *any* function that produces a list. However, there's more to 
fusion than just using the build/fold isomorphism. The big idea behind 
it all is that when producers and consumers are in 1-to-1 correlation, 
then we can avoid allocating that 1 (the cons cell) and can just pass 
the arguments of the constructor directly to the consumer. For example:


let buildF [] = []
buildF (x:xs) = x : buildF xs

consumeF [] = 0
consumeF (x:xs) = 1 + consumeF xs
in
consumeF . buildF
==
let buildF = \xs - build (f xs)
where
f [] cons nil = nil
f (x:xs) cons nil = x `cons` f xs cons nil

consumeF = foldr consumeCons consumeNil
where
consumeNil   = 0
consumeCons x rs = 1 + rs
in
consumeF . buildF
==
let f [] cons nil = nil
f (x:xs) cons nil = x `cons` f xs 

Re: [Haskell-cafe] Data Structures with Haskell

2009-03-25 Thread Gwern Branwen

2009/3/25 Rohit Agrawalla son...@gmail.com:

I am a beginner haskell programmer. I am interested  in data structures
implementation (all from basic ones like stack, queues etc. to advance ones
like balanced binary trees, graphs etc.)  in haskell. It would be really
helpful if someone can point some good references for the same.

Regards ,
Rohit


Okasaki's thesis on functional datastructures
http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf

and the implementation in Haskell
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/EdisonCore

are both good places to start.

--
gwern

signature.asc
Description: OpenPGP digital signature
___
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 Dan Piponi
On Wed, Mar 25, 2009 at 12:44 PM, Thomas Hartman tphya...@gmail.com wrote:
 Are you saying there's a problem with this implementation? It's the

 Yes, there is actually a problem with this implementation.

 However, there is something to be said for code that just looks like a
 duck and quacks like a duck. It's less likely to surprise you.

Well the problem here isn't that the code does something surprising.
It's author was making assumptions about the type of input that it's
going to get. I think that's an orthogonal issue.

 So... I insist... Easy for a beginner to read == better!

Not at all. Beginner list processing code can and often does go awry
when presented with infinite lists.

The moral here has nothing to do with readability by beginners. It's:
if the function you're defining could be extended naturally to
infinite lists, and it would be useful to do so, then make it do so.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Ryan Ingram
On Wed, Mar 25, 2009 at 8:25 AM, Jonathan Cast
jonathancc...@fastmail.fm wrote:
 On Wed, 2009-03-25 at 15:09 +, Simon Marlow wrote:
 the ordering that the state monad expects
 (and I can never remember which way around they are in Control.Monad.State).

 Really?  I found it obvious once I figured out it how simple it made
 (=).  With the order from Control.Monad.State (with constructors
 ignored):

    a = f = \ s - case s a of
       (x, s') - f x s'

 Reversing the order of the components of the result gives you

    a = f = \ s - case s a of
        (s', x) - f x s'

 which just looks weird.

However, if you are used to thinking in terms of type composition, s
- (s, a) makes more sense, because it is effectively

  (s -) . (s,) . Identity

whose functor-ness is automatic via composition of functors:

newtype Identity a = Identity a
inIdentity f (Identity a) = Identity (f a)

instance Functor Identity where
fmap f = inIdentity f

instance Functor ((,) a) where
fmap f (a, x) = (a, f x)
instance Functor ((-) a) where
fmap f k a = f (k a)

newtype O f g x = O (f (g x))
inO f (O a) = O (f a)
instance (Functor f, Functor g) = Functor (O f g) where
fmap f = inO (fmap (fmap f))
-- or fmap = inO . fmap . fmap

-- not valid haskell, but if there were sections at the type level it would be.
type State s = (s -) `O` (s,) `O` Identity

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


[Haskell-cafe] [OT] Japanese (was: Re: about Haskell code written to be too smart)

2009-03-25 Thread wren ng thornton

Zachary Turner wrote:

On Tue, Mar 24, 2009 at 10:32 PM, wren ng thornton w...@freegeek.orgwrote:


Both of these conclusions seem quite natural to me, even from before
learning Haskell. It seems, therefore, that naturality is not the proper
metric to discuss. It's oft overlooked, but the fact is that expressivity
comes not from more formal power, but from _less_.

* Natural language has a limited range of words and syntactic constructs,
but gives the larger-enough building blocks to enable unconstrained
communication; whereas a language with a unique word for every utterance
(arguably simpler) is impossible to learn.



On the other hand, -certain- languages are more expressive than others.  As
an example, I personally find English far more expressive than both
Vietnamese and Japanese, yet English is far more complicated.


That's funny, I find Japanese to be far more expressive than English. 
(The language itself. Due to familiarity, I myself am more expressive in 
English.)


Japanese has sophisticated forms of address that indicate the distance, 
degree, and style of the speaker's relationship with the listener. In 
English we can get the point across but we don't have the formalism and 
so it's all a lot more handwaving. Japanese can indicate topic and focus 
directly; whereas English must resort to bold/italics or syntactic 
contortions to be precise. Japanese has a wide assortment of pronouns 
which imply measures of respect, arrogance, disdain, abashment, etc; 
whereas English is limited to a small number that are only deictic. 
Japanese has many postpositions which capture abstract comparative 
relations that are difficult to express concisely in English. Japanese 
sentential particles can express a wide range of affect; whereas English 
must rely on intonation and context to determine whether something 
should be interpreted as compassionate, bonding, insulting, ironic, etc.


Of course it all depends on what exactly you care to express. Japanese 
has restricted phonology, as you mentioned, though this is only as 
meaningful as the character set used for variable names in a programming 
language. Japanese also lacks certain sophisticated distinctions in 
English like definite vs indefinite articles, and singular vs plural vs 
mass-count nouns.




Words that are spelled the same in Japanese are
pronounced the same 100% of the time.


False. There are numerous words which have the same spelling and 
different pronunciations. For example 今日 can be either /kyou/ today 
or /kon'niti/ every day; daily. This is one reason why learning to 
read Japanese is so difficult for westerners. An even bigger reason is 
that countless words can be spelled in a number of different ways, with 
each spelling having different nuances and implications (sometimes to 
the point where the spellings are not interchangeable).




Anyway the point of all this is that in English you have more freedom and
more power, and hence you use (abuse?) the syntax of the language to create
words, sentences, and phrases that express very powerful things.
Furthermore, they are things that almost all English speakers would be able
to grasp the full meaning of what you've said.


All natural languages are Thinking-complete. Just like with 
Turing-complete programming languages, the only difference is where they 
hide the bodies. There are plenty of things that I as a native speaker 
of English could say which other natives would grasp but which would 
confuse many of my non-native yet fluent coworkers. The Japanese abuse 
their syntax just as badly as we abuse English, or far far worse if we 
include the slang of youth culture. The Japanese have long thought of 
their language as a toy box ripe for experimentation, and you can see 
the effects of this everywhere.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Data Structures with Haskell

2009-03-25 Thread Achim Schneider
Rohit Agrawalla son...@gmail.com wrote:

 I am a beginner haskell programmer. I am interested  in data
 structures implementation (all from basic ones like stack, queues
 etc. to advance ones like balanced binary trees, graphs etc.)  in
 haskell. It would be really helpful if someone can point some good
 references for the same.
 
The fgl paper[1] is highly readable. It explains and solves the issues a
functional approach has to overcome that an imperative approach can
simply hack around and gave me many important insights into how to
think in a functional way as I was starting to learn Haskell. YMMV, but
if you're a decent imperative coder and/or got any kind of scheme or
ocaml experience most of it shouldn't be too hard to follow.


[1] http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01

-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


[Haskell-cafe] Re: How to increment an Int in Haskell (stack overflow issue)

2009-03-25 Thread John Lato
 From: Tim Bauer bauer...@eecs.orst.edu

 I have a program that is currently blowing out the stack,
    Stack space overflow: current size 8388608 bytes.
    Use `+RTS -Ksize' to increase it.
 I am pretty sure I get to the end of the computation that
 increments various statistic counters (lazily?) and only
 when I go to print them out at the end, do things fail.


In addition to the excellent advice provided by others on this topic,
you may want to look at using GHC's heap profiler if you can't track
down the source of a memory issue.  I've found it helpful in the past.
 Keep in mind that there are several different modes that may or may
not be helpful for a particular problem, so you should try them all to
see if you get any useful information.

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


[Haskell-cafe] Re: [OT] Japanese (was: Re: about Haskell code written to be too smart)

2009-03-25 Thread Achim Schneider
wren ng thornton w...@freegeek.org wrote:

 All natural languages are Thinking-complete.

No, they aren't. Falsifying the Saphir-Worph thesis, I quite often find
myself incapable of expressing a certain thought, or if I succeed,
come up with two or more versions in multiple different languages that
mean slightly different things, and, in retrospect, all don't fit the
thought. 

On another scale, it's just a waste of time: Why should I spend minutes
figuring out how to spell out Even though X - Y and X - nonsense, 
(Z - Y) - nonsense does not necessarily hold when I already figured
that one out.

All thoughts are fundamentally ineffable: Therefore, all languages are
thinking-incomplete.

-- 
(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.


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


Re: [Haskell-cafe] about Haskell code written to be too smart

2009-03-25 Thread Thomas Hartman
 Beginner list processing code can and often does go awry when presented with 
 infinite lists.

I didn't mean code that a beginner would write, I mean code that would
be easy to understand for a beginner to read -- that is, explicit
pattern matching, explicit recursion, no gratuitous use of state
monad.

I don't think I necessarily would have written my favored version when
learning haskell, probably something a lot uglier.

What I like about the pattern matching is the totality -- you see all
the possible inputs, and you see what happens.

With the state version, there's a lot of behind-the-scenes magic, and
as we've seen, things can go wrong.

Also, the issue isn't infinite lists, but lists that are longer than
the sum of the partitions provided. The state monad partition version
goes equally as badly awry if the test is restructured as

testP pf = mapM_ putStrLn  [
  show . pf ( take 1000 [3,7..] ) $ [1..10]
  , show . pf [3,7,11,15] $ ( take (10^6) [1..])
  , show . head . last $ pf (take 1000 $ [3,3..]) [1..10^6]
]

(no infinite lists, just long lists)



2009/3/25 Dan Piponi dpip...@gmail.com:
 On Wed, Mar 25, 2009 at 12:44 PM, Thomas Hartman tphya...@gmail.com wrote:
 Are you saying there's a problem with this implementation? It's the

 Yes, there is actually a problem with this implementation.

 However, there is something to be said for code that just looks like a
 duck and quacks like a duck. It's less likely to surprise you.

 Well the problem here isn't that the code does something surprising.
 It's author was making assumptions about the type of input that it's
 going to get. I think that's an orthogonal issue.

 So... I insist... Easy for a beginner to read == better!

 Not at all. Beginner list processing code can and often does go awry
 when presented with infinite lists.

 The moral here has nothing to do with readability by beginners. It's:
 if the function you're defining could be extended naturally to
 infinite lists, and it would be useful to do so, then make it do so.
 --
 Dan

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread wren ng thornton

Henning Thielemann wrote:

Jonathan Cast wrote:
 Xiao-Yong Jin wrote:
 
  Could you elaborate more about why this kind of breakage
  wouldn't happen if 'try' is used in an IO monad as intended?

 It would.  But it would happen in IO, which is allowed to be
 non-deterministic.  Pure Haskell is not allowed to be non-deterministic.

In my opinion, 'try' catching 'error's is still a hack, since 'error's 
aka bottom mean programming error. Thus catching them is debugging, bug 
hiding or something worse, but not exception handling. 'try' and friends 
should be limited to exceptional outcomes of IO actions, e.g. disk 
full, file read protected etc. There might be a variant 'unsafeTry' 
which can also block 'error's.


+1.

I have long been disappointed by a number of `error`s which shouldn't 
be. For example, the fact that `head` and `div` are not total strikes me 
as a (solvable) weakness of type checking, rather than things that 
should occur as programmer errors/exceptions at runtime. The use of 
`error` in these cases muddies the waters and leads to a laissez-faire 
attitude about when it's acceptable to throw one's hands up in despair 
and use `error` rather than writing a better function.


As nice as exceptional control flow is, I can't help but think there was 
a reason the H98 committee said that `error` should be uncatchable. That 
we'd like to be able to catch errors in an interpreter or debugger is 
the exception that proves the rule. Extensible exceptions are 
impressive, but the existence of exceptions outside of type annotations 
says something about purity. Let us not err in the direction of Java, 
but we really should plug that hole.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] typeOf for polymorphic value

2009-03-25 Thread Lennart Augustsson
Using Data.Typeable.typeOf we can get a representation of the the type
of a monomorphic value, for instance
  Prelude Data.Typeable typeOf not
  Bool - Bool

But if we try using it on a polymorphic value it fails
  Prelude Data.Typeable typeOf id

  interactive:1:0:
Ambiguous type variable `a' in the constraint:
  `Typeable a' arising from a use of `typeOf' at interactive:1:0-8
Probable fix: add a type signature that fixes these type variable(s)

And understandably so.  Does anyone know of a trick to accomplish `typeOf id'?
Using something else than TypeRep as the representation, of course.

Any tricks and existing language extensions are welcome.
(As ghc moves towards first class polymorphic values this question
gets more interesting.)

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


Re: [Haskell-cafe] Learning Haskell

2009-03-25 Thread Lennart Augustsson
I'm still learning. :)   (And I wrote the first available Haskell compiler.)

  -- Lennart

On Tue, Mar 24, 2009 at 4:08 AM, Tom.Amundsen tomamund...@gmail.com wrote:

 How long did it take you to become proficient in Haskell? By that, I mean -
 how long until you were just as comfortable with Haskell as you were with
 your strongest language at that time?
 --
 View this message in context: 
 http://www.nabble.com/Learning-Haskell-tp22673552p22673552.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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

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


[Haskell-cafe] Re: about Haskell code written to be too smart

2009-03-25 Thread Heinrich Apfelmus
Manlio Perillo wrote:
 Heinrich Apfelmus ha scritto:

 I think you'd have had a much easier time by starting with a proper book
 right away, like Richard Bird's Introduction to Functional Programming
 in Haskell, accompanied by Real World Haskell. 
 
 Unfortunately, one year ago Real World Haskell was not here.
 And note that I have no problems with basic functional programming
 concepts.
 My problems are specific to Haskell.

Despite the title, Bird's book is quite specific to Haskell, in
particular concerning the philosophy of composing solutions from
building blocks as opposed to primitive recursion.

I'd say that every serious Haskell programmer should have it on his
bookshelf (even if only for show ;) ).


Regards,
apfelmus

--
http://apfelmus.nfshost.com

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


Re: [Haskell-cafe] Re: a cabal package with both a library and executable programs

2009-03-25 Thread Duncan Coutts
On Wed, 2009-03-25 at 15:19 +0100, Achim Schneider wrote:
 Manlio Perillo manlio_peri...@libero.it wrote:
 
  Should I fill a feature request ticket, or this is how it is supposed
  to work?
 
 I would like to be able to do that, too. I also don't want cabal to
 recompile a thousand modules just for a demo program, and don't want to
 see hackage being polluted by thousands of foo-lib and foo-bin packages
 to circumvent the current behaviour, either.
 
 That is, feel yourself seconded.

The existing ticket for this feature request is:

http://hackage.haskell.org/trac/hackage/ticket/89

The plan is to allow the executables to build-depend on the library.

Duncan

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Duncan Coutts
On Wed, 2009-03-25 at 18:14 +0100, Benja Fallenstein wrote:
 On Wed, Mar 25, 2009 at 3:52 AM, Duncan Coutts

  Of course your tryArith only tests for certain kinds of _|_ value, but
  in principle the problem is the same.
 
 That's not *quite* how the semantics of Haskell exceptions are
 defined, actually, unless I'm misunderstanding something or the
 thinking about it has changed since the original paper on the topic:

Yep, that's the semantics I've been working from too.

I was not being precise when I said tests for _|_. As you point out,
the semantics of imprecise exceptions distinguishes exceptions from
bottom, however pure code cannot make that distinction and so that's why
I was lumping them together and saying that tryArith tests for certain
kinds of _|_ value.

 tryArith is still noncontinuous, though, and nondeterministic, too. Consider:

Those are nice examples. Thanks for that. I was too tired to come up
with any :-)

Anyway, I hope this is enough to dissuade people from using
unsafePerformIO to catch exceptions.

Duncan

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


Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?

2009-03-25 Thread Benja Fallenstein
On Thu, Mar 26, 2009 at 2:40 AM, Duncan Coutts
duncan.cou...@worc.ox.ac.uk wrote:
 I was not being precise when I said tests for _|_. As you point out,
 the semantics of imprecise exceptions distinguishes exceptions from
 bottom, however pure code cannot make that distinction and so that's why
 I was lumping them together and saying that tryArith tests for certain
 kinds of _|_ value.

Right... I had this mental picture of exceptions being values
denotationally smaller than any real value of the domain before I
read the imprecise exceptions paper, so I interpreted your imprecise
description that way =)

 Anyway, I hope this is enough to dissuade people from using
 unsafePerformIO to catch exceptions.

Yes, unfortunately you can't even use it to return Nothing on errors
(ie without returning the specific exception) because of the (overflow
+ loop) issue where you have nondeterminism between returning Nothing
and looping forever. I have my own history of wondering why isn't
there in Control.Exception a function that... for a while before
figuring out why there isn't :-)

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


[Haskell-cafe] typeOf for polymorphic value

2009-03-25 Thread oleg

 Does anyone know of a trick to accomplish `typeOf id'?
 Using something else than TypeRep as the representation, of course.

Yes. The analysis of polymorphic types has been used in the inverse
type-checker
http://okmij.org/ftp/Haskell/types.html#de-typechecker

The enclosed code computes TypeRep of polymorphic values. 
The code returns real TypeRep. Here are a few examples:

tt2 = mytypof not
-- Bool - Bool

tt3 = mytypof [True]
-- [Bool]

tt4 = mytypof id
-- any1 - any1

tt5 = mytypof []
-- [any1]

tt6 = mytypof const
-- any1 - any2 - any1

tt7 = mytypof Just
-- any1 - Maybe any1

tt8 = mytypof map
-- (any1 - any2) - [any1] - [any2]

tt9 = mytypof maybe
-- any1 - (any2 - any1) - Maybe any2 - any1

The code was tested on GHC 6.8.2. I don't have access to any computer
with GHC 6.10, so I can't say how it works with that version of GHC.

{-# LANGUAGE ScopedTypeVariables, EmptyDataDecls #-}
{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE IncoherentInstances #-}

module Typeof where

import Data.Typeable

-- tests

tt1 = mytypof True
-- Bool

tt2 = mytypof not
-- Bool - Bool

tt3 = mytypof [True]
-- [Bool]

tt4 = mytypof id
-- any1 - any1

tt5 = mytypof []
-- [any1]

tt6 = mytypof const
-- any1 - any2 - any1

tt7 = mytypof Just
-- any1 - Maybe any1

tt8 = mytypof map
-- (any1 - any2) - [any1] - [any2]

tt9 = mytypof maybe
-- any1 - (any2 - any1) - Maybe any2 - any1

class MyTypeable a where
mytypof :: a - TypeRep

-- Gamma is the sequence of type varaibles. It is used to assign
-- different indices to different type variables
instance (Analyze a result, MyTypeable' HNil gout result)
= MyTypeable a 
 where
 mytypof a = fst $ mytypof' HNil (analyze a)

class MyTypeable' gin gout classification | gin classification - gout where
mytypof' :: gin - classification - (TypeRep,gout)


instance Typeable a = MyTypeable' gin gin (TAtomic a) where
mytypof' gin _ = (typeOf (undefined::a), gin)

instance Typeable a = MyTypeable' gin gin (TAtomic1 a) where
mytypof' gin _ = (typeOf (undefined::a), gin)

instance (MyTypeable' gin g a, MyTypeable' g gout b)
= MyTypeable' gin gout (TFunction a b) where
mytypof' gin _ = let (tr1,g)= mytypof' gin (undefined::a)
 (tr2,gout) = mytypof' g (undefined::b)
 in (mkFunTy tr1 tr2,gout)

instance (MyTypeable' gin g c, MyTypeable' g gout a)
= MyTypeable' gin gout (TConstructed c a) where
mytypof' gin _ = let (tr1,g)= mytypof' gin (undefined::c)
 (tr2,gout) = mytypof' g (undefined::a)
 in (mkTyConApp (typeRepTyCon tr1) [tr2],gout)

instance (HIndex a gin n, MyTypeable'' n gin gout (TVariable a))
  = MyTypeable' gin gout (TVariable a) where
mytypof' = mytypof'' (undefined::n)


class MyTypeable'' n gin gout classification | n gin classification -gout where
mytypof'' :: n - gin - classification - (TypeRep,gout)


instance HLen gin n1 = MyTypeable'' Z gin (HCons a gin) (TVariable a) where
mytypof'' _ gin _ = (mkany (undefined::S n1),
 HCons (undefined::a) gin)

instance Nat n = MyTypeable'' (S n) gin gin (TVariable a) where
mytypof'' _ gin _ = (mkany (undefined::S n), gin)


mkany :: Nat n = n - TypeRep
mkany n = mkTyConApp (mkTyCon ts) []
 where
 ts = any ++ show (nat n)


-- Lookup the index of an item x in the list l
-- The index is 1-based. If not found, return 0
class Nat n = HIndex x l n | x l - n

instance HIndex x HNil Z

instance (Nat n, TypeEq x a f, HIndex' f x (HCons a l) n)
= HIndex x (HCons a l) n

class HIndex' f x l n | f x l - n

instance HLen l n = HIndex' HTrue x l n
instance HIndex x l n = HIndex' HFalse x (HCons a l) n

-- Length of a list
class Nat n = HLen l n | l - n
instance HLen HNil Z
instance HLen l n = HLen (HCons a l) (S n)



-- Analyze a type

-- Result of the type analysis
data TAtomic a
data TVariable a
data TFunction a b
data TConstructed c  a 

-- only one level: kind * - *
data TAtomic1 a
data TVariable1 a

data Level1 a

data W a = W a

-- We can have more levels, cf Typeable2, etc.

class Analyze a b | a - b
analyze:: Analyze a b = a - b
analyze = undefined

instance TypeCast f (TAtomic Int)  = Analyze Int f
instance TypeCast f (TAtomic Bool) = Analyze Bool f
instance TypeCast f (TAtomic Char) = Analyze Char f

instance TypeCast f (TAtomic Int)  = Analyze (W Int) f
instance TypeCast f (TAtomic Bool) = Analyze (W Bool) f
instance TypeCast f (TAtomic Char) = Analyze (W Char) f

instance (Analyze (c x) rx, Analyze (d y) ry, TypeCast f (TFunction rx ry)) 
= Analyze (c x-d y) f

instance (Analyze (W x) rx, Analyze (d y) ry, TypeCast f (TFunction rx ry)) 
= Analyze (x-d y) f

instance (Analyze (c x) rx, Analyze (W y) ry, TypeCast f (TFunction rx ry)) 
= Analyze (c x-y) f

instance (Analyze (W x) rx, Analyze 

  1   2   >