[Haskell-cafe] head as a total function

2006-09-07 Thread oleg

Jo'n Fairbairn wrote in response to Neil Mitchell:
  And as you go on to say, if you apply it to the infinite
  list, who cares if you used head. Head is only unsafe on
  an empty list. So the problem then becomes can you detect
  unsafe calls to head and let the programmer know.

 No, that's the wrong approach because it relies on detecting
 something that (a) the programmer probably knows already and
 (b) is undecidable in general. It would be far better for
 the programmer to express this knowledge in the
 programme.

It is indeed possible -- and quite easy -- to write programs where
head and tail are total functions. That issue was discussed, for
example, at the end of an old message:

Exceptions in types and exception-free programming
http://www.haskell.org/pipermail/haskell/2004-June/014271.html

The first two thirds of the message showed how to make exceptions
apparent in the signature of a function, so we can see if a function
could potentially raise the `head of an empty list' exception just by
looking at its (inferred) type.


The exception-free programming is far more rewarding, and practical as
well. We don't actually need to introduce subtyping; explicit
injection/projections don't seem to be as much of (syntactic)
overhead. There is absolutely no runtime overhead! The non-empty lists
have exactly the same run-time representation as the regular
lists. The technique generalizes to arrays, even numbers, sorted lists
(and, seemingly, to strings that are safe to include into HTML/SQL
documents).


That technique has been mentioned several times recently (perhaps not
on this forum). Quite complex algorithms like Knuth-Morris-Pratt
string search (with mutable arrays, packed strings, general recursion
and creative index expressions) can be handled. Again, without
introducing any runtime overhead:

http://pobox.com/~oleg/ftp/Haskell/KMP-deptype.hs

The approach is formalizable; the recent PLPV talk by Chung-chieh Shan
presented the types systems and the proof techniques. Some of the
proofs have been formalized in Twelf:

http://pobox.com/~oleg/ftp/Computation/lightweight-dependent-typing.html#Formalization

In short, the safety property (absence of `head of an empty list'
exception) is a corollary to the Progress theorem, for a type system
with dependent-type flavor. The type system doesn't actually have
dependent types. Furthermore, whatever dependent-type flavor there
is, it can be erased while maintaining the safety guarantees, given
some precisely stated conditions on the safety kernel.

P.S. Algol68 was my favorite language too.

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


Re[2]: [Haskell-cafe] Reading integers

2006-09-07 Thread Bulat Ziganshin
Hello Neil,

Thursday, September 7, 2006, 1:45:03 AM, you wrote:

 Currently I have a single module that provides reading operations
 for Integers and Ints. I'm not quite sure what to do with it.

 Get it into base!  Where it is, or what its called is less relevant -
 perhaps entirely decoupled from the Read class, and I wouldn't have
 thought reading octal integers etc was useful - just simple bog
 standard integers. I'd really like just readInt/readInteger in
 Numeric, or Prelude, or possibly even a new Read style module.

i'd just defined the following function, mainly because standard
'read' machinery occupies whole 50 kb in exe-file

readI = foldl f 0
  where f m c | isDigit c  =  fromIntegral (ord c - ord '0') + (m * 10)
  | otherwise  =  error (Non-digit ++[c]++ in readI)



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: [Haskell-cafe] head as a total function

2006-09-07 Thread Bulat Ziganshin
Hello oleg,

Thursday, September 7, 2006, 10:28:00 AM, you wrote:

 P.S. Algol68 was my favorite language too.

+1 :)

it was the first imperative language supporting closures, after all



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: [Haskell-cafe] how do you debug programs?

2006-09-07 Thread Tamas K Papp
On Wed, Sep 06, 2006 at 11:34:05AM +0200, Pepe Iborra wrote:
 Hi Tamas
 
 There are several ways to debug a Haskell program.
 
 The most advanced ones are based in offline analysis of traces, I
 think Hat [1] is the most up-to-date tool for this. There is a Windows
 port of Hat at [5].
 
 Another approach is to simply use Debug.Trace. A more powerful
 alternative for this approach is Hood [2]. Even if it hasn't been
 updated in some time, Hood works perfectly with the current ghc
 distribution. Even more, Hugs has it already integrated [3]. You can
 simply import Observe and use observations directly in your program.

Dear Pepe,

Thank you for the information.  I finally ended up working with
Debug.Trace, and found the bug very quickly.  I also tried Hood, but
couldn't load it in ghci: import Observe can't find the library, but

% locate Observe
/usr/lib/ghc-6.4.2/hslibs-imports/util/Observe.hi
/usr/lib/ghc-6.4.2/hslibs-imports/util/Observe.p_hi
/usr/lib/hugs/libraries/Hugs/Observe.hs
/usr/lib/hugs/oldlib/Observe.hs

Does importing from hslibs-imports require something special?

Quite a bit of philosophical discussion erupted as a result of my
original question.  I understand the arguments of those who dislike
debuggers, but I don't think I could have done without some debugging.

It turns out that the problem was not in the algorithm, but in the
specification of the equation itself.  I was solving a continuous time
Hamilton-Jacobi-Bellman equation, and there was a point in the state
space where the supremum was infinity, giving stuff like 0/Inf and
their ilk.  I respecified the problem and now it works.

For those who think that it is always possible to break the problem up
into small pieces you can test individually (without a debugger): you
can't, at least not when solving functional equations.  The corner
cases (and nonconvergence, when using non-contraction methods, such as
PEA) are difficult to catch and reproduce.

Thanks for all the suggestions,

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


Re: [Haskell-cafe] NaN, Infinity literals

2006-09-07 Thread Chris Kuklewicz
You want the RealFloat class functions: 
http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3ARealFloat


Tamas K Papp wrote:

Hi,

Is there a way to use NaN and Infinity as literals, or at least to
test if a value is NaN or Infinity?

I tried

*Main let nan=0/0
*Main nan
NaN
*Main nan==0/0
False

so storing the value does not work...

Thanks,

Tamas
___
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] NaN, Infinity literals

2006-09-07 Thread Bertram Felgenhauer
Hi,

Tamas K Papp wrote:
 Is there a way to use NaN and Infinity as literals, or at least to
 test if a value is NaN or Infinity?

 *Main let nan=0/0
 *Main nan
 NaN
 *Main nan==0/0
 False

This is correct according to the IEEE 754 standard, which defines
that NaN compares unequal to everything, including itself.

You can test the numbers using the isNaN and isInfinite functions.

Incidentally, one can define

  isNaN x = x /= x

for IEEE floating point numbers. Comparing with +Infinity and
-Infinity works as expected.

regards,

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


Re: [Haskell-cafe] NaN, Infinity literals

2006-09-07 Thread Udo Stenzel
Tamas K Papp wrote:
 Is there a way to use NaN and Infinity as literals, or at least to
 test if a value is NaN or Infinity?
 
 *Main let nan=0/0
 *Main nan
 NaN
 *Main nan==0/0
 False
 
 so storing the value does not work...

Not sure what you mean here.  In IEEE floating point, NaN is not equal
to anything, especially not to itself.  So the above worked, didn't it?
And therefore,

isNaN :: Double - Bool
isNaN x = not (x == x)

but this is wrong (I believe):

isNaN' :: Double - Bool
isNaN' x = x /= x

Anyway, isNaN is alerady in the Prelude, and so are isInfinite,
isDenormalized and isNegativeZero.

This is all a bit ill-defined, but you'll have to live with that.  If
you also want a personal advise: switch on signaling NaNs (there's a C
function to do that, simply foreign import it) and have your program
bomb out as soon as a NaN is formed.  Propagating them through
calculations just increases the headache.


Udo.
-- 
FORTUNE PROVIDES QUESTIONS FOR THE GREAT ANSWERS: #4
A:  Go west, young man, go west!
Q:  What do wabbits do when they get tiwed of wunning awound?


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


Re: [Haskell-cafe] Monad laws

2006-09-07 Thread Brian Hulley

Deokhwan Kim wrote:

What is the practical meaning of monad laws?

(M, return, =) is not qualified as a category-theoretical monad, if
the following laws are not satisfied:

 1. (return x) = f == f x
 2. m = return == m
 3. (m = f) = g == m  (\x - f x = g)

But what practical problems can unsatisfying them cause? In other
words, I wonder if declaring a instance of the Monad class but not
checking it for monad laws may cause any problems, except for not
being qualified as a theoretical monad?


Afaiu the monad laws are needed so the compiler can do various 
optimizations, especially in regard to the do notation. Consider:


   g c = do
   if c
   then p
   else return ()
   q

Intuitively, the else branch of the if statement does nothing 
interesting, but we need to put something there because we can't just leave 
the branch empty, hence the use of (return ()), but thankfully, because of 
the monad laws, the compiler can apply transformations to get rid of it when 
it desugars the do notation.


The above is equivalent to:

   g c = (if c then p else return ()) = (\_ - q)

which could be re-written as:

   g c = if c then (p = (\_ - q)) else (return () = (\_ - q))

which can be optimized using monad law 1) to:

   g c = if c then (p = (\_ - q)) else (\_ - q) ()

which can further be optimized to:

   g c = if c then (p = (\_ - q)) else q

so when the condition (c) is False we don't waste time doing the (return ()) 
action, but go straight to (q).


However if your monad didn't satisfy the laws, the compiler would still 
assume that it did thus leading to a flawed optimization ie the compiler 
would throw your program away and substitute it for a different, unrelated, 
program...


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


Re: Re[2]: [Haskell-cafe] Reading integers

2006-09-07 Thread Lennart Augustsson

What about negative numbers?

Also, don't use (ord c - ord '0'), it doesn't work with Unicode digits.
That's why there is a digitToInt function.

-- Lennart

On Sep 7, 2006, at 02:12 , Bulat Ziganshin wrote:


readI = foldl f 0
  where f m c | isDigit c  =  fromIntegral (ord c - ord '0') + (m *  
10)

  | otherwise  =  error (Non-digit ++[c]++ in readI)


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


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-07 Thread Claus Reinke

 thinking helps, but claiming that tools can't help doesn't.


Lets be absolutely clear about this: I've never claimed that
tools can't help. In this thread I've been using the term
debugger in the narrow sense implied by the OP's question --
something that steps through the execution of the code. Such
a debugger is inappropriate for Haskell programmers, and
doubly so for beginners.


well, then it is clear that we disagree on this. imho, being 
able to step through reductions is very appropriate for all
functional programmers (**), and an essential exercise 
for beginners. 

and if that is true for tiny examples on paper, then there 
should be tool support for applying it to larger programs.


from experience with the PI-RED systems, there are few
cases where one can apply such a tool without thinking
(eg. let it run till it gets stuck on an error, go a few steps
back to see where that erroneous part was constructed;
or let it run for a large number of steps, then check why
and where the program it is still growing instead of 
terminating). (*) 


after the initial learning phase, where such a stepper helps
to form the student's mental model of program evaluation,
the majority of debugging cases need to combine thinking
with experimentation, but dropping either of these two
ingredients makes the problem much harder. 

and it is nice to be able to do the experiments without 
having to switch tools or mindsets (although there are 
many ways in which the old PI-RED systems could have 
been improved, not to mention lessons learned from 
other tools, like Hat, that were developed for Haskell 
because there were no reduction systems for it).


claus

(*) note that the programmer never saw thunks, or 
   stacks, let alone heap objects or abstract machine
   code, only high-level program text, transformed by 
   reductions. intermediate programs were fully editable,
   in no way distinguished from the original programs 
   entered by the programmer, so one could make some 
   local observations, changes and reductions, then 
   continue with the overall reduction, or return to the 
   original program. compilation, decompilation, and 
   presentation were implicit, under the hood.


   for the PI-RED developers, though, there were 
   *separate* debugging tools that would allow them 
   to inspect the abstract machine's stack, heap, etc.. 
   and only if those failed to indicate the problem, 
   would they have to resort to C-level debugging 
   tools, another level lower.


(**) in fact, Berkling used to argue that was true for 
   all declarative programmers, and he extended his 
   ideas and machines to functional logic languages


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


Re: [Haskell-cafe] Monad laws

2006-09-07 Thread Lennart Augustsson

Brian,

Are you really sure Haskell compilers do that optimization?
I would regard a compiler that does optimizations that are justified  
by laws that the compiler cannot check as broken.


-- Lennart

On Sep 7, 2006, at 08:50 , Brian Hulley wrote:


Deokhwan Kim wrote:

What is the practical meaning of monad laws?

(M, return, =) is not qualified as a category-theoretical monad, if
the following laws are not satisfied:

 1. (return x) = f == f x
 2. m = return == m
 3. (m = f) = g == m  (\x - f x = g)

But what practical problems can unsatisfying them cause? In other
words, I wonder if declaring a instance of the Monad class but not
checking it for monad laws may cause any problems, except for not
being qualified as a theoretical monad?


Afaiu the monad laws are needed so the compiler can do various  
optimizations, especially in regard to the do notation. Consider:


   g c = do
   if c
   then p
   else return ()
   q

Intuitively, the else branch of the if statement does nothing  
interesting, but we need to put something there because we can't  
just leave the branch empty, hence the use of (return ()), but  
thankfully, because of the monad laws, the compiler can apply  
transformations to get rid of it when it desugars the do notation.


The above is equivalent to:

   g c = (if c then p else return ()) = (\_ - q)

which could be re-written as:

   g c = if c then (p = (\_ - q)) else (return () = (\_ - q))

which can be optimized using monad law 1) to:

   g c = if c then (p = (\_ - q)) else (\_ - q) ()

which can further be optimized to:

   g c = if c then (p = (\_ - q)) else q

so when the condition (c) is False we don't waste time doing the  
(return ()) action, but go straight to (q).


However if your monad didn't satisfy the laws, the compiler would  
still assume that it did thus leading to a flawed optimization ie  
the compiler would throw your program away and substitute it for a  
different, unrelated, program...


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.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] Monad laws

2006-09-07 Thread Robert Dockins


On Sep 7, 2006, at 9:04 AM, Lennart Augustsson wrote:


Brian,

Are you really sure Haskell compilers do that optimization?
I would regard a compiler that does optimizations that are  
justified by laws that the compiler cannot check as broken.


What, like list fusion?

;-)

Although, more seriously, there are a number of monads in the  
standard libs that don't follow the monad laws (including IO http:// 
article.gmane.org/gmane.comp.lang.haskell.general/5273  !!).


I can't imagine that any haskell compilers rely on these laws to do  
program transformations.




-- Lennart

On Sep 7, 2006, at 08:50 , Brian Hulley wrote:


Deokhwan Kim wrote:

What is the practical meaning of monad laws?

(M, return, =) is not qualified as a category-theoretical  
monad, if

the following laws are not satisfied:

 1. (return x) = f == f x
 2. m = return == m
 3. (m = f) = g == m  (\x - f x = g)

But what practical problems can unsatisfying them cause? In other
words, I wonder if declaring a instance of the Monad class but not
checking it for monad laws may cause any problems, except for not
being qualified as a theoretical monad?


Afaiu the monad laws are needed so the compiler can do various  
optimizations, especially in regard to the do notation. Consider:


   g c = do
   if c
   then p
   else return ()
   q

Intuitively, the else branch of the if statement does nothing  
interesting, but we need to put something there because we can't  
just leave the branch empty, hence the use of (return ()), but  
thankfully, because of the monad laws, the compiler can apply  
transformations to get rid of it when it desugars the do notation.


The above is equivalent to:

   g c = (if c then p else return ()) = (\_ - q)

which could be re-written as:

   g c = if c then (p = (\_ - q)) else (return () = (\_ - q))

which can be optimized using monad law 1) to:

   g c = if c then (p = (\_ - q)) else (\_ - q) ()

which can further be optimized to:

   g c = if c then (p = (\_ - q)) else q

so when the condition (c) is False we don't waste time doing the  
(return ()) action, but go straight to (q).


However if your monad didn't satisfy the laws, the compiler would  
still assume that it did thus leading to a flawed optimization  
ie the compiler would throw your program away and substitute it  
for a different, unrelated, program...


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com




Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
  -- TMBG



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


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-07 Thread David Roundy
On Thu, Sep 07, 2006 at 06:21:01AM +0100, Jn Fairbairn wrote:
 David Roundy [EMAIL PROTECTED] writes:
 
  On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:
   Or maybe even more extreme you could use template haskell or the c
   preprocessor to fill in the line number + column.
  
  Which is precisely what darcs does for fromJust (which we use a lot):
  we define a C preprocessor macro fromJust. 
 
 Curiously, the only bug in darcs that has bitten me so far
 was a use of fromJust.  Perhaps that indicates a weakness in
 the style, rather than the tools?

Yeah, in general fromJust is a dangerous business, and most of the
uses of it in darcs can lead to trouble for partial repositories, for
instance.  I was just yesterday discussing with Jason the possibility
of switching away from a Maybe approach for lazily reading patches.
-- 
David Roundy
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Reading integers

2006-09-07 Thread Bertram Felgenhauer
Lennart Augustsson wrote:
 Also, don't use (ord c - ord '0'), it doesn't work with Unicode digits.
 That's why there is a digitToInt function.

FWIW, in Haskell 98, isDigit and digitToInt are defined as

isDigit c=  c = '0'  c = '9'

digitToInt :: Char - Int
digitToInt c
  | isDigit c=  fromEnum c - fromEnum '0'
  | c = 'a'  c = 'f' =  fromEnum c - fromEnum 'a' + 10
  | c = 'A'  c = 'F' =  fromEnum c - fromEnum 'A' + 10
  | otherwise=  error Char.digitToInt: not a digit

making this a bit of a red herring. I can't comment on why Bulat doesn't
like negative numbers.

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


Re: [Haskell-cafe] how do you debug programs?

2006-09-07 Thread Pepe Iborra


On 07/09/2006, at 10:53, Tamas K Papp wrote:



Dear Pepe,

Thank you for the information.  I finally ended up working with
Debug.Trace, and found the bug very quickly.  I also tried Hood, but
couldn't load it in ghci: import Observe can't find the library, but

% locate Observe
/usr/lib/ghc-6.4.2/hslibs-imports/util/Observe.hi
/usr/lib/ghc-6.4.2/hslibs-imports/util/Observe.p_hi
/usr/lib/hugs/libraries/Hugs/Observe.hs
/usr/lib/hugs/oldlib/Observe.hs

Does importing from hslibs-imports require something special?


Hi Tamas

I'm glad to hear that you fixed it!

GHC includes Observe (the hs-libs-imports file you are seeing) only  
in the hidden 'util' package, which I believe is deprecated or not  
present in 6.6. If you want to use it, launch ghci with the flag '- 
package util'.
Or download Observe.hs from the Hood website and place it somewhere  
in the path.


Hmm, it would be handy to have a Cabal Hood package...

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


Re: [Haskell-cafe] Monad laws

2006-09-07 Thread Brian Hulley

Lennart Augustsson wrote:

On Sep 7, 2006, at 08:50 , Brian Hulley wrote:

Deokhwan Kim wrote:

What is the practical meaning of monad laws?

Afaiu the monad laws are needed so the compiler can do various
optimizations, especially in regard to the do notation. Consider:

   g c = do
   if c
   then p
   else return ()
   q

which can further be optimized to:

   g c = if c then (p = (\_ - q)) else q


Brian,

Are you really sure Haskell compilers do that optimization?
I would regard a compiler that does optimizations that are justified
by laws that the compiler cannot check as broken.


I think at least GHC does, if I understand the -ddump-simpl output below 
properly:


   -- in Monad.hs
   module Main where

   import Control.Monad

   test :: Bool - IO ()
   test c = do
if c
 then putStr True
 else return ()
putStrLn Finish

   main = test False

ghc --make -O2 -ddump-simpl monad

gives:

 Tidy Core 
Main.s :: GHC.Base.String
[GlobalId]
[Str: DmdType]
Main.s = GHC.Base.unpackCString# Finish

Main.main :: GHC.IOBase.IO ()
[GlobalId]
[Arity 1
Str: DmdType L]

