Re: [Haskell-cafe] closed classes [was: Re: exceptions vs. Either]

2004-08-12 Thread André Pang
On 12/08/2004, at 11:05 PM, Simon Peyton-Jones wrote:
module M where
class C a where
   op :: a - a
instance C Int where
   op x = x+1
f x = Just (op x)
Under your proposal, I'd infer f :: Int - Maybe Int, on the grounds
that C is closed and there is only one instance.
If I'm reading Keean's posts right, that's exactly his point: if you 
only have one instance of class C, then it's valid to improve f's type 
to :: Int - Maybe Int, right?

If, on the other hand, you had another instance (e.g. instance C Bool), 
then the signature of f would have to remain polymorphic.

--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: exceptions vs. Either

2004-08-06 Thread André Pang
On 06/08/2004, at 6:56 PM, MR K P SCHUPKE wrote:
After all, Java basically does exactly what you're asking for with
Java's head/tail would be doing runtime checks if they are throwing 
exceptions,
static guarantees mean the program would not be allowed to compile if 
it broke
the static guarantees.
As Keith said, Java will check at compile time whether or not you 
handle the exception.  My point is this: it is impossible to check 
whether the exception is properly handled.  If you adjust Haskell's 
tail function to return (Maybe [a]) instead of just ([a]), you are 
doing the thing as Java from a pragmatic perspective: you are adding 
information to the type system that tells the programmer the function 
may fail.  You also suffer the same consequence as Java: you have no 
idea whether the programmer properly handles the error situation.

If I am writing a one-shot, never-use-again script that takes 3 minutes 
to write, and I _know_ that I'm not going to be feeding the tail 
function a non-empty list--e.g. because I'm writing a one-shot 
five-minute script to transform a file from one text format to another, 
as is the case for lots of Perl programs--then the extra Maybe type 
just gets in the way.  I'll either ignore the Nothing case, or write 
`case tail foo of ... Nothing - error bleh'.  I will go so far to 
say that such a program can be considered correct: it does exactly 
what I want it to do, in exactly the circumstances I desire (0 byte 
files being specifically excluded from the circumstances!).

Which is a bad thing! All programmers always have to consider error 
conditions,
if they don't they write buggy code - that's the nature of the beast. 
I prefer
making programmers expicitly face the decisions they are making, 
rather than
have things implicitly handled in a way that hides what is going on 
from the
programmer.
It's a question of whether the library designer should impose their 
will on the library user.  As a library designer, do you feel that you 
are always making the right decision for the library user 100% of the 
time?  I know I never feel like that when I write libraries ...

--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: exceptions vs. Either

2004-08-05 Thread André Pang
On 05/08/2004, at 7:40 PM, MR K P SCHUPKE wrote:
I have a hard time understanding why functional programmers would not 
want
more static typing guarantees, after all they can always use C if they
dont like type systems!
Static guarantees are great, but if you have to explicitly change your 
style of coding to cope with those extra constraints, it can become 
(very) cumbersome.

After all, Java basically does exactly what you're asking for with 
head/tail: if you were to write a tail method in a List class, you 
could simply throw a EmptyListException.  That's really the same effect 
as tail in Haskell returning a Maybe: both forms force you to perform 
error-handling in the calling function.  However, I think Java has 
shown that forcing error-handling on the caller via exceptions is no 
magic bullet: a lazy programmer will simply catch the exception in an 
empty catch {} block.  It's a human problem, not a technical one.

Obviously exceptions, Maybes, monads etc. are useful, but forcing the 
programmer to Do The Right Thing is nearly impossible.  I personally 
think that using tricks such as type classes to propagate constraints 
and errors via the type system is a fantastic idea, because then 
end-programmers have to worry much less about handling errors properly.

--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: exceptions vs. Either

2004-08-04 Thread André Pang
On 04/08/2004, at 12:28 AM, MR K P SCHUPKE wrote:
f (case xs of (x:_) - x; [] - error whoops)  -- direct style
Yup, this is how I do it... I never use head!
I like to pass failures back up to the level where some kind of 
sensible
error message can be generated. In your example the error is no
better than with 'head' - the point is a Nothing can be 'caught'
outside of an IO monad.

I would suggest using the type system as I said earlier so:
toNonEmptyList :: [a] - Maybe (NonEmpty a)
toNonEmptyList (a0:_) = Just (NonEmpty a)
toNonEmptyList _ = Nothing
Then redefine head:
head :: NonEmpty a - a
head (NonEmpty (a0:_)) = a0
There's an interesting discussion going on at Lambda the Ultimate right 
now, about this very topic:

http://lambda-the-ultimate.org/node/view/157#comment
There are plenty of noteworthy comments there, but one which quite 
nicely expresses my point of view is:

Using Maybe for this is like saying - let's turn this partial 
function into a total one by lifting its range to include Nothing. It 
became total by obtaining permission to return something I have no use 
of. I do not say monads are not useful, or Maybe is not useful.

And, of course, there's the type wizardry post by Oleg:
http://lambda-the-ultimate.org/node/view/157#comment-1043
I'd like to point out that it is possible in Haskell98 to write 
non-trivial list-processing programs that are statically assured of 
never throwing a `null list' exception. That is, tail and head are 
guaranteed by the type system to be applied only to non-empty lists. 
Again, the guarantee is static, and it is available in Haskell98. 
Because of that guarantee, one may use implementations of head and tail 
that don't do any checks. Therefore, it is possible to achieve both 
safety and efficiency. Please see the second half of the following 
message:

http://www.haskell.org/pipermail/haskell/2004-June/014271.html
--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: optimising for vector units

2004-07-26 Thread André Pang
On 26/07/2004, at 10:49 AM, Ben Lippmeier wrote:
... though it would be nice to be able to define
a + b :: (Float, Float, Float, Float) - (Float, Float, Float, Float) 
- (Float, Float, Float, Float)

and expect it to go via SSE..
I believe it would be possible to do this with associated types:
http://www.cse.unsw.edu.au/~chak/papers/CKPM04.html
... whenever they decide to appear in GHC :).
--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: so how does one convert an IO a into an a ?

2004-07-08 Thread André Pang
On 09/07/2004, at 4:50 AM, Crypt Master wrote:
One person mentioned how random just returns an interative program  
which when eveluated returns the Int. Also from the school of  
expression book he says  The right way to think of (=) above is  
simply this: It Executes e1 ... in relation to do pat - e1 

so I have this:
code
rollDice :: IO Int
rollDice = getStdRandom (randomR (1,6))
rl :: [Int]
rl = [ (getRndNum x) | x - [1..] ]
getRndNum :: Int - Int
getRndNum x = do n - rollDice
  return n
/code  *PS Pretend return is correctly aligned under n. dont what  
ahppens in copy and paste*
Other people have covered a lot about IO, but for your particular  
problem of random numbers, here's a reasonably simple solution:

module RandomList where
import Random
seed :: Int
seed = 69
randomList :: [Int]
randomList = randomRs (1,6) (mkStdGen seed)
Usage:
RandomList :t randomList
randomList :: [Int]
RandomList take 10 randomList
[6,2,6,2,6,2,1,3,2,3]
RandomList
The key to figuring out how on earth to use the combinations of  
randomRs and generators is having good documentation on the Random  
module, which I found here:

 
http://www.haskell.org/ghc/docs/latest/html/libraries/base/ 
System.Random.html#t%3ARandom

I'm guessing you're using hugs, which does give you the Random module,  
but it's not exactly easy to figure out from reading the source code  
(especially if you're a Haskell beginner)!

--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] RE: Modelling Java Interfaces with Existential data types

2004-06-09 Thread André Pang
On 10/06/2004, at 3:29 AM, Mike Aizatsky wrote:
thanks for your time to look into the HList paper.
It's quite good. It reminds me the quirks Alexandrescu does in his 
Modern
C++ Design or here
http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html 
.
Since type system allows implementation of natural arithmetic, do you 
know,
is it Turing-complete?
I don't know whether it's Turing complete, but if you're more 
interested in how to (ab?)use type classes to perform computations, see 
a paper named Fun with Functional Dependencies:

http://www.cs.chalmers.se/~hallgren/Papers/wm01.html
That shows how you use multi-parameter type classes and functional 
dependencies to create full functions in the type system.  Once you 
understand that, you might be able to wrap your head around this 
example:

http://www.haskell.org/hawiki/SimulatingDependentTypes
which shows how to create an AVL tree data type, with which it is 
impossible write a function that can unbalance the tree.

There is also a very interesting paper posted to the main Haskell 
mailing list only a few days ago:

http://www.eecs.harvard.edu/~ccshan/prepose/
which shows (amongst other things) how to reify _any_ value to a type, 
i.e. create a new type which represents that (and only that) particular 
value in the type system, and how to round-trip that unique type back 
to the value it originally came from.  I'm not sure if you're 
interested in type wizardry, but it shows a very impressive amount of 
static computation that you can do with the type system at 
compile-time.

The only issue is to get rid of AnyMyInterface around the code. Can you
explain me why
Hmm, what's the higher goal of what you're trying to achieve?  I, like 
you, came from a background of object-oriented programming, and I've 
always managed to avoid making a list containing more than one type 
after re-thinking about the problem.  You can do it, sure, but the 
typical reasons for doing so in Haskell are very different from doing 
this in, say, Java.

--
% Andre Pang : trust.in.love.to.save
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe