[Haskell-cafe] Re: socket TChan problem
Hi I think I finally found the problem. I had to replace the call to usleep with a call to threadDelay and it worked. regards Stefan 2006/2/27, Stefan Aeschbacher [EMAIL PROTECTED]: HiI try to write a program that reads from a socket and communicates the result over a TChan and writes it to stdout. Somehow I can't seem to get it right,the result is only printed when I send ETX on the socket. Attached is a sample program that shows the behvaviour.Any hints on where my error is or how I could debug such a problem is appreciated.regardsStefan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: standard poll/select interface
Marcin 'Qrczak' Kowalczyk wrote: Simon Marlow [EMAIL PROTECTED] writes: I think the reason we set O_NONBLOCK is so that we don't have to test with select() before reading, we can just call read(). If you don't use O_NONBLOCK, you need two system calls to read/write instead of one. This probably isn't a big deal, given that we're buffering anyway. I've heard that for Linux sockets select/poll/epoll might say that data is available where it in fact is not (it may be triggered by socket activity which doesn't result in new data). Select/poll/epoll are designed to work primarily with non-blocking I/O. Ah yes, you're right. It's important for us to guarantee that calling read() can't block, so even if we select() first there's a race condition in that someone else can call read() before the current thread. In my implementation of my language pthreads are optionally used in the way very similar to your paper Extending the Haskell Foreign Function Interface with Concurrency. This means that I have a choice of using blocking or non-blocking I/O for a given descriptor, both work similarly, but blocking I/O takes up an OS thread. Each file has a blocking flag kept in its data. That's an interesting idea, and neatly solves the problem of making stdin/stdout/stderr non-blocking, but at the expense of some heavyweight OS-thread blocking. Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] haskell programming guidelines
On 28/02/06, John Meacham [EMAIL PROTECTED] wrote: On Tue, Feb 28, 2006 at 01:09:03AM -0500, Cale Gibbard wrote: Well, the benefit of the Identity monad is so that the user of a routine can choose to recover gracefully by using a different monad, you only use the Identity monad when you are making a choice to bottom out on errors. using 'error' directly is not an option in said cases because it would take away the ability of the user of a routine to catch errors properly. error should only be used for reporting bugs that should never happen, not user visible failure. I'd argue that it would be better for the user to simply catch the value returned which indicates error explicitly, and throw the error themselves. This indicates that they have put thought into the fact that the function may fail. so does using runIdentity, that is the point of it. You are saying I want failure to bottom out, just like using it as a 'Maybe' means you only care about whether it has a result or using it as a 'Either' means you want the result string or using it as a WriterT Foo IO means you want to possibly collect some results and have fail throw an IO exception. I consider it bad style to spend code on cases you never expect to happen, if it takes too much work to write code that fails properly on bugs, people arn't (and definitly should not have to) do the extra work, they will just write code that fails poorly. Monadic failure is absolutely great for writing robust, concise, code. be handled, the user of it should. Right, which is why minimal types for expressing the failure should be used, and the user should convert from those types to whatever larger environment they have in mind. If your function is simply partial, use Maybe, if you want to report error strings, use Either String. These types easily lift into any monad which support similar functionality. It also gives the users of your library more information about the exact way in which your functions may fail, just by looking at the type signatures, and gets them thinking about handling that failure. An arbitrary monad m doesn't indicate anything about the failure modes present. ack! The user of a library is who should get to choose how to deal with the error case, not the library writer. I'd hate to give up such very common idioms as -- collect error messages from all failing parsers [ err | Left err - map parse xs] I don't see how you lose this one at all. -- look up a string transformed by a map in another map, failing if it -- is not in said other map. runIdentity $ Map.lookup (concatMap (`Map.lookup` map) xs) smap Suppose Map.lookup returns something in the Maybe monad. let lookup k m = fromJust $ Map.lookup k m in lookup (map (`lookup` m) xs) sm Not so hard. How about if Map.lookup is prepared to give us a string via the Either String monad and we want to throw an error: let lookup k m = either error id $ Map.lookup k m in lookup (map (`lookup` m) xs) sm If we had a bigger monadic context, it would be just as easy to lift the error up into that. let lookup k m = either (throwError . strMsg) return $ Map.lookup k m in do vs - mapM (`lookup` m) xs lookup vs sm Or finally, if Map.lookup uses the MonadError class, like it probably should: do vs - mapM (`Map.lookup` m) xs Map.lookup vs sm But note that this is *not* the Identity monad we're working in here. It's some MonadError, and as far as I'm concerned, that's quite different. Also, if Map.lookup was equipped to give us symbolic information about the error, we could extend this to that. With fail, all we get is a string. We'd know what's actually available from Map.lookup before we write any of this. It's important to note here that either (throwError . strMsg) return is a useful lifter in its own right, and should probably be extracted and put in the library. but the real power is when you combine monadic failure with combinators and monad transformers -- imagine some complicated function f x xs = runWriterT $ mapM (\x - foofunc x = tell) xs the great thing about this is it is transparent to failure! so you can build arbitrarily complicated transformers while still letting the user of 'f' decide what to do with failure. this is a great feature, if foofunc returned a data type, the writer of 'f' would be forced to deal with failure, and might (likely will) do something silly like call 'error'. I'm not sure I understand your point here. Why would the writer of f be any more forced to deal with failure if foofunc returned a specific type here? In fact, it must be at least typed in WriterT, so I'm not sure what you mean. The code would be identical regardless of whether the transformed monad was fixed or not, and the writer of f doesn't have to do anything. What I'm advocating is not the use of non-monadic case-style failure handling. I'm advocating the use of specific classes and types which
Re: [Haskell-cafe] Re: socket TChan problem
Why do you need to duplicate channels? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] haskell programming guidelines
On Tue, Feb 28, 2006 at 04:52:40AM -0500, Cale Gibbard wrote: -- collect error messages from all failing parsers [ err | Left err - map parse xs] I don't see how you lose this one at all. because somewhere else, you might want to use 'parse' as a maybe. somewhere else, you might want it to throw an IO exception, somewhere else you might want to compose it with some other arbitrary monad and not loose the ability to override the return type. -- look up a string transformed by a map in another map, failing if it -- is not in said other map. runIdentity $ Map.lookup (concatMap (`Map.lookup` map) xs) smap Suppose Map.lookup returns something in the Maybe monad. let lookup k m = fromJust $ Map.lookup k m in lookup (map (`lookup` m) xs) sm and then in 2 months you get a Predule.error: fromJust but moreso, you may define a value like so z = Map.lookup (concatMap (`Map.lookup` map) xs) smap now z can be used for any sort of monad. very handy. The need for partial functions like fromJust are exactly what I don't want to see used anywhere. Not so hard. How about if Map.lookup is prepared to give us a string via the Either String monad and we want to throw an error: let lookup k m = either error id $ Map.lookup k m in lookup (map (`lookup` m) xs) sm exactly, if it is in a monad then you don't have to make this decision, the user of lookup does. let lookup k m = either (throwError . strMsg) return $ Map.lookup k m in do vs - mapM (`lookup` m) xs lookup vs sm now compare that to: mapM (`lookup` m) xs = (`lookup` sm) and that is a relatively simple one. But note that this is *not* the Identity monad we're working in here. It's some MonadError, and as far as I'm concerned, that's quite different. I was never working in the Identity monad either, the routines should work in an _arbitrary_ monad, of which Identity is one of. It's important to note here that either (throwError . strMsg) return is a useful lifter in its own right, and should probably be extracted and put in the library. but the real power is when you combine monadic failure with combinators and monad transformers -- imagine some complicated function f x xs = runWriterT $ mapM (\x - foofunc x = tell) xs the great thing about this is it is transparent to failure! so you can build arbitrarily complicated transformers while still letting the user of 'f' decide what to do with failure. this is a great feature, if foofunc returned a data type, the writer of 'f' would be forced to deal with failure, and might (likely will) do something silly like call 'error'. I'm not sure I understand your point here. Why would the writer of f be any more forced to deal with failure if foofunc returned a specific type here? In fact, it must be at least typed in WriterT, so I'm not sure what you mean. The code would be identical regardless of whether the transformed monad was fixed or not, and the writer of f doesn't have to do anything. indeed. it is identical only because the inner monad can be an arbitrary one. if foofunc returned an error in an algebraic type, then the monad becomes fixed and your function is no longer general. I really don't like it when things fail via 'error'. Then why do you advocate the use of 'fail' which is implemented with error in half of all monads that people use? Why do you advocate the use of runIdentity on a possibly failing computation? That's the same as failing via error. Yup. except for the fact that I am advocating making functions work in an arbitrary monad. Think about lambda patterns, they cause 'errors' but arn't indicated as special in the type system, at least with the 'do' notation you can recover and do something interesting when the pattern doesn't match. bottom is a member of every type in haskell whether we like it or not. People already use 'error' way to much, we should be making it easier for them to use recoverable things like 'fail', not harder. Dealing with errors sanely should not take more effort, but should be the default. bottoming out is a perfectly valid thing to do on some errors, but such a thing should _never_ be forced. the choice of Monad is what lets you do that. The difference is non-trivial and deals with more than just error handling. A space leaking deterministic parser written correctly will become constant space when run in the 'Identity' Monad (but might fill in some values with bottom) while using Either or Just would cause it to hold onto its entire input until the information can be verified. Sometimes you want fail to bottom, sometimes you don't, but best of all in all cases is to defer the decision to an outer monad. if people can't do foo - getString without changing all their type signatures, then they are going to do something like x - getString if x == foo then ... else error expecting foo! being able to use 'fail' without changing your signatures is a very nice thing and
[Haskell-cafe] Re: PrefixMap: code review request
Brian Hulley wrote: Whoever thought up the original Haskell layout rule assumed that people would be happy using a single fixed width font, tabs set to 8 spaces, and didn't care about the brittleness of the code (in the face of identifier renamings) it allowed one to write. Are you complaining that Haskell permits you to write code with these problems, or that it requires you to? The latter is not true. Instead of keyword clause1 clause2 you can always write keyword clause1 clause2 or keyword { clause1 ; clause2 } Both styles are insensitive to tab width and renaming of identifiers. The off-side rule only comes into play when you don't include an explicit {, so you can suppress it entirely if you prefer. If you have a different layout rule in mind I'd be interested in hearing it, but I think Haskell's is quite good overall. Lisp has similar indentation problems despite the lack of a layout rule, since people commonly write (foo (...) (...)) Renaming foo can't confuse the compiler, but I've never had a Haskell layout error change the meaning of my program. At worst it causes the program to be rejected. I do edit my source code in a fixed-width font, but it's a very pretty font (Bitstream Vera Sans Mono). It's a small price to pay for the convenience of being able to use 2D layout, even in languages where it's not significant, and in comments. -- Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: PrefixMap is a Trie
David F.Place wrote: The PrefixMap datastructure implements a Prefix Tree which allows a key/value relationship. \begin{code} data PrefixMap k v = Node (Maybe v) (Map.Map k (PrefixMap k v)) deriving (Show) \end{code} You may compare your code with Keith's implemenation of a Trie. http://article.gmane.org/gmane.comp.lang.haskell.libraries/2571 Find attached a modified version (that I never tested, though). Christian {- | Module : Trie Copyright : (c) Keith Wansbrough 2005, C. Maeder 2006 License : BSD-style Maintainer : none Stability : experimental Portability : portable This module provides a very basic implementation of the Trie data type, with no great concern for efficiency, or for completeness of API. original version http://article.gmane.org/gmane.comp.lang.haskell.libraries/2571 modified using Data.Map and added functions insert and null -} module Trie ( -- * Data type Trie, -- * Constructors empty, insert, unit, plus, plus_C, -- * Primitive discriminators, accessors and mutators null, value, children, value_u, children_u, -- * Basic operations preOrder, upwards, downwards, -- * Derived operations takeWhile, takeWhile_V, fringe, ) where import Prelude hiding (takeWhile, null) import qualified Data.Map as Map import Data.Maybe import Control.Monad -- |A Trie with key elements of type at k at -- (keys of type at [k] at ) and values of type at v at . data Trie k v = Trie { value :: Maybe v, children :: Map.Map k (Trie k v) } -- |Modify the 'children' field of a trie. value_u :: (Maybe v - Maybe v) - Trie k v - Trie k v value_u f p = p { value = f (value p) } -- |Modify the 'children' field of a trie. children_u :: (Map.Map k (Trie k v) - Map.Map k (Trie k v)) - Trie k v - Trie k v children_u f p = p { children = f (children p) } -- |The empty trie. empty :: Trie k v empty = Trie { value = Nothing, children = Map.empty } -- |Test for the empty trie null :: Trie k v - Bool null t = isNothing (value t) Map.null (children t) -- |The singleton trie. unit :: Ord k = [k] - v - Trie k v unit [] x = Trie { value = Just x, children = Map.empty } unit (k:ks) x = Trie { value = Nothing , children = Map.singleton k (unit ks x) } insert :: Ord k = [k] - (Maybe v - Maybe v) - Trie k v - Trie k v insert l f t = case l of [] - t { value = f (value t) } k : ks - let cs = children t nt = insert ks f $ Map.findWithDefault empty k cs in if null nt then t { children = Map.delete k cs } else t { children = Map.insert k nt cs } -- |Combining two tries. The first shadows the second. plus :: Ord k = Trie k v - Trie k v - Trie k v plus p1 p2 = Trie { value = mplus (value p1) (value p2), children = Map.unionWith plus (children p1) (children p2) } -- |Combining two tries. If the two define the same key, the -- specified combining function is used. plus_C :: Ord k = (v - v - v) - Trie k v - Trie k v - Trie k v plus_C f p1 p2 = Trie { value = lift f (value p1) (value p2), children = Map.unionWith (plus_C f) (children p1) (children p2) } where lift _ Nothing y = y lift _ x Nothing = x lift _ (Just x) (Just y) = Just (f x y) -- |Enumerate all (key,value) pairs, in preorder. preOrder :: Ord k = [k] - Trie k v - [([k],v)] preOrder ks p = getNode p ++ concatMap (\(k,p') - preOrder (ks++[k]) p') (Map.toList (children p)) where getNode q = maybe [] (\ v - [(ks,v)]) (value q) -- |An upwards accumulation on the trie. upwards :: Ord k = (Trie k v - Trie k v) - Trie k v - Trie k v upwards f = f . children_u (Map.map (upwards f)) -- |A downwards accumulation on the trie. downwards :: Ord k = (Trie k v - Trie k v) - Trie k v - Trie k v downwards f = children_u (Map.map (downwards f)) . f -- |Return the prefix of the trie satisfying at f at . takeWhile :: Ord k = (Trie k v - Bool) - Trie k v - Trie k v takeWhile f = downwards (children_u (Map.filter f)) -- |Return the prefix of the trie satisfying at f at -- on all values present. takeWhile_V :: Ord k = (v - Bool) - Trie k v - Trie k v takeWhile_V f = takeWhile (maybe True f . value) -- |Return the fringe of the trie (the trie composed of only the leaf nodes). fringe :: Ord k = Trie k v - Trie k v fringe = upwards (\ p - if Map.null (children p) then p else value_u (const Nothing) p) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: rounding errors with real numbers.
Henning Thielemann wrote: Maybe you should use a kind of convex combination, that is (x-oldLower)*a + (oldUpper-x)*b Maybe lower*(1-z) + upper*z where z = (x-oldLower) / (oldUpper-oldLower). I think this will always map oldLower and oldUpper to lower and upper exactly, but I'm not sure it's monotonic. -- Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: PrefixMap: code review request
Ben Rudiak-Gould wrote: Brian Hulley wrote: Whoever thought up the original Haskell layout rule assumed that people would be happy using a single fixed width font, tabs set to 8 spaces, and didn't care about the brittleness of the code (in the face of identifier renamings) it allowed one to write. Are you complaining that Haskell permits you to write code with these problems, or that it requires you to? The latter is not true. Instead [snip] Just that it allows you to, because this means other people's code (which you may be editing) can be brittle. If you have a different layout rule in mind I'd be interested in hearing it, but I think Haskell's is quite good overall. Here is my proposed layout rule: 1) All layout keywords (where, of, let, do) must either be followed by a single element of the corresponding block type, and explicit block introduced by '{', or a layout block whose first line starts on the *next* line and whose indentation is accomplished *only* by tabs In particular, this allows: let a = 56 in a*a and let a = 56 b = 78 in a*b but not let a = 56 b = 78 or let a = 56; b = 78 c = 90 I would also make it that explicit braces are not allowed to switch off the layout rule (ie they can be used within a layout), multiline strings would not be permitted, and multiline comments would not be permitted (pragmas could easily be used just by using --#) (I'd have a special keyword eg '{}module' instead of 'module' at the top of a file to switch off layout for the whole file if required, but making the presence of the layout rule depend on whether or not there are surrounding braces makes life *way* too complicated imho) This would give the following advantages: 1) When you see a ';' you could immediately tell which block it belongs to by looking backwards till the next '{' 2) Variable width fonts can be used, or different font faces to represent different sorts of identifier eg class names, tycons, value constructors, operators like `seq` as opposed to seq etc 3) Using only tabs ensures that vertical alignment goes to the same position on the screen regardless of the font and tabs could even have different widths just like in a wordprocessor 4) Any keypress has a localised effect on the parse tree of the buffer as a whole ( { no longer kill everything which follows and there would be no {- ) 5) It paves the way for a much more immersive editing environment, but I can't say more about this at the moment because I haven't finished writing it yet and it will be a commercial product :-))) Using my self-imposed layout rule I'm currently editing all my Haskell code in a standard text editor using tabs set to 4 spaces and a variable width font and have no problems. Regards, Brian. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: PrefixMap is a Trie
On Feb 28, 2006, at 8:33 AM, Christian Maeder wrote:You may compare your code with Keith's implemenation of a Trie. http://article.gmane.org/gmane.comp.lang.haskell.libraries/2571 Thanks for the pointer, I searched for "Prefix Tree" which is an alternative name for trie so I didn't find that implementation. Perhaps, as you suggest in your code, it's time for Data.Trie. David F. Place mailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: socket TChan problem
HiActually I don't need to duplicate them, it's an oversight from my side when I converted my code from my own channels to TChan.regardsStefanAm 28.02.06 schrieb Anatoly Zaretsky [EMAIL PROTECTED]: Why do you need to duplicate channels?___Haskell-Cafe mailing listHaskell-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] Picking a shell for runCommand
It appears runCommand uses /bin/sh by default, but our environment needs tcsh. Is there any way to set an alternative shell? -Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Picking a shell for runCommand
On Tue, 28 Feb 2006, Tom Hawkins wrote: It appears runCommand uses /bin/sh by default, but our environment needs tcsh. Is there any way to set an alternative shell? Ideally, it would be better to fix your environment, but something like this should work if you can't do that - runSh cmd = runProcess /bin/tcsh [-c, cmd] Nothing Nothing Nothing Nothing Nothing The 2nd parameter is argv with argv[0] gratuitously removed. Donn Cave, [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Layout rule (was Re: PrefixMap: code review request)
Brian Hulley wrote: Here is my proposed layout rule: 1) All layout keywords (where, of, let, do) must either be followed by a single element of the corresponding block type, and explicit block introduced by '{', or a layout block whose first line starts on the *next* line I wouldn't have much trouble adapting to that. and whose indentation is accomplished *only* by tabs You can't be serious. This would cause far more problems than the current rule. I would also make it that explicit braces are not allowed to switch off the layout rule (ie they can be used within a layout), I don't understand. What does used within a layout mean? multiline strings would not be permitted, They aren't now, except with \ escapes. A stray will be caught on the same line unless the line happens to end with \ and the next line happens to begin with \, which is exceedingly unusual. and multiline comments would not be permitted (pragmas could easily be used just by using --#) But --# doesn't introduce a comment. And this would make UNPACK pragmas rather inconvenient to use. 1) When you see a ';' you could immediately tell which block it belongs to by looking backwards till the next '{' I guess that might be helpful, but it doesn't seem easier than looking left to the beginning of the current line and then up to the first less-indented line. 2) Variable width fonts can be used, They can be used now, if you adhere to a certain style, but not everyone likes that style. I wrote in C++ with a variable width font and tabs at one time, but eventually went back to fixed width. One reason was that I couldn't use comment layout conventions that tend (in my experience) to improve readability more than monospacing hurts it. Another reason was that glyph widths appropriate to natural languages didn't work all that well for source code. Spaces are much more important in source code than in natural language, for example. A proportional font designed for source code would be nice, but I haven't found one yet. Stroustrup used a mixture of proportional and monospaced glyphs in _The C++ Programming Language_ and it worked well. or different font faces to represent different sorts of identifier eg class names, tycons, value constructors, operators like `seq` as opposed to seq etc Lots of editors do this with monospaced fonts; I think it's orthogonal to the layout issue. 3) Using only tabs ensures that vertical alignment goes to the same position on the screen regardless of the font and tabs could even have different widths just like in a wordprocessor Requiring tabs is a really bad idea. Just forget it. Seriously. 4) Any keypress has a localised effect on the parse tree of the buffer as a whole ( { no longer kill everything which follows and there would be no {- ) I don't understand why this is an advantage. If you have an editor that highlights comments in green, then large sections of the program will flash green while you type a {- -} comment, which might be annoying, but it also means you'll never forget to close the comment, so the practical benefit of forbidding {- -}, as opposed to simply not typing it yourself, seems nil. 5) It paves the way for a much more immersive editing environment, but I can't say more about this at the moment because I haven't finished writing it yet and it will be a commercial product :-))) I guess everything has been leading up to this, but my reaction is that it renders the whole debate irrelevant. The only reason layout exists in the first place is to make source code look good in ordinary text editors. If you have a high-level source code editor that manipulates the AST, then you don't need layout, or tabs, or any of that silly ASCII stuff. The only time you need to worry about layout is when interoperating with implementations that use the concrete syntax, and then there's nothing to stop you from exporting in any style you like. And when importing, there's no reason to place restrictions on Haskell's layout rule, because the visual layout you display in the editor need have no connection to the layout of the imported file. Using my self-imposed layout rule I'm currently editing all my Haskell code in a standard text editor using tabs set to 4 spaces and a variable width font and have no problems. Which is the best argument for keeping the current rule! If it were changed as you propose, then someday Hugh Briley would come along and complain that Haskell's layout syntax squandered screen space---but he *wouldn't* be able to program in his preferred style, because it would no longer be allowed. Religious freedom is a good thing. {- Ben -} ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Help with Type Class
Although the discussion about Array refactoring died down quickly on the Haskell' mailing list, I've been noodling on refactoring the various Collections in Haskell. In doing so, I've bumped into a problem with type classes that I can't resolve. The issue is as follows: I'm designing a Collections class heirarchy that is a blend between that of Java and of Haskell. The problem is that, whereas in OOP it is easy to do so, Haskell class mechanism seems to make it difficult to add *new* member variable to subclasses. Simple goal: create a top-level Collection with an *indexed* Array subclass (and various other subclasses). The problem I'm running into is Collection has no need of an index variable and I can't seem to figure out how to add an index to Array when subclassing from Collection Mock up: -- class CollectionClass c e where -- every Collection supports toList... toList :: c e - [e] class (CollectionClass a e)= ArrayClass a e where ... data Array i e = Array i i instance CollectionClass Array e where -- Since Array is a Collection -- toList :: c e - [e] -- but with an Array the type would be -- toList :: a i e - [e] toList = ... -- I think that the problem goes away if: class CollectionClass c x e where ... with x used an index for Array or a key for Map or () for Set, but it doesn't seem clean to scatter member variables in the parent class in case the subclass requires them... Another possible solution that I couldn't get to work would be to use (Array i) as the type for c in Collection c: instance CollectionClass (Array i) e where toList = ... -- (Array i) e - [e] ? This seems clean because it says the Collection holds es and is organized by an (Array i). Similarly, Set would be a Collection of es organized by Set and Map would be a Collection of es organized by (Map k). Undoubtedly, I've missspoken some crucial aspect of the type/kind/class/instance magical incantation. Help! - Alson ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] My piece of an IRC bot
Today I started on a simple IRC bot framework thingy. I decided to post the source code here so people can look at it and tell me what the heck I did wrong :-P module IRC where import Control.Monad.State import System.IO import Network {--}{--} data IRCMessage = IRCMessage (Maybe String) String [String] type IRCBot a = IRCMessage - State a [IRCMessage] type IRCConnection a= IRCBot a - IO () ircConnect :: String - Integer - a - IRCConnection a ircConnect server port state bot = withSocketsDo (do connection - connectTo server (PortNumber (fromInteger port)) ircLoop connection state bot) ircLoop connection state bot = do eof - hIsEOF connection if eof then hWaitForInput connection 500 return () else do message - hGetLine connection hPutStr connection (fst (runState (bot (ircParseMessage message)) state) = decodeMessage) ircLoop connection (snd (runState (bot (ircParseMessage message)) state)) bot -- Oh noes. Let's hope we'll never, ever have to read that ;-) {-End I/O capable code-}{--} ircParseMessage x = let rx = filter (/='\r') x (p:u:us) = words rx in if (head p) == ':' then IRCMessage (Just p) u (ircParseParams us) else IRCMessage Nothing p (ircParseParams (u:us)) ircParseParams (x:xs) = if head x == ':' then [unwords (x:xs)] else x : ircParseParams xs decodeMessage (IRCMessage Nothing command params)= (command ++ ' ' : unwords (init params) ++ ' ' : (':' : last params)) decodeMessage (IRCMessage (Just prefix) command params)= ((':' : prefix) ++ ' ' : command ++ ' ' : unwords (init params) ++ (':' : last params)) {-Thus ends the IRCbot-}{--} The very simple bot I've been trying to run with it: module Main where import IRC import Control.Monad.State {--}{--} main= ircConnect brown.freenode.net 6667 False bot bot _ = State (\x - if x then ([],True) else ( [IRCMessage Nothing NICK [EagleBot], IRCMessage Nothing USER [EagleBot, Null, Null, EagleBot], IRCMessage Nothing PRIVMSG [NickServ, IDENTIFY censored], IRCMessage Nothing JOIN [#esoteric]],True)) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Layout rule (was Re: PrefixMap: code review request)
Ben Rudiak-Gould wrote: Brian Hulley wrote: Here is my proposed layout rule: 1) All layout keywords (where, of, let, do) must either be followed by a single element of the corresponding block type, and explicit block introduced by '{', or a layout block whose first line starts on the *next* line I wouldn't have much trouble adapting to that. and whose indentation is accomplished *only* by tabs You can't be serious. This would cause far more problems than the current rule. Why? Surely typing one tab is better than having to hit the spacebar 4 (or 8) times? I would also make it that explicit braces are not allowed to switch off the layout rule (ie they can be used within a layout), I don't understand. What does used within a layout mean? I meant that {;} would be used just like any other construct that has to respect the layout rule so you could write let a = let { b = 6; z = 77; h = 99; p = 100} in b+z+h + p etc but not: let a = let { b = 6; z = 77; h = 99; -- this binding would be part of the outermost 'let' p = 100} in b+z+h + p multiline strings would not be permitted, They aren't now, except with \ escapes. A stray will be caught on the same line unless the line happens to end with \ and the next line happens to begin with \, which is exceedingly unusual. and multiline comments would not be permitted (pragmas could easily be used just by using --#) But --# doesn't introduce a comment. And this would make UNPACK pragmas rather inconvenient to use. -- # but I hadn't thought about UNPACK... The motivation in both points is to make it easy for an editor to determine which lines need to be re-parsed based on the number of leading tabs alone. 1) When you see a ';' you could immediately tell which block it belongs to by looking backwards till the next '{' I guess that might be helpful, but it doesn't seem easier than looking left to the beginning of the current line and then up to the first less-indented line. There was an example posted on another thread where someone had got into confusion by using ; after a let binding in a do construct with an explicit brace after the 'do' but not after the 'let' (sorry I can't find it again). Also the current layout rule uses the notion of an implicit opening brace which is a to be regarded as a real opening brace as far as ';' in concerned but an unreal non-existent opening brace as far as '}' is concerned. Thus I think it is a real mix-up. 2) Variable width fonts can be used, They can be used now, if you adhere to a certain style, but not everyone likes that style. I wrote in C++ with a variable width font and tabs at one time, but eventually went back to fixed width. One reason was that I couldn't use comment layout conventions that tend (in my experience) to improve readability more than monospacing hurts it. Another reason was that glyph widths appropriate to natural languages didn't work all that well for source code. Spaces are much more important in source code than in natural language, for example. A proportional font designed for source code would be nice, but I haven't found one yet. Stroustrup used a mixture of proportional and monospaced glyphs in _The C++ Programming Language_ and it worked well. or different font faces to represent different sorts of identifier eg class names, tycons, value constructors, operators like `seq` as opposed to seq etc Lots of editors do this with monospaced fonts; I think it's orthogonal to the layout issue. For example on Windows Trebuchet MS is a very nice font, also Verdana, both of which are not monospaced. But yes I agree it's not a major issue and I just see the option of being able to use them as a nice side-effect. 3) Using only tabs ensures that vertical alignment goes to the same position on the screen regardless of the font and tabs could even have different widths just like in a wordprocessor Requiring tabs is a really bad idea. Just forget it. Seriously. I'm really puzled here. I've been using tabs to indent my C++ code for at least 10 years and don't see the problem. The only problem would be if someone mixed tabs with spaces. Since it has to be either tabs only or spaces only I'd choose tabs only to save keystrokes. I suppose though it is always going to be a matter of personal taste... 4) Any keypress has a localised effect on the parse tree of the buffer as a whole ( { no longer kill everything which follows and there would be no {- ) I don't understand why this is an advantage. If you have an editor that highlights comments in green, then large sections of the program will flash green while you type a {- -} comment, which might be annoying, but it also means you'll never forget to close the comment, so the practical benefit of forbidding {- -}, as opposed to simply not typing it yourself,
Re: [Haskell-cafe] Layout rule (was Re: PrefixMap: code review request)
On Wed, 1 Mar 2006, Brian Hulley wrote: Ben Rudiak-Gould wrote: Brian Hulley wrote: Here is my proposed layout rule: snip and whose indentation is accomplished *only* by tabs You can't be serious. This would cause far more problems than the current rule. Why? Surely typing one tab is better than having to hit the spacebar 4 (or 8) times? Not when it prevents me from ever exhibiting the slightest shred of style in my code. I use that control for readability purposes in my code. -- [EMAIL PROTECTED] My religion says so explains your beliefs. But it doesn't explain why I should hold them as well, let alone be restricted by them. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: haskell programming guidelines
G'day all. Quoting Christian Maeder [EMAIL PROTECTED]: I suggested: f . g $ h x or f $ g $ h x Of these, the first version only makes sense if you want to single out h for some reason. I'm known to do this, for example, if h is a record accessor. The second is just plain wrong. My reasoning is here for those who care: http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/11256 Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Layout rule (was Re: PrefixMap: code review request)
BH Why? Surely typing one tab is better than having to hit the spacebar 4 (or 8) BH times? PC Not when it prevents me from ever exhibiting the slightest shred of style PC in my code. I use that control for readability purposes in my code. [snip] BH I'm really puzled here. I've been using tabs to indent my C++ code for at BH least 10 years and don't see the problem. At least two reasons: 1. C++ doesn't care about any whitespace (except to separate tokens). Haskell cares about leading whitespace (which it is clear you are thinking a lot about...) but 2. as Philippa mentioned, Haskell programmers care a ton about inter-line, inter-word layout/alignment, for example, lining up = signs and arguments to functions in pattern matches, etc. C++ does not invite this style of declarative programming so it is not surprising that it wasn't an issue: aside from the indentation, I rarely type fancy whitespace inside a giving line of C++ code to align elements with those on a preceding line. In Haskell, this unofficial layout style doesn't affect the machine-parsing of the code, but rather the human-parsing of the code. (In fact, it's one of my favorite things about Haskell.) If you want to see what can be accomplished with variable width fonts and complex layouts (not just beginning of lines but rather inter-line, inter-word alignment) you should checkout lhs2TeX. They accomplish all their magic with spaces. BH The only problem would be if BH someone mixed tabs with spaces. Since it has to be either tabs only or BH spaces only I'd choose tabs only to save keystrokes. BTW, tab doesn't type the tab character (at least in emacs and I think vim) but instead moves the left edge of the current line by adding or deleted spaces (or trying to ident the right amount). This usually means you don't have to type 4 or 8 spaces. (And anyway, I would just hold the key down if I had to type more than one spacebar, etc.) [snip] For example on Windows Trebuchet MS is a very nice font, also Verdana, both of which are not monospaced. But yes I agree it's not a major issue and I just see the option of being able to use them as a nice side-effect. Very few programmers I know would go to variable width fonts just to use some Microsoft font to edit code... (BTW I like Trebuchet and Verdana too.) To each his/her own! Cheers, Jared. -- http://www.updike.org/~jared/ reverse )-: ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] mediawiki syntax highlighting plugins
hi, i've noted that the new haskellwiki has dropped syntax highlighting support for haskell code fragments. while i think that full highlighting might be overkill, at least different color markup of code and comments would certainly be nice. investigating the options for syntax highlighting in mediawiki i found the following two extensions using GNU enscript: http://www.wickle.com/wiki/index.php/Syntax_Highlight_extension http://www.milab.is.tsukuba.ac.jp/~bushuhui/index.php?title=Enhanced_syntax_highlight_extension_for_MediaWiki where the second is an alteration of the first, with haskell support already added. an alternative would be geshi (http://qbnz.com/highlighter/) for which a mediawiki plugin also exists (http://meta.wikimedia.org/wiki/GeSHiHighlight), but it says on the geshi site GeSHi supports PHP5 and Windows. and i'm not clear whether they mean it _also_ supports those options or exclusively. it would be cool if one of the wiki maintainers could look into this matter and possibly install/setup one of the above extensions. thank you, Johannes Ahlmann ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Code snippet, a `trace' with line and column numbers
Suggested by a question from sethk on #haskell irc channel. Solves an FAQ where people have often resorted to cpp or m4: a `trace' that prints line numbers. module Location (trace, assert) where import qualified Control.Exception as C (catch) import System.IO.Unsafe (unsafePerformIO) import GHC.Base (assert) import System.IO -- An identity function that also prints the current line and column number trace :: (Bool - IO () - IO ()) - a - a trace assrt f = (unsafePerformIO $ C.catch (assrt False $ return ()) printIt) `seq` f where printIt e = let (x,_) = break (== ' ') $ show e in hPutStrLn stderr (x ++ trace) for example: import Location main = do let x = trace assert (1+2) putStrLn . show $ x Generates: $ ./a.out M.hs:4:18-23: trace 3 This continues a theme I've noticed: catching internal exceptions can yield some interesting results, i.e. with undefined, missing class methods, and here, assertion failures. Hope this little thing is useful. Cheers, Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Layout rule
Brian Hulley [EMAIL PROTECTED] writes: You can't be serious. This would cause far more problems than the current rule. Why? Surely typing one tab is better than having to hit the spacebar 4 (or 8) times? What you type depends on your editor. I hit tab, and the editor inserts an appropriate number of spaces. (I thought all editors did this now?) There was an example posted on another thread where someone had got into confusion by using ; after a let binding in a do construct with an explicit brace after the 'do' but not after the 'let' (sorry I can't find it again). If you allow {- everything becomes a lot more complicated and who needs them anyway? Multi line comments are nice for commenting out blocks of code. It is much less intrusive, in particular if you're using version control. back to editing a function at the top of a file. Things like {- would mean that all the parse trees for everything after it would have to be discarded. Also, flashing of highlighting on this scale could be very annoying for a user, so I'd rather just delete this particular possibility of the user getting annoyed when using my software :-) Couldn't your editor just be a little bit smarter? E.g. count the {-s and -}s, and only comment-hilight them if there are two of them? Retain a history of old parse trees, so that it is quick to return to a previous one? Haskell, which in turn might lead to more people understanding and therefore using the language, more libraries, more possibilities for You forget one thing: Avoid success at all costs :-) -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe