Re: [Haskell-cafe] closed classes [was: Re: exceptions vs. Either]
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
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
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
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
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 ?
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
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