Main.main = \ (eta_a26L :: GHC.Prim.State# GHC.Prim.RealWorld) -
  case (# GHC.Prim.State# GHC.Prim.RealWorld, () #) GHC.IO.hPutStr
 GHC.Handle.stdout Main.s eta_a26L
  of wild_a26O { (# new_s_a26M, a85_a26N #) -
  System.IO.lvl1 new_s_a26M
  }

Main.s1 :: GHC.Base.String
[GlobalId]
[Str: DmdType]
Main.s1 = GHC.Base.unpackCString# True

Main.test :: GHC.Base.Bool - GHC.IOBase.IO ()
[GlobalId]
[Arity 2
Str: DmdType SL]
Main.test = \ (c_a19p :: GHC.Base.Bool)
  (eta_s27s :: GHC.Prim.State# GHC.Prim.RealWorld) -
  case (# GHC.Prim.State# GHC.Prim.RealWorld, () #) c_a19p of wild_B1 {
 GHC.Base.False - Main.main eta_s27s;
 GHC.Base.True -
   case (# GHC.Prim.State# GHC.Prim.RealWorld, () #) GHC.IO.hPutStr
 GHC.Handle.stdout Main.s1 eta_s27s
   of wild1_a27o { (# new_s_a27m, a85_a27n #) -
   Main.main new_s_a27m
   }
  }

So when the condition in Main.test is False, the compiler immediately 
executes Main.main eta_s27s which does the putStr Finish directly, so the 
return () has been optimized out.


Whether this is because ghc has used the monad laws, or has applied some 
different optimization due to it's knowledge of the built-in IO monad etc I 
don't know.


Even if the compiler is not itself making use of the laws, other parts of 
standard library code might be, and their correctness would therefore also 
depend on something which the compiler can't verify.


It seems a pity that having gone to the trouble of ensuring a monad obeys 
the laws, the compiler can't make use of them. What then *is* the point of 
the monad laws?


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


[Haskell-cafe] Re: Monad laws

2006-09-07 Thread Stefan Monnier
 Are you really sure Haskell compilers do that optimization?
 I would regard a compiler that does optimizations that are justified  by
 laws that the compiler cannot check as broken.

You mean like the non-aliasing law in Fortran?


Stefan ;-)

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


Re[4]: [Haskell-cafe] Reading integers

2006-09-07 Thread Bulat Ziganshin
Hello Bertram,

Thursday, September 7, 2006, 6:01:17 PM, you wrote:

 Also, don't use (ord c - ord '0'), it doesn't work with Unicode digits.
 That's why there is a digitToInt function.

 making this a bit of a red herring. I can't comment on why Bulat doesn't
 like negative numbers.

because my program can't split files into chunks of -10 files or -1 mbytes ;)


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


Re: [Haskell-cafe] head as a total function

2006-09-07 Thread Bill Wood
On Thu, 2006-09-07 at 11:03 +0400, Bulat Ziganshin wrote:
   . . .
 it was the first imperative language supporting closures, after all

Uh, what about lisp?  The (MIT) lisp 1.4 manual (ca. 1965) refers to
FUNCTION differing from QUOTE in that it handled free variables
correctly; I take this to mean that at least a primitive form of
closure was provided.  Moreover, a language that provides SET/SETQ,
RPLACA/RPLACD and the PROG feature (including labels and a goto) surely
qualifies as imperative?

 -- Bill Wood


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


Re: [Haskell-cafe] Reading integers

2006-09-07 Thread Bertram Felgenhauer
Hi,

I've implemented replacements for readsPrec for Int and Integer in
a module called Compat (in my darcs repository [1]) and measured
their performance.

There's some overhead when compared to the plain versions.
For Integer, it's about 30% for single digit numbers, going down
to about 10% at 10 digits, and about 1.3% at 100.

It's still a big win over the existing instances at a small loss
in compatibility to Haskell 98. As far as I can make out, the only
difference is that it fails to diverge in some cases where reads
would diverge (see my initial mail for an example.)


I've also received a question from Ketil Malde off list, asking
(in reply to Neil Mitchell) what the advantages would be of having
this in base.

Personally I think it should go into base if we can agree on replacing
existing code (the Read instances or something in Numeric or maybe both).
This would have the advantage of making quite a few programs more
efficient just by recompiling them.

If we can't agree on that, the code will be made available as an extra
module but I wouldn't see any advantage at having it in base. Having
it distributed with ghc would have some advantages (mainly convenience
for users and a slightly better chance of avoiding forks).


In other news, darcs send will now send the patches to me - in case
anyone has any.

regards,

Bertram

[1] I'll say again that browsing directly doesn't work, darcs is fine
though, get the code with
darcs get http://int-e.home.tlink.de/haskell/readinteger
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Re[2]: [Haskell-cafe] Reading integers

2006-09-07 Thread Brian Hulley

Bertram Felgenhauer wrote:

I can't comment on why Bulat doesn't like negative numbers.


Neither it seems, did the original Haskell committee - that's why we have to 
muddle along with a confusing unary minus operator instead of proper 
negative literals - see the thread beginning 
http://www.haskell.org/pipermail/haskell-cafe/2006-August/017410.html for 
the latest exciting attempt to get rid of unary minus... ;-)


Regards, Brian.
--
Man simply could not have the right interest in beauty
 if in his life of soul he were not entangled in a world
of hideously ugly spider-like beings. - Rudolf Steiner 16/12/1922

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


Re: [Haskell-cafe] head as a total function

2006-09-07 Thread Jared Updike

 it was the first imperative language supporting closures, after all

Uh, what about lisp?


For those who read the Foozles slides posted earlier [0], I must say
he nailed this one, on slide 2.


The (MIT) lisp 1.4 manual (ca. 1965) refers to
FUNCTION differing from QUOTE in that it handled free variables
correctly; I take this to mean that at least a primitive form of
closure was provided.


Steele's work on Scheme helped Lisp programmers take lexical scoping
seriously [1]; these ideas and a method for efficient implementation
were attributed to Algol [2]. That lexical scope was available in some
dialect of Lisp, even very early on, doesn't surprise me (and
according to [3] is the case). But I do think dynamic scoping took a
while to die out as generally accepted Lisp practice (it does still
exist in Common LISP, with a special keyword, IIRC) and that Scheme
(late 1970s) helped to effect that.


Moreover, a language that provides SET/SETQ,
RPLACA/RPLACD and the PROG feature (including labels and a goto) surely
qualifies as imperative?


Haskell has been called the best imperative programming language ever.
:-) I mean, Haskell has IORef and friends, right?

 Jared.

[0] http://hope.cs.rice.edu/twiki/pub/WG211/M3Schedule/foozles.pdf
[1] Tenth paragraph, this page: http://www.lisp.org/table/Lisp-History.html
[2] Steele's Rabbit compiler paper, p.13. See also Steele's Lambda papers
[3] Steele and Gabriel, Evolution of Lisp.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] map (-2) [1..5]

2006-09-07 Thread Cale Gibbard

On 17/08/06, Brian Hulley [EMAIL PROTECTED] wrote:

Jared Updike wrote:
 In other words, superscripts bind tighter than prefix ops but prefix
 ops bind tighter than infix.

 I see. My point is that there already exists a convention[1] that the
 way to type in
2
-4
 is -4^2 which means -(4^2) not (-4)^2 because - as a prefix op has the
 same precedence as binary subtraction, not super tight like normal
 prefix ops (i.e. normal function application) as you would like it to
 be (if I understand correctly). You are welcome to break an existing
 (unofficial) convention for the sake of lexical syntax[2].
 [2] http://wadler.blogspot.com/2006/01/bikeshed-coloring.html

This choice of precedence for unary - conflicts with the normal usage in
languages like C, where unary ops obviously bind tighter than infix.

The typesetting in maths conveys a lot of info eg to distinguish f -x from
f - x or f-x, and so the relationship between the visual representation and
the meaning depends on a knowledge of various conventions that have evolved
over time, and the knowledge of when to apply them in a given context.

In contrast, a programming language should be based on general concepts
uniformly applied. In Haskell we have operators, identifiers, prefix
application using an identifier and infix application using a symbol, and a
uniform way to convert a symbol to an identifier and vice versa, and a
uniform way of forming sections.

All this machinery should be enough to be satisfied with. However, someone
somewhere decided that one trivial arithmetic operation, namely unary minus,
should be allowed to totally ruin everything, and not only that, but that
half of any number line, the positives, should (literally!) have a special
advantage over the other half, the negatives.

Thus while I can agree with Wadler that it's easy to have different opinions
on little issues, I think that in this case the goal of uniformity leads
to an objective answer.

Of course not all languages care about being uniform or neat ;-)

Best regards, Brian.


First, f - x, f -x, and f-x all tend to mean the same thing in
mathematics, though f -x would be considered poorly typeset (and, to
some degree, they're all poorly typeset, because we're using hyphens
rather than the minus symbol, which really don't look the same). We
tend to write f(-x) when applying a function f to the negation of x,
even in circumstances when application is normally written without
parentheses.

Secondly, I think it's quite a reasonable thing to do to treat unary
negation as a separate operation. It follows quite naturally to do so
from the definition of a ring. While having separate literals for
negative numbers might be okay, it seems unnecessary in light of the
fact that we *do* want a nice looking unary negation symbol, which
doesn't strictly apply to literals. If -x suddenly became a
non-expression, and I had to write 0-x, -1*x or (negate x) instead,
I'd consider that a severe enough bug that I would avoid upgrading my
compiler until it was fixed.

In mathematics, we don't use separate symbols for negative integers,
and negated positive integers, even though in the underlying
representation of the integers as equivalence classes of pairs of
naturals, we can write things like -[(1,0)] = [(0,1)], which expressed
in ordinary notation just says that -1 = -1. This doesn't bother us,
because the two things are always equal.

Another thing to note is that all the natural literals are not, as one
might initially think, plain values, but actually represent the
embedding of that natural number into the ring (instance of Num), by
way of 0 and 1. They simply provide a convenient notation for getting
particular values of many rings, but in many cases, don't get one very
far at all before other functions must be introduced to construct the
constant values one wants. While there always is a homomorphism from Z
to a ring (represented in Haskell by fromInteger), one would get
similar expressiveness by with just the nullary operators 0 and 1, and
the unary negation as well as addition and multiplication (albeit with
an often severe performance hit, and some annoyance, I'm not
recommending we really do this, simply characterising the purpose of
numeric literals).

If the performance issue regarding the polymorphic literal -5 meaning
negate (fromInteger 5) is a problem, it would be easy enough to agree
for the compiler to find and rewrite literals like that as fromInteger
(-5) instead, where -5 is the precomputed integer -5. Assuming that
fromInteger is not broken, that will always mean the same thing
(because fromInteger is supposed to be a homomorphism). Similarly,
when the type of (fromInteger x) is known statically to be Integer,
the compiler can rewrite it as x. In any event, this is a tiny
constant factor performance hit.

Anyway, the point of all this is that 0,1,2... are not really literals
at all. They're nullary operators which give particular elements of
any given 

Re: [Haskell-cafe] Monad laws

2006-09-07 Thread ajb
G'day all.

Quoting Deokhwan Kim [EMAIL PROTECTED]:

 What is the practical meaning of monad laws?

Interesting philosophical question.  There will be an article on
this topic in the next The Monad.Reader, so watch this space.

 But what practical problems can unsatisfying them cause?

Pretty much the same as any practical problems that occur when you
break invariants.  What problems do you cause if you don't maintain
your binary search trees in sorted order, for example?  Basically,
you break anything which depends on the laws.

For example, breaking any of the monad laws implies breaking the
functor laws (exercise: prove this), so fmap breaks.  Monad
transformers may depend on the underlying monad to satisfy the
laws, so you break stacked transformers.  Using non-conforming monads
as Kleisli arrows break the arrow laws.

Any and all of this may result in programs which misbehave.

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


Re[2]: [Haskell-cafe] head as a total function

2006-09-07 Thread Bulat Ziganshin
Hello Bill,

Thursday, September 7, 2006, 8:24:53 PM, you wrote:
 it was the first imperative language supporting closures, after all

 Uh, what about lisp?

Lots of Idiotic Silly Parentheses? :)

well, i say about more or less well-known non-FP languages. actually,
i'm sure that some FBCPL supports closures (or at least anonymous
functions) several years before Algol-68 :)


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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