From bulat.ziganshin at gmail.com Sun Jul 1 04:33:14 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jul 1 04:28:32 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: <18054.22195.858951.944853@gargle.gargle.HOWL> References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> <229B0A4C-CA11-4443-B7E7-7653CA5500EB@googlemail.com> <18054.22195.858951.944853@gargle.gargle.HOWL> Message-ID: <118245819.20070701123314@gmail.com> Hello David, Saturday, June 30, 2007, 5:12:19 PM, you wrote: >> matchAndDropPrefx >> dropMatchingPrefix > stripMatchingPrefix? functionThatRemovesItsFirstArgumentFromSecondOneOrReturnsNothing`PleaseSendSuggestionsAboutFurtherImprovingThisFunctionNameToTheUnitedKongdomCambridgeMicrosoftResearchLabsSimonPeytonJones`ThankYouForUsingOurFunction`CopyrightIanLynagh`AllRightsReserved -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From apfelmus at quantentunnel.de Sun Jul 1 05:23:58 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Sun Jul 1 05:18:12 2007 Subject: apfelmus' interface degustation - System.FilePath.Find In-Reply-To: <4685A33B.8020108@serpentine.com> References: <4683F32E.3060207@quantentunnel.de> <4685A33B.8020108@serpentine.com> Message-ID: Bryan O'Sullivan wrote: >> b) Making (FindClause a) a mere type synonym of (FileInfo -> a) >> has the benefit that the user can choose whether he wants to use >> monads or applicative functors via the respective instances >> or whether he does not. > > That's where I had started out, as a matter of fact. Yes. What I want to say is that you're still there, even if not intended. Although FindClause is implemented as a state monad, the functions evalClause :: FindClause a -> (FileInfo -> a) (`liftM` fileInfo) :: (FileInfo -> a) -> FindClause a are isomorphisms. In other words, nothing is gained or lost compared to (FileInfo -> a). Interestingly, these functions can be defined for any state monad, but in general, their composition is not the identity. Here it is because put is not available. Whether an abstract data type is isomorphic to some other type depends on what functions are defined but also on what functions are not defined. >> or for general applicative functors as >> >> (||) <$> ((== ".hs") <$> extension) <*> ((== ".lhs") <$> extension) > > I don't find that very readable, I must confess. Neither do I. It's probably due to (||) and (==) being infix operators, it's quite readable for normal functions. I think it's indeed best to have custom infix operators like (==?) and (||?). Btw, liftOp works for any functor liftOp :: Functor f => (a -> b -> c) -> f a -> b -> f c liftOp = flip . (fmap .) . flip >> Maybe unsafePerformIO is the best solution, because you may safely close >> the file after having evaluated >> >> predicate (unsafePerformIO $ hGetContents handle) (fileinfo) >> >> to weak head normal form, i.e. True or False. I think it fits perfectly. > > In principle > > unsafeInterleaveIO $ readFile fileName > > ought to be better, because it will not try to open the file unless the > predicate actually inspects it, and opening files is expensive. But it > will also not close the file until a finalizer kicks in. A tidier > approach might be: > > maybeH <- newIORef Nothing > contents <- unsafeInterleaveIO $ do > h <- openFile fileName ReadMode > writeIORef maybeH (Just h) > hGetContents h > let result = predicate contents > result `seq` readIORef maybeH >>= maybe (return ()) hClose > > That's a little cumbersome, but very appealing from the perspective of a > user of the library. Unfortunately, it looks to me like it's not very > safe; see below. Yes, this code looks best. And I think it's safe if the predicate may only return unary constructors like True or False. I mean, evaluating this to WHNF is like evaluating it to NF and every unused part of the file can safely be discarded, since there are no unevaluated thunks depending on the file contents anymore (and which are not garbage). >> Using >> System.FilePath.Find.fold gives you both file status and file path but >> the ought-to-be equivalent approach of using foldl' on the list returned >> by find only gives the file path but no file status. So, the suggestion >> is to make find return a list of FileInfo > > Let me pass an idea by you. There's a problem with augmenting FileInfo > to potentially cause IO to occur as above (both with your original > suggestion and my changes), no? We lose the ability to control when a > file might be opened, and when it ought to be closed. I agree, augmenting FileInfo with actual file contents is probably not advisable, although it would be very functional in style. Better ditch the idea for now. However, we probably could safely salvage two lazy reading operations: 1) reading the FileStatus record of a file 2) reading file contents if to be used in a True/False predicate The common pattern is that the information extracted is small enough to be deepSeq'ed, so that the file can be closed early once the lazy read is triggered. > If that were the case, the fold interface would have the same problem, > if it decided for some reason to sock away FileInfo values in an > accumulator and work on them after the fold had completed. (The rank-2 trick can prevent FileInfos to leak out into the result of the fold fold :: (forall s . a -> FileInfo s -> a) -> FilePath -> IO a but that doesn't help very much as long as one would want a to be able to depend on the file contents via one of contents :: forall s . FileInfo s -> String withContents :: forall s . FileInfo s -> (String -> a) -> a so this is not an option.) Concerning fold, I think that it is the very core of the directory traversal algorithm: traversing a tree is a catamorphism. In other words, every other traversal can be formulated with a fold. For instance, we currently almost have find r p dir = fold r (flip $ (:) . infoPath) [] dir except that find returns a lazy list whereas fold traverses the directory tree before returning the list. But fold is currently not the general catamorphism, which is fold :: (FileInfo -> [a] -> a) -> (FileInfo -> a) -> FilePath -> IO a (I have been tricked by the name 'Foldable', this class does not give the catamorphism I had in mind.) This fold has to be lazy to be useful since only this allows to skip hole subdirectories. With the catamorphism, we can express find and the old fold: toList r p = fold branch leaf where branch dir xs = if r dir then concat xs else [] leaf file = if p file then [file] else [] find r p = map infoPath . toList r p oldfold r f x root = listSeq `fmap` foldl' f x `fmap` toList r (const True) root where listSeq xs = length xs `seq` xs (Btw, does the old fold only fold the value of type a over regualar files or also over directories?) Being able to return FileInfos captures reading operation 1) but misses the opportunity 2). However, 2) can simply be supplied as an extra function contentsSatisfies :: (String -> Bool) -> FilePath -> Bool contentsSatisfies f file = unsafePerformIO $ do h <- openFile file ReadMode b <- f `fmap` hGetContents h b `seq` hClose h return b to be used at the users discretion. >> Of course, this leads to the question whether find should be factored >> even more into generate & prune >> >> find r p dir = map filepath . filter p . directoryWalk r dir >> >> with the intention that System.FilePath.Find only exports directoryWalk. > > That's a nice idea, but subject to the same problems as the fold > interface would be if we added file contents to the interface. > > Your other observations regarding making a directory tree abstract, and > instances of some of our favourite typeclasses, are very appealing. As soon as we supply a (lazy) catamorphism like above, the user can make a concrete directory tree data File = Directory FileInfo [File] | File FileInfo (fold Directory File) :: FilePath -> IO File and the only way to keep the type abstract is to only supply weaker stuff than fold. Which is probably too weak then. Regards, apfelmus From apfelmus at quantentunnel.de Sun Jul 1 06:45:25 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Sun Jul 1 06:39:35 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: <20070630003528.GA12736@matrix.chaos.earth.li> References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> Message-ID: Ian Lynagh wrote: > On Wed, Jun 27, 2007 at 02:26:05AM +0100, Ian Lynagh wrote: >> dropPrefix :: Eq a => [a] -> [a] -> Maybe [a] >> dropPrefix [] ys = Just ys >> dropPrefix (x:xs) (y:ys) >> | x == y = dropPrefix xs ys >> dropPrefix _ _ = Nothing > > On names, Stefan wrote "I'd name it differently---not sure how", as the > existing drop* functions always returns a list. Other names I considered > were stripPrefix and removePrefix, but I can't think of any commonality > between those names and existing functions off the top of my head. Here's an (admittedly crazy) approach to the naming problem. It comes to mind when eating too many peppermint drops. First a higher order drop (yummy) data Action b = Continue b | Stop | Bail type Dropper a b = (b -> a -> Action b, b) drop :: Dropper a b -> [a] -> Maybe [a] drop (f,y) = drop' y where drop' y (x:xs) = case f y x of Continue y' -> drop' y' xs Stop -> Just (x:xs) Bail -> Nothing then some flavors while :: (a -> Bool) -> Dropper a () while p = (\_ x -> if p x then Continue () else Stop, ()) first :: Int -> Dropper a Int first n = (\k x -> if k < n then Continue (k+1) else Stop, 0) prefix :: Eq a => [a] -> Dropper a [a] prefix s = (f, s) where f [] _ = Stop f (c:cs) x = if c==x then Continue cs else Bail and now enjoy your meal! drop (while (/= 5)) [1..10] drop (first 3) [1..10] drop (prefix "pre") "prefix" Note that the Droppers can be used to write a higher order take or split as well, but you can't eat that anymore. Regards, apfelmus From ndmitchell at gmail.com Sun Jul 1 08:22:49 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sun Jul 1 08:16:50 2007 Subject: Supported Windows versions (was: Re: unix package) In-Reply-To: References: Message-ID: <404396ef0707010522p172b678bsd7b26aeb5746fbcf@mail.gmail.com> Hi Esa, > Maybe this is a good place to ask for opinions. Anyone have any or know of > need to support old Windows versions? I am also curious if someone still > writes software for pre-Windows 2000 NTs, as there's some nice API functions > in Windows 2000. "Effective July 11, 2006, Windows 98, Windows 98 Second Edition, and Windows Me (and their related components) will transition to a non-supported status. After this date, Microsoft will no longer provide any incident support options or security updates. Microsoft is not offering a custom support agreement for these products." I think its perfectly reasonable to assume that people only run Windows 2000 and Windows XP. Anyone who is running anything older is either a) not connected to the internet, or b) full of spyware. Either way, running brand new GHC applications is unlikely to be top of their list of priorities. As a personal point of experience, when developing WinHugs I made it Win NT only, by accident. It was only a one line change to fix it, but it was a very long time before anyone complained, and trying to find a Win98 machine that could connect to the world was nearly impossible. Thanks Neil From bulat.ziganshin at gmail.com Sun Jul 1 09:34:27 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jul 1 09:30:07 2007 Subject: unix package In-Reply-To: <1183220225.6962.23.camel@localhost> References: <125EACD0CAE4D24ABDB4D148C4593DA901BDFB23@GBLONXMB02.corp.amvescap.net> <4683E108.1080002@serpentine.com> <1183220225.6962.23.camel@localhost> Message-ID: <192078263.20070701173427@gmail.com> Hello Duncan, Saturday, June 30, 2007, 8:17:05 PM, you wrote: > Yes. I've got a little Gtk2Hs demo that shows you a directory tree with > file names and file sizes. With the portable Haskell directory stuff I > can't even get the file size, I'd have to open every file and use > hFileSize. getFileSize isn't any harder to implement than getModificationTime, the only minoor problem is that function used (lstat) will truncate file size to low 32 bits, for full 64-bit value non-portable lstati64 should be used instead (and another type for C-level filesize too) > Perhaps with splitting the base package up we have the opportunity to > have the directory & IO stuff live in a package that can depend on > either the posix/unix or win32 packages, and implement the portable IO > stuff on top of those (probably still using cpp). anyway file operations best should be split away from base. the only problem is that Handle type used in definition of Exception which is used in definition of IO monad which is used in Prelude (and some Prelude functions need file i/o by itself) i once proposed plan of implementing stack of file system/io libraries http://haskell.org/haskellwiki/Library/IO , also portable base for file i/o and memory-mapped files i/o implemented in Streams library: see System.FD and System.MMFile modules in http://www.haskell.org/library/StreamsBeta.tar.gz -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From isaacdupree at charter.net Sun Jul 1 10:05:57 2007 From: isaacdupree at charter.net (Isaac Dupree) Date: Sun Jul 1 09:58:19 2007 Subject: unix package In-Reply-To: <192078263.20070701173427@gmail.com> References: <125EACD0CAE4D24ABDB4D148C4593DA901BDFB23@GBLONXMB02.corp.amvescap.net> <4683E108.1080002@serpentine.com> <1183220225.6962.23.camel@localhost> <192078263.20070701173427@gmail.com> Message-ID: <4687B4C5.7090900@charter.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Bulat Ziganshin wrote: > anyway file operations best should be split away from base. the > only problem is that Handle type used in definition of Exception which > is used in definition of IO monad which is used in Prelude (and some > Prelude functions need file i/o by itself) Maybe we will end up having to move Prelude out of base (and all base modules import explicitly what they want; we could have a small prelude for them if there are some things that can only be gotten from the Prelude ( (.), ($), seq... ?), or make real modules that export those.) And there is a long-term plan for fixing Exception to be an extensible single-inheritance hierarchy ... maybe ghc 6.10 ... at which point low-level refactorings will be MUCH more possible (I tried once... Exception was one problem, avoiding orphan instances, another...) Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGh7TFHgcxvIWYTTURAomPAKCxLrNULfBLMWwcWmJRoVqVKiA9/ACaA8vz ZOwtpjK7Zasrvflfwwkq+aM= =H2Uc -----END PGP SIGNATURE----- From bulat.ziganshin at gmail.com Sun Jul 1 10:12:08 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jul 1 10:07:45 2007 Subject: Supported Windows versions (was: Re: unix package) In-Reply-To: References: Message-ID: <327796691.20070701181208@gmail.com> Hello Esa, Saturday, June 30, 2007, 9:28:49 PM, you wrote: > Maybe this is a good place to ask for opinions. Anyone have any or know of > need to support old Windows versions? I am also curious if someone still > writes software for pre-Windows 2000 NTs, as there's some nice API functions > in Windows 2000. i write a general-purpose program (archiver) and will prefer to have it win9x-compatible. btw, this doesn't have any relation to the fact that ghc itself can be run on old OSes regarding i/o library, it will be great to make it independent of GHC RTS, as Streams does -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From igloo at earth.li Mon Jul 2 05:54:31 2007 From: igloo at earth.li (Ian Lynagh) Date: Mon Jul 2 05:48:32 2007 Subject: darcs patch: Use filepath rather than System.Directory.Internals Message-ID: Mon Jul 2 10:54:08 BST 2007 Ian Lynagh * Use filepath rather than System.Directory.Internals -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/x-darcs-patch Size: 58726 bytes Desc: A darcs patch for your repository! Url : http://www.haskell.org/pipermail/libraries/attachments/20070702/3620d91d/attachment-0001.bin From simonmarhaskell at gmail.com Mon Jul 2 07:09:05 2007 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Mon Jul 2 07:03:06 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: <20070630003528.GA12736@matrix.chaos.earth.li> References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> Message-ID: <4688DCD1.2070002@gmail.com> Ian Lynagh wrote: > On Wed, Jun 27, 2007 at 02:26:05AM +0100, Ian Lynagh wrote: >> dropPrefix :: Eq a => [a] -> [a] -> Maybe [a] >> dropPrefix [] ys = Just ys >> dropPrefix (x:xs) (y:ys) >> | x == y = dropPrefix xs ys >> dropPrefix _ _ = Nothing > > Summary so far: > > Something should go in. > > The Maybe version seems more popular than generalisations, especially > because Data.List already uses Maybe for the same sort of task in other > functions. > > I don't think I tend to want the extra generality of Conor's leftFactor, > and no-one else has "me-too"ed it either. Also, writing "(_, ([], zs))" > rather than "Just zs" would be a bit cumbersome, so I think I'd like > dropPrefix even if we also had leftFactor. > > Thus, based on the feedback thus far, I think dropPrefix as defined > above should go in, with 'generalising Data.List functions' and > 'implementing "leftFactor"' being left to possible future proposals. > > On names, Stefan wrote "I'd name it differently---not sure how", as the > existing drop* functions always returns a list. FWIW, the version in GHC is called "matchPrefixMaybe". Cheers, Simon From simonpj at microsoft.com Wed Jul 4 03:46:58 2007 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Wed Jul 4 03:40:54 2007 Subject: FW: [Haskell-cafe] Sparse documentation Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 196 bytes Desc: signature.asc Url : http://www.haskell.org/pipermail/libraries/attachments/20070704/8903adbd/signature.bin From duncan.coutts at worc.ox.ac.uk Wed Jul 4 11:33:22 2007 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Wed Jul 4 11:27:02 2007 Subject: Gtk2Hs 0.9.12 release candidate 1 available for testing Message-ID: <1183563202.8180.20.camel@localhost> All, The first release candidate for Gtk2Hs 0.9.12 is now available. (The actual version number is 0.9.11.3) The source tarball and windows installer are available: http://haskell.org/gtk2hs/gtk2hs-0.9.11.3.tar.gz (md5sum 72ae779f8d12c6013787cc735272f723) http://haskell.org/gtk2hs/gtk2hs-0.9.11.3.exe (md5sum e1be8f38d33d76492c078cb66a790db1) Changes since 0.9.11: * ps, pdf and svg cairo backends are now supported * drag & drop support added * can run mainGUI in GHCi after :reload * Graphics.SOE.Gtk now works with threaded rts and GHCi * Windows build now includes OpenGL and SourceView packages * c2hs no longer chokes on some system headers (eg glibc-2.4) * various bug fixes and minor code cleanups * major overhaul of the code generator (will help binding gtk-2.10) Please test this on your platform and report success or failures to the gtk2hs-users list. Reports for less common platforms, processors architectures and older versions of GHC and Gtk+ are particularly appreciated. This release has seen less churn than most, so we expect relatively few build issues. We're expecting more significant changes in the next major release, including support for the new features in Gtk+ 2.10 and 2.12, a simplified signals and properties api which should make for considerably simpler documentation. In the long term we also expect to modularise Gtk2Hs and build each component using Cabal. For testing this release, try building, installing and then run: make installcheck This should build all the demo programs that are appropriate for your configuration. Running a selection of them would be good. Then if you have any other programs that use Gtk2Hs then testing those with this new release would be good. Windows notes: The installer expects GHC 6.6.1. (As always if you need a build for a different version of GHC then that's possible by building from source.) If anyone thinks we should include support for older versions of GHC in the windows installer (eg 6.4.2 or 6.6) then to say so. For example the last Gtk2Hs release included support for both 6.4.2 and 6.6. The windows build now includes the gtkglext and sourceview packages, but not svgcairo as that has pretty heavy dependencies. This makes the download a bit bigger, but on the other hand currently it includes support for only one GHC version, so overall the installer is rather smaller than in the last release. Duncan From eivuokko at gmail.com Thu Jul 5 16:25:33 2007 From: eivuokko at gmail.com (Esa Ilari Vuokko) Date: Thu Jul 5 16:19:22 2007 Subject: Supported Windows versions (was: Re: unix package) In-Reply-To: <327796691.20070701181208@gmail.com> References: <327796691.20070701181208@gmail.com> Message-ID: Thanks for answers Neil and Bulat! It seems that there's still users for Win 9x, as both answers had something to say about end-users in Win 9x. Maybe breaking Win 9x compatibility on purpose isn't sensible yet. I couldn't get any answers in irc, either. I recall Windows users were had lots of opinions in ghc poll few years back, but we are pretty quiet on these lists. On 7/1/07, Bulat Ziganshin wrote: > i write a general-purpose program (archiver) and will prefer to have > it win9x-compatible. btw, this doesn't have any relation to the fact > that ghc itself can be run on old OSes I realize that. Do you care about Win32 package or only about ghc rts and base? Could you find some resources to test on Win 9x? What do you think would be workable solution for Win32 package? I can think of few solutions * use old versions of Win32 package if you need Win9x compatibility (doesn't need extra work.) * Add new package with Win 2k APIs (but that's really annoying because of overlap) * Use CPP to make it possible to compile Win9x-compatible Win32 (need testers!) Any other ideas? Best regards, Esa From bulat.ziganshin at gmail.com Fri Jul 6 06:12:49 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Jul 6 06:10:40 2007 Subject: Supported Windows versions (was: Re: unix package) In-Reply-To: References: <327796691.20070701181208@gmail.com> Message-ID: <1158633611.20070706141249@gmail.com> Hello Esa, Friday, July 6, 2007, 12:25:33 AM, you wrote: >> i write a general-purpose program (archiver) and will prefer to have >> it win9x-compatible. btw, this doesn't have any relation to the fact >> that ghc itself can be run on old OSes > I realize that. Do you care about Win32 package or only about ghc > rts and base? Could you find some resources to test on Win 9x? i don't use Win32 package at all. i implemented my own file manipulation and i/o module because it was easiest way to provide uniform API for both Unix and Windows i proposed to develop file and i/o library which is platform-independent, utilize new NT features and still Win9x compatible (http://haskell.org/haskellwiki/Library/IO), but there is not enough resources to develop it > What do you think would be workable solution for Win32 package? > I can think of few solutions > * use old versions of Win32 package if you need Win9x compatibility > (doesn't need extra work.) > * Add new package with Win 2k APIs (but that's really annoying > because of overlap) > * Use CPP to make it possible to compile Win9x-compatible Win32 (need testers!) i think that, regarding small interest to this theme, the best solution will be one that require less work. it's obvious that 9x support will become less and less popular and it's better to focus attention on new OSes. so, i think that minimal solution is the best with only one exception - there should be a way to use *both* old and new lib in project (in order to provide compatibility with both systems). so i propose the following: * clone existing library and rename one of copies to either win9x or winnt. rename modules in this library appropriately. continue development of one of these clones using NT features freely while another clone will remain stabilized at current set of features. if someone will ever want to backport features from new library to old one (because these particular features are also available on 9x), he can do it yourself -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From apfelmus at quantentunnel.de Fri Jul 6 15:30:08 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Fri Jul 6 15:24:14 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> Message-ID: Ketil Malde wrote: > On Sun, 2007-07-01 at 12:45 +0200, apfelmus wrote: > >> Here's an (admittedly crazy) approach > > Why is it so crazy? The orthogonality issues with the different ways of > breaking up lists (split/break/span/take/drop), and the multitude of > possible predicates (either too complicated, or too specific) has always > been an annoyance to me. I thought your solution was quite nice! One problem is that you have to use drop (first 2) instead of drop 2 now. This can be remedied with some type-class hackery. Another problem is that performance will suffer a bit with the general approach. So, the specialized versions are likely to be kept around anyway. (Type classes can help with specialization, too.) Other than that, the general approach to drop & friends is not so crazy. But I don't like my implementation, so let's build a better one: One problem of the implementation is that I think it doesn't handle nicely the different semantics of dropPrefix compared to drop or dropWhile : whereas the latter don't fail on a premature end of the list, the dropPrefix version should fail. (The question whether it should fail with an error or with Nothing can be delegated by providing different variants of drop). The solution comes automatically when pondering what a Dropper really is: it's a *parser*. In other words, drop & friends are just functions that parse the beginning of a string and return how much has been parsed. Put differently, their feature is to ignore the "AST" resulting from a parse. type Dropper a = Parser a () -- token type a, result type () Here, I don't mean the usual (s -> (a,s)) parsers, but an implementation that fits the stream-like nature of our dropper: either a determinstic data Parser c r = Get (c -> Dropper c r) | Result r | Fail or a non-deterministic parser data Parser c a = Get (c -> Dropper c r) | Result r (Dropper c r) | Fail The latter are, of course, Koen Classen's parallel parsing processes (http://www.cs.chalmers.se/~koen/pubs/jfp04-parser.ps). Now, which ones to choose? With deterministic parsers, we loose the normal behavior of drop and dropWhile to accept lists that are too small. Thus, we choose non-deterministic parsers and implement drop with a "maximum munch" behavior -- drop as much as we can parse, but not more drop :: Dropper a -> [a] -> [a] drop p xs = case drop' p xs of Nothing -> error "drop: parse failed" Just xs -> xs where drop' Fail _ = Nothing drop' (Result _ p) xs = drop' p xs `mplus` Just xs drop' (Get f) (x:xs) = drop' (f x) xs drop' (Get _) [] = Nothing Here, the second equation of drop tries to drop more but jumps back via Maybe's `mplus` if that fails. With the usual Monad and MonadPlus instances for Parser c a, we can now write -- take while the condition is satisfied while :: (a -> Bool) -> Dropper a while = many' . satisfy where many' p = return () `mplus` p >> many' -- accept the first n characters or less first :: Int -> Dropper a first 0 = return () first n = return () `mplus` (get >> first (n-1)) -- parse a given String prefix :: Eq a => [a] -> Dropper a prefix [] = eaten prefix (x:xs) = get >>= \c -> if c == x then prefix xs else mzero By returning successes early, while and first accept an unexpected end of input. An alternative version of first that complains when not enough characters are available to drop would be exactly :: Int -> Dropper a exactly 0 = return () exactly n = get >> exactly (n-1) or exactly n = sequence_ (replicate n get) Regards, apfelmus From benja.fallenstein at gmail.com Fri Jul 6 15:58:39 2007 From: benja.fallenstein at gmail.com (Benja Fallenstein) Date: Fri Jul 6 15:52:22 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: <118245819.20070701123314@gmail.com> References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> <229B0A4C-CA11-4443-B7E7-7653CA5500EB@googlemail.com> <18054.22195.858951.944853@gargle.gargle.HOWL> <118245819.20070701123314@gmail.com> Message-ID: 2007/7/1, Bulat Ziganshin : > functionThatRemovesItsFirstArgumentFromSecondOneOrReturnsNothing`PleaseSendSuggestionsAboutFurtherImprovingThisFunctionNameToTheUnitedKongdomCambridgeMicrosoftResearchLabsSimonPeytonJones`ThankYouForUsingOurFunction`CopyrightIanLynagh`AllRightsReserved Hmm... fuctionThatRemovesItsFirstArgumentFromSecondOneOrReturnsNothing`theLicensesForMostSoftwareAreDesignedToTakeAwayYourFreedomToShareAndChangeItByContrastTheGnuGeneralPublicLicenseIsIntendedTo... Ah. Now I see why BSD is preferred in Haskell circles. :-) - Benja From apfelmus at quantentunnel.de Fri Jul 6 16:03:46 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Fri Jul 6 15:57:42 2007 Subject: Proposal #1464: add dropPrefix to Data.List In-Reply-To: References: <20070627012605.GA6337@matrix.chaos.earth.li> <20070630003528.GA12736@matrix.chaos.earth.li> Message-ID: apfelmus wrote: > what a Dropper really is: it's a *parser*. > > type Dropper a = Parser a () -- token type a, result type () > > a non-deterministic parser > > data Parser c a > = Get (c -> Dropper c r) > | Result r (Dropper c r) > | Fail > > The latter are, of course, Koen Classen's parallel parsing processes > (http://www.cs.chalmers.se/~koen/pubs/jfp04-parser.ps). > > drop with a "maximum munch" behavior > > -- drop as much as we can parse, but not more > drop :: Dropper a -> [a] -> [a] > drop p xs = case drop' p xs of > Nothing -> error "drop: parse failed" > Just xs -> xs > where > drop' Fail _ = Nothing > drop' (Result _ p) xs = drop' p xs `mplus` Just xs > drop' (Get f) (x:xs) = drop' (f x) xs > drop' (Get _) [] = Nothing To implement take/break/span, we can even abstract this code further. Assuming that we have all the goodies from Text.ParserCombinators.ReadP available, we can get the functionality of drop & friends by adapting the parser, not the traversal. The only thing we need is a "maximum munch" function maximumMunch :: Parser c r -> [c] -> r maximumMunch p = fromJust . run p Nothing where run Fail r _ = r run (Result r p) _ xs = run p (Just r) xs run (Get f) r (x:xs) = run (f x) r xs run (Get _) r [] = r (using an accumulating parameter is also more efficient here). Now, we can say drop p = maximumMunch $ p >> look take p = maximumMunch $ fst `liftM` gather p split p = maximumMunch $ (\(x,y) -> (y,x)) `liftM` gather (p >> look) Regards, apfelmus From dan.doel at gmail.com Fri Jul 6 22:19:14 2007 From: dan.doel at gmail.com (Dan Doel) Date: Fri Jul 6 22:10:48 2007 Subject: Applicative Identity Message-ID: <200707062219.14603.dan.doel@gmail.com> Hello, I ran into a tiny snag recently, attempting to write a library for a monad + transformer. If one uses MTL, it typically nice to be able to do something like the following: newtype FooT m a = FooT { runFooT :: ... } ... instances for FooT newtype Foo a = Foo { unFoo :: FooT Identity a } deriving (Functor, Monad, ...) Since the normal monad is just the case of the transformer parameterized by the Identity monad. However, we now have the Control.Applicative library, which sits in between Functors and Monads, so it seems reasonable to provide instances of those, as well. However, Identity (and, for that matter, all of the monads in MTL, I think) lacks an appropriate instance for Applicative, so generalized deriving can't be used there. On the other side, Control.Applicative has a newtype WrappedMonad, which provides such instances for an arbitrary monad. However, it has the reverse problem: There are no Monad (and related) instances for WrappedMonad. So, it seems that the full gamut of instances can't be automatically derived in this way, as the libraries currently stand. Now, this clearly isn't a dire situation, but it might be nice to fill in one or both of these gaps so the libraries play a little nicer with each other. For instance, I think the Identity instance is as simple as: instance Applicative Identity where pure = Identity f <*> a = Identity $ runIdentity f (runIdentity a) And, of course, in general, one can fill in the MTL instances as easily as: instance Applicative MTLType where pure = return (<*>) = ap Although it may be less trivial with transformers (though I assume Applicative a => Applicative (T a) aren't too hard). Many thanks, Dan Doel From wss at Cs.Nott.AC.UK Mon Jul 9 09:38:56 2007 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Mon Jul 9 09:32:27 2007 Subject: Proposal: Data.Stream Message-ID: Dear all, I just uploaded a fairly unspectacular package Data.Stream to Hackage. It implements quite a few operations on streams (infinite lists), analogous to those defined in Data.List. Sometimes it is just good to know a list is infinite. * Haddock documentation: http://www.cs.nott.ac.uk/~wss/repos/Stream/ dist/doc/html/ * Hackage homepage: http://hackage.haskell.org/cgi-bin/hackage- scripts/package/Stream-0.1 I know of a few libraries that implement this package themself (Ross Paterson's arrow library and my IOSpec spring to mind). I think it's fairly uncontroversial, and would like to see it added to base (I realize that there are also proposals to clean up base to speed up the build of ghc), or at least, the standard libraries. What's the right way to accomplish this? Send a darcs patch to Ian? Submit a trac ticket? Thanks, Wouter From ndmitchell at gmail.com Mon Jul 9 11:10:32 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jul 9 11:04:07 2007 Subject: Optimising words Message-ID: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> Hi While benchmarking a word count program I found that it wasn't running as fast as it could. I traced this back to the original definition of words, which isn't as good as it could be: This is the version in Base: words :: String -> [String] words s = case dropWhile isSpace s of "" -> [] s' -> w : words s'' where (w, s'') = break isSpace s' We can instantiate s' with s:ss, since we already pattern match: words :: String -> [String] words s = case dropWhile isSpace s of "" -> [] s:ss -> w : words s'' where (w, s'') = break isSpace (s:ss) Now we know that s is not a space, since if it was the dropWhile would have removed it. This means that we don't need to test it, and can put it straight on to w: words :: String -> [String] words s = case dropWhile isSpace s of "" -> [] s:ss -> (s:w) : words s'' where (w, s'') = break isSpace ss Now we have eliminated an extra isSpace test per character, and as it happens, isSpace is very slow. Is my reasoning correct? If so, can we make this optimisation? Thanks Neil From stefanor at cox.net Mon Jul 9 12:31:56 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Mon Jul 9 12:25:31 2007 Subject: Proposal: Data.Stream In-Reply-To: References: Message-ID: <20070709163156.GA4936@localhost.localdomain> On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > Dear all, > > I just uploaded a fairly unspectacular package Data.Stream to Hackage. It > implements quite a few operations on streams (infinite lists), analogous to > those defined in Data.List. Sometimes it is just good to know a list is > infinite. Unfortunately, there is a bit of a name collision here; Coutts, Stewart, and Leshchinskiy are pushing for a completely unrelated Data.Stream to be added to base. (Theirs is a package of operations on lists defined by generalized unfold operators.) > * Haddock documentation: > http://www.cs.nott.ac.uk/~wss/repos/Stream/dist/doc/html/ > * Hackage homepage: > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream-0.1 > > I know of a few libraries that implement this package themself (Ross > Paterson's arrow library and my IOSpec spring to mind). I think it's fairly > uncontroversial, and would like to see it added to base (I realize that > there are also proposals to clean up base to speed up the build of ghc), or > at least, the standard libraries. What's the right way to accomplish this? > Send a darcs patch to Ian? Submit a trac ticket? http://haskell.org/haskellwiki/Library_submissions (and people wonder why base is so stagnant?) Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/libraries/attachments/20070709/451910f9/attachment.bin From apfelmus at quantentunnel.de Mon Jul 9 13:46:48 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Mon Jul 9 13:40:23 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070709163156.GA4936@localhost.localdomain> References: <20070709163156.GA4936@localhost.localdomain> Message-ID: Stefan O'Rear wrote: > On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: >> >> I just uploaded a fairly unspectacular package Data.Stream to Hackage. It >> implements quite a few operations on streams (infinite lists) > > Unfortunately, there is a bit of a name collision here; Coutts, Stewart, > and Leshchinskiy are pushing for a completely unrelated Data.Stream to > be added to base. (Theirs is a package of operations on lists defined > by generalized unfold operators.) How about Data.Colist for infinite lists :) Regards, apfelmus From wss at cs.nott.ac.uk Mon Jul 9 14:15:07 2007 From: wss at cs.nott.ac.uk (Wouter Swierstra) Date: Mon Jul 9 14:08:38 2007 Subject: Proposal: Data.Stream In-Reply-To: References: <20070709163156.GA4936@localhost.localdomain> Message-ID: <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> > snip Thanks for the link, Stefan. That's exactly what I was looking for. I've created a ticket and will add the corresponding darcs patch shortly. On 9 Jul 2007, at 19:46, apfelmus wrote: >> and Leshchinskiy are pushing for a completely unrelated >> Data.Stream to >> be added to base. (Theirs is a package of operations on lists >> defined >> by generalized unfold operators.) > > How about Data.Colist for infinite lists :) The problem with calling it Colist, is that a Colist can still have a base case. I consider Colists the same as "lazy lists", that Haskell programmers are familiar with. Streams on the other hand, do *not* have a base case and are necessarily infinite. I realize there's a bit of a naming conflict with Don, Duncan, and Roman's "Data.List.Stream". Clearly, their library should have been called "Data.List.ImpredicativeChurchEncodingOfNuX.OnePlusATimesX" :) On a more serious note, this proposal has no chance if we can't agree no some name. I could almost settle for "Data.Infinite.Stream" or maybe even "Data.Infinite.List". I'd welcome any other suggestions. Wouter From stefanor at cox.net Mon Jul 9 14:27:59 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Mon Jul 9 14:21:34 2007 Subject: Proposal: Data.Stream In-Reply-To: <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> References: <20070709163156.GA4936@localhost.localdomain> <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> Message-ID: <20070709182759.GA5475@localhost.localdomain> On Mon, Jul 09, 2007 at 08:15:07PM +0200, Wouter Swierstra wrote: [snip] > I realize there's a bit of a naming conflict with Don, Duncan, and Roman's > "Data.List.Stream". Clearly, their library should have been called > "Data.List.ImpredicativeChurchEncodingOfNuX.OnePlusATimesX" :) No. There is a bit of a naming conflict with Don, Duncan, and Roman's "Data.Stream". This would be a lot easier if we had a hierarchal module namespace de facto. Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/libraries/attachments/20070709/889ae25e/attachment.bin From ndmitchell at gmail.com Mon Jul 9 15:06:23 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jul 9 14:59:57 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070709182759.GA5475@localhost.localdomain> References: <20070709163156.GA4936@localhost.localdomain> <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> <20070709182759.GA5475@localhost.localdomain> Message-ID: <404396ef0707091206t658b8553w95e617b6507a820d@mail.gmail.com> Hi Wouter, > I just uploaded a fairly unspectacular package Data.Stream to > Hackage. It implements quite a few operations on streams (infinite > lists), analogous to those defined in Data.List. Sometimes it is just > good to know a list is infinite. What is the advantage of knowing that a list is infinite? Are these versions just identical to the Data.List versions, but you know you won't encounter [] ? If so, I'm not sure there is a pressing need for this. I would have thought a much more common problem is telling the difference between an empty list and a non-empty list, rather than an infinite list and another type of list. I'm not saying that its not useful, I'm just not sure it deserves to be in the base libraries. We could add a multitude of different data types, each of which is "a list by some other name", but we'd probably end up confusing users more than helping them. As a related point, if you do use infinite lists, and are worried that your operations might cause a pattern-match error, Catch will detect this and prove it for you: http://www-users.cs.york.ac.uk/~ndm/catch/ Thanks Neil From ctm at cs.nott.ac.uk Mon Jul 9 15:53:18 2007 From: ctm at cs.nott.ac.uk (Conor McBride) Date: Mon Jul 9 15:47:00 2007 Subject: Proposal: Data.Stream In-Reply-To: References: <20070709163156.GA4936@localhost.localdomain> Message-ID: <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> Hi On 9 Jul 2007, at 18:46, apfelmus wrote: > Stefan O'Rear wrote: >> On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: >>> >>> I just uploaded a fairly unspectacular package Data.Stream to >>> Hackage. It >>> implements quite a few operations on streams (infinite lists) >> >> Unfortunately, there is a bit of a name collision here; Coutts, >> Stewart, >> and Leshchinskiy are pushing for a completely unrelated >> Data.Stream to >> be added to base. (Theirs is a package of operations on lists >> defined >> by generalized unfold operators.) > > How about Data.Colist for infinite lists :) It's such a precarious business, this. But, by way of documentation, data List x = Nil | Cons x (List x) codata CoList x = Nil | Cons x (CoList x) codata Stream x = Cons x (Stream x) Which of these things are what, if you're a scrupulous (co)programmer? | List | CoList | Stream ------------+------------+------------+------------ Functor | Yes | Yes | Yes ------------+------------+------------+------------ Applicative | Yes-nondet | Yes-nondet | | | Yes-zipmin | Yes-zip ------------+------------+------------+------------ Monad | Yes-nondet | No | Yes-zip ------------+------------+------------+------------ CoMonad | No | No | Yes ------------+------------+------------+------------ Monoid | Yes | Yes | No By Yes-nondet, I mean monadic/applicative with respect to the return/concatMap structure. By Yes-zipmin, I mean applicative via a truncating zip operation. The stream monad is not the same as the list monad: the stream join takes the diagonal of an infinite matrix. It's interesting to add columns for *nonempty* lists and colists, but I'll leave that for another time. Similarly, I can think of a few more rows... Anyhow, the point is this. The fact that Haskell's [] is big enough to represent all of these things does not mean that [] is all we need in the library. If a type is just a bucket to chuck data into, we should base the library on leaf-labelled binary trees, with a special notation for right-nested spines. But we use types to indicate computational structure and to guide the specialisation of overloaded operations (eg traverse) which exploit that structure. Types tell us what the programs are: lists and streams have different computational structure, hence different (co)programs. I'm in favour of starting a separate stream library, and I would expect it to diverge from the list library over time. All the best Conor From wss at Cs.Nott.AC.UK Mon Jul 9 16:51:35 2007 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Mon Jul 9 16:45:16 2007 Subject: Proposal: Data.Stream In-Reply-To: <404396ef0707091206t658b8553w95e617b6507a820d@mail.gmail.com> References: <20070709163156.GA4936@localhost.localdomain> <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> <20070709182759.GA5475@localhost.localdomain> <404396ef0707091206t658b8553w95e617b6507a820d@mail.gmail.com> Message-ID: <800EC6B6-1B32-411D-8649-14E7C358C248@Cs.Nott.AC.UK> > What is the advantage of knowing that a list is infinite? There is plenty of overlap with the *functions* defined in Data.List, but the *data types* are really different. Conor emphasizes this point by tabulating the different structure Streams, Lists and CoLists carry. This distinction makes perfect sense if you distinguish between data and codata. Languages such as Coq have separate types for (inductive) lists and (coinductive) streams. See the Coq standard libraries for instance: http://coq.inria.fr/V8.1/stdlib/Coq.Lists.List.html http://coq.inria.fr/V8.1/stdlib/Coq.Lists.Streams.html I've encountered the need for streams, as opposed to lists, on several occassions. I know that Ross Paterson's arrow library defines a Data.Stream as well (used in Control.Arrows.Internal). I'm sure these aren't the only places where you really want to use streams instead of lists. As far as name clashes are concerned, Andres Loeh suggested Codata.Stream. I realize this requires the creation of a new category of libraries, but its the best suggestion I've heard so far. Wouter From stefanor at cox.net Mon Jul 9 16:59:28 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Mon Jul 9 16:53:03 2007 Subject: Proposal: Data.Stream In-Reply-To: <800EC6B6-1B32-411D-8649-14E7C358C248@Cs.Nott.AC.UK> References: <20070709163156.GA4936@localhost.localdomain> <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> <20070709182759.GA5475@localhost.localdomain> <404396ef0707091206t658b8553w95e617b6507a820d@mail.gmail.com> <800EC6B6-1B32-411D-8649-14E7C358C248@Cs.Nott.AC.UK> Message-ID: <20070709205928.GA6105@localhost.localdomain> On Mon, Jul 09, 2007 at 10:51:35PM +0200, Wouter Swierstra wrote: > As far as name clashes are concerned, Andres Loeh suggested Codata.Stream. > I realize this requires the creation of a new category of libraries, but > its the best suggestion I've heard so far. Currenly, Haskell package main module names almost invariably take the form Data.* for some value of *. This utterly defeats the point of a hierarchy! I'd like to see *lots* more top level categories, on the order of sqrt(packages in hackage). Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/libraries/attachments/20070709/a2c836c8/attachment.bin From ndmitchell at gmail.com Mon Jul 9 17:44:19 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jul 9 17:37:53 2007 Subject: Optimising words In-Reply-To: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> Message-ID: <404396ef0707091444i6df4e93g486ece237c8f5a40@mail.gmail.com> Hi > An optimised version of words: > > words :: String -> [String] > words s = case dropWhile isSpace s of > "" -> [] > s:ss -> (s:w) : words s'' > where (w, s'') = break isSpace ss Thinking harder, this is an improvement, but not as good as we can get. If s'' is non-empty, then the first character must be a space, which we can drop without testing: words :: String -> [String] words s = case dropWhile isSpace s of "" -> [] s:ss -> (s:w) : words (drop1 s'') where (w, s'') = break isSpace ss drop1 [] = [] drop1 (x:xs) = xs (of course, drop1 = drop 1, but if we're going for maximum efficience :-) ) I think this now ensures that we only test each character once for being a space. Thanks Neil From duncan.coutts at worc.ox.ac.uk Mon Jul 9 18:43:09 2007 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Mon Jul 9 18:36:17 2007 Subject: Optimising words In-Reply-To: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> Message-ID: <1184020989.9278.51.camel@localhost> On Mon, 2007-07-09 at 16:10 +0100, Neil Mitchell wrote: > Hi > > While benchmarking a word count program I found that it wasn't running > as fast as it could. I traced this back to the original definition of > words, which isn't as good as it could be: [...] > Is my reasoning correct? If so, can we make this optimisation? To really convince yourself and everyone else you could compare it against the spec, for both total and partial values. For our list library re-implementation we used SmallCheck and a modified version of SmallCheck for checking partial values. It turned up lots of bugs in our code and found several instances where the current base implementations are not the same as the spec (for various good reasons). http://www.cse.unsw.edu.au/~dons/code/streams/list/tests/Strictness/BaseVsSpec.hs Duncan From dons at cse.unsw.edu.au Mon Jul 9 19:05:38 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Mon Jul 9 18:59:22 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070709163156.GA4936@localhost.localdomain> References: <20070709163156.GA4936@localhost.localdomain> Message-ID: <20070709230538.GC8884@cse.unsw.EDU.AU> stefanor: > On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > > Dear all, > > > > I just uploaded a fairly unspectacular package Data.Stream to Hackage. It > > implements quite a few operations on streams (infinite lists), analogous to > > those defined in Data.List. Sometimes it is just good to know a list is > > infinite. > > Unfortunately, there is a bit of a name collision here; Coutts, Stewart, > and Leshchinskiy are pushing for a completely unrelated Data.Stream to > be added to base. (Theirs is a package of operations on lists defined > by generalized unfold operators.) > He's talking about this module, btw, http://www.cse.unsw.edu.au/~dons/code/streams/list/Data/Stream.hs -- Don From ndmitchell at gmail.com Mon Jul 9 19:06:10 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jul 9 18:59:44 2007 Subject: Optimising words In-Reply-To: <1184020989.9278.51.camel@localhost> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> <1184020989.9278.51.camel@localhost> Message-ID: <404396ef0707091606n706c6fe2q69c9bdc904b34d36@mail.gmail.com> Hi Actually, you can go slightly better: words s = case dropWhile isSpace s of [] -> [] (s:ss) -> (s:w) : drop1 sss where (w, sss) = break isSpace ss drop1 [] = [] drop1 (x:xs) = words xs Although a good optimising compiler may make this last leap all on its own. > To really convince yourself and everyone else you could compare it > against the spec, for both total and partial values. I'm pretty convinced that I applied reasoning rules at each stage. If you have a proof, testing is irrelevant :-) I've already modified the Yhc base library with this optimisation, and done some basic testing, and nothing broke. Thanks Neil From duncan.coutts at worc.ox.ac.uk Mon Jul 9 19:30:28 2007 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Mon Jul 9 19:23:36 2007 Subject: Optimising words In-Reply-To: <404396ef0707091606n706c6fe2q69c9bdc904b34d36@mail.gmail.com> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> <1184020989.9278.51.camel@localhost> <404396ef0707091606n706c6fe2q69c9bdc904b34d36@mail.gmail.com> Message-ID: <1184023828.9278.55.camel@localhost> On Tue, 2007-07-10 at 00:06 +0100, Neil Mitchell wrote: > > To really convince yourself and everyone else you could compare it > > against the spec, for both total and partial values. > > I'm pretty convinced that I applied reasoning rules at each stage. If > you have a proof, testing is irrelevant :-) Ok, if you're sure. :-) > I've already modified the Yhc base library with this optimisation, and > done some basic testing, and nothing broke. I'm more hesitant because I've already rewritten words once and got it wrong. What's more it passed all the casual testing and quickcheck tests I used. That's because it was correct for total values, it only went wrong for partial values. It wasn't until I developed the SmallCheck on partial value tests that I discovered the bug. Duncan From ctm at cs.nott.ac.uk Mon Jul 9 19:50:06 2007 From: ctm at cs.nott.ac.uk (Conor McBride) Date: Mon Jul 9 19:43:48 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070709230538.GC8884@cse.unsw.EDU.AU> References: <20070709163156.GA4936@localhost.localdomain> <20070709230538.GC8884@cse.unsw.EDU.AU> Message-ID: <0A9B52FB-FDDF-4252-89C9-479720576E8A@cs.nott.ac.uk> Hi folks On 10 Jul 2007, at 00:05, Donald Bruce Stewart wrote: > stefanor: >> On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: >>> Dear all, >>> >>> I just uploaded a fairly unspectacular package Data.Stream to >>> Hackage. It >>> implements quite a few operations on streams (infinite lists), >>> analogous to >>> those defined in Data.List. Sometimes it is just good to know a >>> list is >>> infinite. >> >> Unfortunately, there is a bit of a name collision here; Coutts, >> Stewart, >> and Leshchinskiy are pushing for a completely unrelated >> Data.Stream to >> be added to base. (Theirs is a package of operations on lists >> defined >> by generalized unfold operators.) >> > > He's talking about this module, btw, > > http://www.cse.unsw.edu.au/~dons/code/streams/list/Data/Stream.hs This looks like lovely stuff, but I'm not sure Stream is the right name. This is a very cunning CoList package, by the looks of things, exploiting the key computational structure of codata, namely being built from coalgebras. But maybe I should shut up, as I always lose fights about names. Cheers Conor From dons at cse.unsw.edu.au Mon Jul 9 22:07:14 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Mon Jul 9 22:00:49 2007 Subject: Proposal: Data.Stream In-Reply-To: <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> Message-ID: <20070710020714.GI1142@cse.unsw.EDU.AU> ctm: > Hi > > On 9 Jul 2007, at 18:46, apfelmus wrote: > > >Stefan O'Rear wrote: > >>On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > >>> > >>>I just uploaded a fairly unspectacular package Data.Stream to > >>>Hackage. It > >>>implements quite a few operations on streams (infinite lists) > >> > >>Unfortunately, there is a bit of a name collision here; Coutts, > >>Stewart, > >>and Leshchinskiy are pushing for a completely unrelated > >>Data.Stream to > >>be added to base. (Theirs is a package of operations on lists > >>defined > >>by generalized unfold operators.) > > > >How about Data.Colist for infinite lists :) > > It's such a precarious business, this. But, by way of documentation, > > data List x = Nil | Cons x (List x) > codata CoList x = Nil | Cons x (CoList x) > codata Stream x = Cons x (Stream x) > > Which of these things are what, if you're a scrupulous (co)programmer? > > | List | CoList | Stream > ------------+------------+------------+------------ > Functor | Yes | Yes | Yes > ------------+------------+------------+------------ > Applicative | Yes-nondet | Yes-nondet | > | | Yes-zipmin | Yes-zip > ------------+------------+------------+------------ > Monad | Yes-nondet | No | Yes-zip > ------------+------------+------------+------------ > CoMonad | No | No | Yes > ------------+------------+------------+------------ > Monoid | Yes | Yes | No > > By Yes-nondet, I mean monadic/applicative with respect to the > return/concatMap structure. By Yes-zipmin, I mean applicative > via a truncating zip operation. The stream monad is not the same as > the list monad: the stream join takes the diagonal of an infinite > matrix. > > It's interesting to add columns for *nonempty* lists and colists, but > I'll > leave that for another time. Similarly, I can think of a few more > rows... > > Anyhow, the point is this. The fact that Haskell's [] is big enough to > represent all of these things does not mean that [] is all we need in > the library. If a type is just a bucket to chuck data into, we should > base > the library on leaf-labelled binary trees, with a special notation for > right-nested spines. > > But we use types to indicate computational structure and to guide > the specialisation of overloaded operations (eg traverse) which exploit > that structure. Types tell us what the programs are: lists and streams > have different computational structure, hence different (co)programs. > > I'm in favour of starting a separate stream library, and I would > expect it to diverge from the list library over time. I agree: this should probably be a separate library for now, until we see how far it grows. There's an awful lot of other things not in base: queues, difference lists, comonads, that live outside base, and I'm not sure there's a strong enough case yet that this should go into base. A standalone package would be my preference. -- Don From dons at cse.unsw.edu.au Mon Jul 9 22:13:39 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Mon Jul 9 22:07:17 2007 Subject: Optimising words In-Reply-To: <404396ef0707091606n706c6fe2q69c9bdc904b34d36@mail.gmail.com> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> <1184020989.9278.51.camel@localhost> <404396ef0707091606n706c6fe2q69c9bdc904b34d36@mail.gmail.com> Message-ID: <20070710021338.GJ1142@cse.unsw.EDU.AU> ndmitchell: > Hi > > Actually, you can go slightly better: > > words s = case dropWhile isSpace s of > [] -> [] > (s:ss) -> (s:w) : drop1 sss > where > (w, sss) = break isSpace ss > > drop1 [] = [] > drop1 (x:xs) = words xs > > Although a good optimising compiler may make this last leap all on its own. > > >To really convince yourself and everyone else you could compare it > >against the spec, for both total and partial values. > > I'm pretty convinced that I applied reasoning rules at each stage. If > you have a proof, testing is irrelevant :-) > > I've already modified the Yhc base library with this optimisation, and > done some basic testing, and nothing broke. I'd second Duncan here -- strictness properties are *really* hard, so changes to existing (H98) functions must come with both QuickCheck and strictness checking properties, before I'd be comfortable accepting them. The missing support for partial values in QuickCheck is quite a hole that needs fixing. -- Don From claus.reinke at talk21.com Mon Jul 9 20:57:03 2007 From: claus.reinke at talk21.com (Claus Reinke) Date: Tue Jul 10 03:57:32 2007 Subject: Read TypeRep? standard for typeRepKey? Message-ID: is there a reason why there is a Show TypeRep, but no Read TypeRep? and isn't it time to standardise typeRepKeys? something based on package name/version, module, name, so that one could rely on being able to read in what one writes out, and on TypeRep-based maps being compatible accross programs (at least as long as the versions match)? i was thinking about improving the reading of existentially typed data (see haskell-cafe thread) of that name, and was surprised to find that Data.Typeable doesn't quite support these things. or is there a workaround i'm missing? claus From wss at cs.nott.ac.uk Tue Jul 10 11:30:00 2007 From: wss at cs.nott.ac.uk (Wouter Swierstra) Date: Tue Jul 10 11:23:24 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070710020714.GI1142@cse.unsw.EDU.AU> References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> <20070710020714.GI1142@cse.unsw.EDU.AU> Message-ID: <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> >> >> I'm in favour of starting a separate stream library, and I would >> expect it to diverge from the list library over time. > > I agree: this should probably be a separate library for now, until we > see how far it grows. There's an awful lot of other things not in > base: > queues, difference lists, comonads, that live outside base, and I'm > not > sure there's a strong enough case yet that this should go into base. I think you're taking Conor's quote out of context. If I understand it correctly, he's replying to Neil Mitchell's post; he is arguing for a separate library different from Data.List. I don't think he objects to including it in base. Conor makes a strong case for separating lists and streams: they are different types, with fundamentally different properties. I don't claim that the proposed Stream library is the final word on the subject, but it is a theoretically solid and the content is completely uncontroversial. If nothing else, it is a starting point for encouraging more coinductive Haskell programming. For that reason, I'd argue for including it in the standard distribution. I am not too concerned whether or not this library should go into base or a separate package. I'd be happy to settle for Codata.Stream. This is easy to separate from base and does not cause any conflicts. Other libraries can be added to the Codata package, as we see fit. I would argue against calling the ByteString package Data.Stream. As tempting as it may be, the package is not about streams, but colists. There's quite some literature on the subject - see for instance Tarmo Uustalu's "Essence of Data Flow Programming" http://cs.ioc.ee/~tarmo/ papers/essence.pdf, numerous papers by Jan Rutten (http:// homepages.cwi.nl/~janr/papers/, for instance http://homepages.cwi.nl/ ~janr/papers/files-of-papers/CRM.pdf), various proceedings of CALCO, etc. I can understand that Stream sounds quite punchy and suitably coinductive, but calling this library Data.Stream will confuse certain people. I don't want to sound at all negative: I think the library is nothing short of phenomenal and "by any other name would smell as sweet". Best, Wouter From ashley at semantic.org Tue Jul 10 13:52:29 2007 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Jul 10 13:46:20 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070709163156.GA4936@localhost.localdomain> References: <20070709163156.GA4936@localhost.localdomain> Message-ID: Stefan O'Rear wrote: > Unfortunately, there is a bit of a name collision here; Coutts, Stewart, > and Leshchinskiy are pushing for a completely unrelated Data.Stream to > be added to base. (Theirs is a package of operations on lists defined > by generalized unfold operators.) And then there's monadic streams, such as sources and sinks of Word8s as might be used by file and network streams. -- Ashley Yakeley From ndmitchell at gmail.com Wed Jul 11 05:22:25 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Wed Jul 11 05:15:54 2007 Subject: Optimising words In-Reply-To: <1184048628.6064.82.camel@nmd9999> References: <404396ef0707090810l26dbcc9axff6329d0188516f7@mail.gmail.com> <1184048628.6064.82.camel@nmd9999> Message-ID: <404396ef0707110222x50678962v3b2190f5b928e354@mail.gmail.com> Hi > > Now we have eliminated an extra isSpace test per character, and as it > > happens, isSpace is very slow. > > Isn't it possible to improve isSpace, too? Yes, most definitely. But unless we improve it to the stage where it takes 0 time, its still worth eliminating useless additional calls. Thanks Neil From rl at cse.unsw.edu.au Thu Jul 12 03:43:39 2007 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Thu Jul 12 03:37:17 2007 Subject: Proposal: Data.Stream In-Reply-To: <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> <20070710020714.GI1142@cse.unsw.EDU.AU> <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> Message-ID: <4695DBAB.4080704@cse.unsw.edu.au> Wouter Swierstra wrote: >>> >>> I'm in favour of starting a separate stream library, and I would >>> expect it to diverge from the list library over time. >> >> I agree: this should probably be a separate library for now, until we >> see how far it grows. There's an awful lot of other things not in base: >> queues, difference lists, comonads, that live outside base, and I'm not >> sure there's a strong enough case yet that this should go into base. > > I think you're taking Conor's quote out of context. If I understand it > correctly, he's replying to Neil Mitchell's post; he is arguing for a > separate library different from Data.List. I don't think he objects to > including it in base. > > Conor makes a strong case for separating lists and streams: they are > different types, with fundamentally different properties. I don't claim > that the proposed Stream library is the final word on the subject, but > it is a theoretically solid and the content is completely > uncontroversial. If nothing else, it is a starting point for encouraging > more coinductive Haskell programming. For that reason, I'd argue for > including it in the standard distribution. In general, I don't think there is a "standard" definition of a stream datatype. IIUC, you see streams as necessarily infinite but there are other perfectly valid interpretations. Stream is simply a very broad term which means too many different things. In particular, I don't see why our Stream data type doesn't model streams. Anyway, IMHO to avoid confusion we shouldn't have a standard stream type at all. And, as Stefan O'Rear has pointed out, a non-base package probably shouldn't put its modules under Data (unless, perhaps, it is under Data.); in any case, the package name should appear somewhere in the path. > I am not too concerned whether or not this library should go into base > or a separate package. I'd be happy to settle for Codata.Stream. This is > easy to separate from base and does not cause any conflicts. Other > libraries can be added to the Codata package, as we see fit. > > I would argue against calling the ByteString package Data.Stream. As > tempting as it may be, the package is not about streams, but colists. I have to admit that I don't really understand the distinction between Haskell's lists and colists (or, in general, datatypes in Haskell and codatatypes). To me, lists are inductive and colists are coinductive, i.e., the former are the least and the latter the greatest fixed point of the underlying functor. Thus, Haskell's list datatype actually models colists (and algebraic datatypes in Haskell are coinductive by default). This thread seems to implicitly assume a different interpretation of the prefix "co" but I don't really understand what this interpretation is. As to Data.Stream, I don't think that the ByteString library actually includes a module with that name Our stream fusion based list library does but that's really quite experimental and not really released, I think. However, our streams will have to go into base at some point as they are already used by the ByteString and NDP packages (even though each has its own copy) and we plan on using them for Data.Array and friends as well. The module doesn't really have to be called Data.Stream, though. Roman From stefan at cs.uu.nl Thu Jul 12 09:41:07 2007 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Thu Jul 12 09:34:34 2007 Subject: Proposal: Data.Stream In-Reply-To: <4695DBAB.4080704@cse.unsw.edu.au> References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> <20070710020714.GI1142@cse.unsw.EDU.AU> <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> <4695DBAB.4080704@cse.unsw.edu.au> Message-ID: Roman, > I have to admit that I don't really understand the distinction > between Haskell's lists and colists (or, in general, datatypes in > Haskell and codatatypes). To me, lists are inductive and colists > are coinductive, i.e., the former are the least and the latter the > greatest fixed point of the underlying functor. Thus, Haskell's > list datatype actually models colists (and algebraic datatypes in > Haskell are coinductive by default). This thread seems to > implicitly assume a different interpretation of the prefix "co" but > I don't really understand what this interpretation is. In Haskell, coinductive types and inductive types coincide. So, Haskell's [] models both lists and colists. Cheers, Stefan From rl at cse.unsw.edu.au Thu Jul 12 10:36:49 2007 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Thu Jul 12 10:30:31 2007 Subject: Proposal: Data.Stream In-Reply-To: References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> <20070710020714.GI1142@cse.unsw.EDU.AU> <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> <4695DBAB.4080704@cse.unsw.edu.au> Message-ID: <46963C81.3000309@cse.unsw.edu.au> Stefan Holdermans wrote: > > In Haskell, coinductive types and inductive types coincide. So, > Haskell's [] models both lists and colists. In what sense do they coincide? Inductive lists are a subset of coinductive ones but that's not Haskell-specific. In fact, I can perfectly well define inductive lists in Haskell: data IList a = Nil | Cons a !(IList a) Roman From igloo at earth.li Thu Jul 12 16:03:32 2007 From: igloo at earth.li (Ian Lynagh) Date: Thu Jul 12 15:56:57 2007 Subject: Proposal: Data.Stream In-Reply-To: References: Message-ID: <20070712200332.GA31333@matrix.chaos.earth.li> On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > > * Hackage homepage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream-0.1 > > fairly uncontroversial, and would like to see it added to base (I > realize that there are also proposals to clean up base to speed up > the build of ghc), Yes indeed; I don't see any reason for adding this to the base library while we're trying to make base smaller. > or at least, the standard libraries. I'm not sure what you mean by "the standard libraries". It wouldn't be needed to build GHC, so it wouldn't be a GHC "core lib". Other than that, if it's in hackage then it's as standard as any other library! A "stream" (or "colist" or whatever) package seems reasonable to me. (The http://www.cse.unsw.edu.au/~dons/code/streams/list/Data/Stream.hs module also looks too specific to use such a generic name, in my opinion). Thanks Ian From igloo at earth.li Thu Jul 12 16:07:04 2007 From: igloo at earth.li (Ian Lynagh) Date: Thu Jul 12 16:00:29 2007 Subject: Proposal: Data.Stream In-Reply-To: <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> References: <20070709163156.GA4936@localhost.localdomain> <688C2116-DF55-4EE8-9905-7D6E1F5F49D3@cs.nott.ac.uk> Message-ID: <20070712200704.GB31333@matrix.chaos.earth.li> On Mon, Jul 09, 2007 at 08:15:07PM +0200, Wouter Swierstra wrote: > > maybe even "Data.Infinite.List". Data.List.Infinite would make more sense than this, I think (but I don't necessarily prefer it to Data.Stream or other suggestions that have been made). Thanks Ian From dons at cse.unsw.edu.au Thu Jul 12 21:18:27 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Thu Jul 12 21:11:58 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070712200332.GA31333@matrix.chaos.earth.li> References: <20070712200332.GA31333@matrix.chaos.earth.li> Message-ID: <20070713011827.GD20548@cse.unsw.EDU.AU> igloo: > On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > > > > * Hackage homepage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream-0.1 > > > > fairly uncontroversial, and would like to see it added to base (I > > realize that there are also proposals to clean up base to speed up > > the build of ghc), > > Yes indeed; I don't see any reason for adding this to the base library > while we're trying to make base smaller. > > > or at least, the standard libraries. > > I'm not sure what you mean by "the standard libraries". It wouldn't be > needed to build GHC, so it wouldn't be a GHC "core lib". > > Other than that, if it's in hackage then it's as standard as any other > library! > > A "stream" (or "colist" or whatever) package seems reasonable to me. > > > (The http://www.cse.unsw.edu.au/~dons/code/streams/list/Data/Stream.hs > module also looks too specific to use such a generic name, in my > opinion). > Yes, I agree. Probably if it will be the base for fusion in ndp arrays, bytestrings and lists, we can find a tag to put between Data.* and *.Stream. -- Don From stefanor at cox.net Thu Jul 12 21:28:02 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Thu Jul 12 21:21:31 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070713011827.GD20548@cse.unsw.EDU.AU> References: <20070712200332.GA31333@matrix.chaos.earth.li> <20070713011827.GD20548@cse.unsw.EDU.AU> Message-ID: <20070713012802.GA13806@localhost.localdomain> On Fri, Jul 13, 2007 at 11:18:27AM +1000, Donald Bruce Stewart wrote: > igloo: > > On Mon, Jul 09, 2007 at 03:38:56PM +0200, Wouter Swierstra wrote: > > > > > > * Hackage homepage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream-0.1 > > > > > > fairly uncontroversial, and would like to see it added to base (I > > > realize that there are also proposals to clean up base to speed up > > > the build of ghc), > > > > Yes indeed; I don't see any reason for adding this to the base library > > while we're trying to make base smaller. > > > > > or at least, the standard libraries. > > > > I'm not sure what you mean by "the standard libraries". It wouldn't be > > needed to build GHC, so it wouldn't be a GHC "core lib". > > > > Other than that, if it's in hackage then it's as standard as any other > > library! > > > > A "stream" (or "colist" or whatever) package seems reasonable to me. > > > > > > (The http://www.cse.unsw.edu.au/~dons/code/streams/list/Data/Stream.hs > > module also looks too specific to use such a generic name, in my > > opinion). > > > > Yes, I agree. Probably if it will be the base for fusion in ndp arrays, > bytestrings and lists, we can find a tag to put between Data.* and > *.Stream. What does Data. mean in a language where almost everything is a data type? I think we should move abolish that subtree entirely, moving the major subtrees (Binary, Generics, Array, ...) to top level, and creating a bunch of new categories (Numeric, Collection, etc) for the remaining modules. (ByteString can go in Text) Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/libraries/attachments/20070712/9de8ed12/attachment.bin From Malcolm.Wallace at cs.york.ac.uk Fri Jul 13 05:54:13 2007 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Fri Jul 13 05:52:12 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070713012802.GA13806@localhost.localdomain> References: <20070712200332.GA31333@matrix.chaos.earth.li> <20070713011827.GD20548@cse.unsw.EDU.AU> <20070713012802.GA13806@localhost.localdomain> Message-ID: <20070713105413.1e7adaaf.Malcolm.Wallace@cs.york.ac.uk> Stefan O'Rear wrote: > What does Data. mean in a language where almost everything is a data > type? And I thought in Haskell almost everything was a function... > I think we should move abolish that subtree entirely, moving > the major subtrees (Binary, Generics, Array, ...) to top level, and > creating a bunch of new categories (Numeric, Collection, etc) for the > remaining modules. (ByteString can go in Text) I couldn't disagree more strongly. _Very_ few libraries are about providing general-purpose data structures. The vast majority of libraries are task-oriented: OpenGL for graphical rendering, HaXml/HXT/pretty for document processing, HUnit/QuickCheck for testing, process/unix/win32/filepath/directory for accessing OS facilities, the list goes on. Looking at http://www.haskell.org/ghc/docs/latest/html/libraries/index.html the Data.* hierarchy is a mere 2/11th of the modules listed (which admittedly covers only a tiny selection of packages available, but these are the ones distributed with ghc). Regards, Malcolm From wss at Cs.Nott.AC.UK Fri Jul 13 10:20:56 2007 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Fri Jul 13 10:17:13 2007 Subject: Proposal: Data.Stream In-Reply-To: <20070712200332.GA31333@matrix.chaos.earth.li> References: <20070712200332.GA31333@matrix.chaos.earth.li> Message-ID: Hi Ian, > >> or at least, the standard libraries. > > I'm not sure what you mean by "the standard libraries". It wouldn't be > needed to build GHC, so it wouldn't be a GHC "core lib". > > Other than that, if it's in hackage then it's as standard as any other > library! Thanks for clearing that up. But why do libraries like mtl or QuickCheck work "out of the box" (on my distribution) without having installed them from Hackage? Maybe this is just me being a bit thick, but there seems to be at least several packages, beyond base, that come bundled with ghc. That's what I'd refer to as "standard libraries" - the term comes from the link to http://haskell.cs.yale.edu/ghc/docs/latest/html/libraries/ index.html on the haskell.org frontpage. Ideally, that's where I'd like to see a separate package for Codata.Stream pop up. Best, Wouter This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. From wss at Cs.Nott.AC.UK Fri Jul 13 10:20:53 2007 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Fri Jul 13 10:17:15 2007 Subject: Proposal: Data.Stream In-Reply-To: <4695DBAB.4080704@cse.unsw.edu.au> References: <20070709163156.GA4936@localhost.localdomain> <4D86CA27-E9C1-43CB-914C-591A12779F12@cs.nott.ac.uk> <20070710020714.GI1142@cse.unsw.EDU.AU> <27949989-BE41-4908-8779-2424A3BE7482@cs.nott.ac.uk> <4695DBAB.4080704@cse.unsw.edu.au> Message-ID: <83E09ABF-E532-4771-8D2B-FF0B13EBEE23@Cs.Nott.AC.UK> > In general, I don't think there is a "standard" definition of a > stream datatype. IIUC, you see streams as necessarily infinite but > there are other perfectly valid interpretations. Stream is simply a > very broad term which means too many different things. In > particular, I don't see why our Stream data type doesn't model > streams. I have to admit that, in general, "stream" can mean a lot of different things. A quick google gives all kinds of results, from streaming media to bandwidth benchmarks. However, there is quite a lot of research, closely related to functional programming, with a clear consensus of what a stream is: \nu X . A * X (or equivalently, functions from Nat -> A) Personally, I think this gives a very clear definition of what a stream is that leaves nothing open to interpretation. Of course people are free to call their data types whatever they like, but in this instance it may be advisable to at least be aware of any related work. Of course, your streams (what I would call colists) can be used to model this type. There are very compelling reasons not to do this: streams are a comonad, colists are not; streams and colists have are really different instances of Monad (just look at the definition of return for both cases); colists are a monoid, streams are not; I'm sure Conor can come up with plenty of other reasons. The important thing is, although you can model streams using colists (I'm using my terminology here), it may not be desirable to do so. It can sometimes pay to be as precise as possible about your types. > I have to admit that I don't really understand the distinction > between Haskell's lists and colists (or, in general, datatypes in > Haskell and codatatypes). To me, lists are inductive and colists > are coinductive, i.e., the former are the least and the latter the > greatest fixed point of the underlying functor. Thus, Haskell's > list datatype actually models colists (and algebraic datatypes in > Haskell are coinductive by default). This thread seems to > implicitly assume a different interpretation of the prefix "co" but > I don't really understand what this interpretation is. That's exactly the way I think about this as well. In the context of Haskell, the distinction is not so clear. When you write "data" as a programmer, you sometimes really mean codata (as in my Stream type). On the other hand, there are occassions where you have an (implicit) invariant in your head stating you will never construct infinite terms, and hence it's safe to assume that a fold will terminate, for instance. Then you really mean data - and not codata. Haskell does not support this separation: both data and codata are introduced by the same language construct. It's a real pity sometimes; if we really care about the types of our programs, I think this is a distinction worth making. All the best, Wouter This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. From ndmitchell at gmail.com Fri Jul 13 10:41:26 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Fri Jul 13 10:34:49 2007 Subject: Proposal: Data.Stream In-Reply-To: References: <20070712200332.GA31333@matrix.chaos.earth.li> Message-ID: <404396ef0707130741r6f36528fkb8344868b17c3f99@mail.gmail.com> Hi > But why do libraries like mtl or QuickCheck work "out of the box" (on > my distribution) without having installed them from Hackage? Your distribution has chosen to include them. In general, the only package which is guaranteed to be present is base, plus filepath from 6.6.1 onwards, plus many fragments of base from 6.8 onwards. > Ideally, that's where I'd like to see a separate package for > Codata.Stream pop up. Is it fair to say that your intention is not to give a level of blessing or whatever to this package, but to lower the barrier to use for your library? If so, things like cabal-install will nearly eliminate the difference between libraries shipped and libraries installed - wait for the tools to catch up and bundling won't be necessary. Thanks Neil From cdsmith at twu.net Fri Jul 13 11:46:04 2007 From: cdsmith at twu.net (Chris Smith) Date: Fri Jul 13 11:39:07 2007 Subject: Proposal: Data.Stream References: <20070712200332.GA31333@matrix.chaos.earth.li> <20070713011827.GD20548@cse.unsw.EDU.AU> Message-ID: <006501c7c564$ec64a9d0$6700a8c0@KYA> > igloo: >> I'm not sure what you mean by "the standard libraries". It wouldn't >> be needed to build GHC, so it wouldn't be a GHC "core lib". >> >> Other than that, if it's in hackage then it's as standard as any >> other library! There does seem to be another level of "standard-ness" than this. Specifically, it would involve the library being distributed with GHC distributions and included in the documentation at http://haskell.org/ghc/docs/latest/html/libraries/. The base split is great, but I hope that it doesn't mean the standard libraries (in this sense) are being phased out, or that libraries or documentation will be made harder for Haskell newcomers to find and use. -- Chris Smith From igloo at earth.li Fri Jul 13 14:20:21 2007 From: igloo at earth.li (Ian Lynagh) Date: Fri Jul 13 14:13:44 2007 Subject: Updated cross-platform IPv6 support In-Reply-To: <4682DA20.9000601@serpentine.com> References: <467d9ad6.1d1e640a.3824.ffffd7f6@mx.google.com> <20070627112504.GA12200@matrix.chaos.earth.li> <4682AEB3.40500@serpentine.com> <4682DA20.9000601@serpentine.com> Message-ID: <20070713182021.GA20665@matrix.chaos.earth.li> On Wed, Jun 27, 2007 at 02:44:00PM -0700, Bryan O'Sullivan wrote: > > darcs get --partial http://darcs.serpentine.com/network Patches pushed; thanks! Ian From bos at serpentine.com Fri Jul 13 14:20:28 2007 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri Jul 13 14:14:19 2007 Subject: Updated cross-platform IPv6 support In-Reply-To: <20070713182021.GA20665@matrix.chaos.earth.li> References: <467d9ad6.1d1e640a.3824.ffffd7f6@mx.google.com> <20070627112504.GA12200@matrix.chaos.earth.li> <4682AEB3.40500@serpentine.com> <4682DA20.9000601@serpentine.com> <20070713182021.GA20665@matrix.chaos.earth.li> Message-ID: <4697C26C.2010503@serpentine.com> Ian Lynagh wrote: >> darcs get --partial http://darcs.serpentine.com/network > > Patches pushed; Thank you! Hi all, This is proposal 1535: http://hackage.haskell.org/trac/ghc/ticket/1535 This comes out of http://hackage.haskell.org/trac/ghc/ticket/1490 where, in createDirectoryIfMissing, we use stat to determine if a directory exists. (I don't think catching an exception is a possibility in this case, as mkdir returns EEXIST if "pathname already exists (not necessarily as a directory)", so we can't distinguish between the directory already existing and a file existing with the name that we want. Short of doing something ugly like trying to make (path ++ "/.") and seeing if we get ENOTDIR, anyway). The problem is that mingw's stat succeeds for C:\ and C:\foo but fails for C: and C:\foo\. The current code strips a trailing \ before calling stat, and thus fails if asked to create C:\ (which we always do if "make parents" is true, and of course this path could be given explicitly by a user). What we want is something like if isDrive x then addTrailingPathSeparator x else dropTrailingPathSeparator x except filepath currently doesn't export isDrive, for reasons I'm not entirely clear on. Thus I propose exposing the *Drive functions from the filepath package. The patch, attached to the bug, is rather trivial as the code is already written, tested etc, just not exposed. Let's try until 21 July for a discussion period. Please try to accompany any objections with a (clean) alternative solution to the original problem. Thanks Ian From bulat.ziganshin at gmail.com Sat Jul 14 15:01:13 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sat Jul 14 14:59:48 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <20070714123932.GA4572@matrix.chaos.earth.li> References: <20070714123932.GA4572@matrix.chaos.earth.li> Message-ID: <491280032.20070714230113@gmail.com> Hello Ian, Saturday, July 14, 2007, 4:39:33 PM, you wrote: > The problem is that mingw's stat succeeds for C:\ and C:\foo but fails > for C: and C:\foo\. The current code strips a trailing \ before calling > stat, and thus fails if asked to create C:\ (which we always do if "make > parents" is true, and of course this path could be given explicitly by a > user). > What we want is something like > if isDrive x > then addTrailingPathSeparator x > else dropTrailingPathSeparator x well, i don't know FilePath library but if it has some sort of canonizeFilename function, this function should make this check yourself and shouldn't strip trailing '\' after ':' for obvious reason - 'c:' and 'c:\' are different directories -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From frederik at a5.repetae.net Sat Jul 14 18:31:55 2007 From: frederik at a5.repetae.net (Frederik Eaton) Date: Sat Jul 14 18:25:16 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs Message-ID: <20070714223155.GD18263@a5.repetae.net> Hello, I am interested in implementing some multi-threaded algorithms in Haskell. I have run into some documentation dead-ends. The documentation in GHC.Conc is what I get when I search for "ghc pseq" on google, but it doesn't document pseq and some other functions: pseq par forkOnIO childHandler ensureIOManagerIsRunning In particular, I wonder: How is pseq different from seq? Under what circumstances is it used? I have looked at the source code so I see that it is implemented in terms of 'seq' and 'lazy': > -- "pseq" is defined a bit weirdly (see below) > -- > -- The reason for the strange "lazy" call is that > -- it fools the compiler into thinking that pseq and par are non-strict in > -- their second argument (even if it inlines pseq at the call site). > -- If it thinks pseq is strict in "y", then it often evaluates > -- "y" before "x", which is totally wrong. > > pseq :: a -> b -> b > pseq x y = x `seq` lazy y - does this mean pseq should be used instead of 'seq' when I want the first argument to be evaluated first? And I am also curious about the others, although par seems to be documented in Control.Parallel. Also, the following functions in Control.Parallel.Strategies are not documented, at least in Haddock: (>|) :: Done -> Done -> Done (>||) :: Done -> Done -> Done using :: a -> Strategy a -> a demanding :: a -> Done -> a sparking :: a -> Done -> a sPar :: a -> Strategy b sSeq :: a -> Strategy b r0 :: Strategy a rwhnf :: Strategy a rnf :: Strategy a ($|) :: (a -> b) -> Strategy a -> a -> b ($||) :: (a -> b) -> Strategy a -> a -> b (.|) :: (b -> c) -> Strategy b -> (a -> b) -> a -> c (.||) :: (b -> c) -> Strategy b -> (a -> b) -> a -> c (-|) :: (a -> b) -> Strategy b -> (b -> c) -> a -> c (-||) :: (a -> b) -> Strategy b -> (b -> c) -> a -> c seqPair :: Strategy a -> Strategy b -> Strategy (a, b) parPair :: Strategy a -> Strategy b -> Strategy (a, b) seqTriple :: Strategy a -> Strategy b -> Strategy c -> Strategy (a, b, c) parTriple :: Strategy a -> Strategy b -> Strategy c -> Strategy (a, b, c) fstPairFstList :: NFData a => Strategy [(a, b)] force :: NFData a => a -> a sforce :: NFData a => a -> b -> b The types Done and Strategy or the class NFData and related classes in this module are also not documented in Haddock. If there is a paper which defines all of these then it would be nice to have a link to the paper in the module's documentation, for people to use until the module's documentation itself can be updated. As an aside, if you've read this far then you may know the answer to a related question: is there a way to query how many processors the current machine has? I am implementing a parallel sort, and in cases such as sorting where one can decompose an algorithm into an arbitrarily large number of threads, I am wondering how to tell what the maximum useful number of threads is (usually this will be some increasing function of the number of CPUs) to avoid the overhead of spawning a thread when it is not needed. (I'm about to read "Lightweight concurrency primitives for GHC" by Li et al, if that's the right place to look) Thanks, Frederik -- http://ofb.net/~frederik/ From igloo at earth.li Sat Jul 14 19:47:15 2007 From: igloo at earth.li (Ian Lynagh) Date: Sat Jul 14 19:40:33 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <491280032.20070714230113@gmail.com> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> Message-ID: <20070714234715.GA22345@matrix.chaos.earth.li> Hi Bulat, On Sat, Jul 14, 2007 at 11:01:13PM +0400, Bulat Ziganshin wrote: > > well, i don't know FilePath library but if it has some sort of > canonizeFilename function, this function should make this check > yourself and shouldn't strip trailing '\' after ':' for obvious reason > - 'c:' and 'c:\' are different directories The normalise function doesn't affect whether or not there is a trailing separator: Prelude System.FilePath.Windows> normalise "c:" "C:" Prelude System.FilePath.Windows> normalise "c:\\" "C:\\" Prelude System.FilePath.Windows> normalise "c:\\foo" "C:\\foo" Prelude System.FilePath.Windows> normalise "c:\\foo\\" "C:\\foo\\" Thanks Ian From dons at cse.unsw.edu.au Sat Jul 14 20:02:13 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Sat Jul 14 19:55:32 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs In-Reply-To: <20070714223155.GD18263@a5.repetae.net> References: <20070714223155.GD18263@a5.repetae.net> Message-ID: <20070715000213.GF12378@cse.unsw.EDU.AU> frederik: > Hello, > > I am interested in implementing some multi-threaded algorithms in > Haskell. > > I have run into some documentation dead-ends. The documentation in > GHC.Conc is what I get when I search for "ghc pseq" on google, but it > doesn't document pseq and some other functions: > > pseq > par These guys are documented in the parallel Haskell stuff (and should be in the haddocks!!) http://www.haskell.org/ghc/dist/current/docs/users_guide/lang-parallel.html > forkOnIO > childHandler > ensureIOManagerIsRunning Not sure about these last ones. > In particular, I wonder: How is pseq different from seq? Under what > circumstances is it used? I have looked at the source code so I see > that it is implemented in terms of 'seq' and 'lazy': > > > -- "pseq" is defined a bit weirdly (see below) > > -- > > -- The reason for the strange "lazy" call is that > > -- it fools the compiler into thinking that pseq and par are non-strict in > > -- their second argument (even if it inlines pseq at the call site). > > -- If it thinks pseq is strict in "y", then it often evaluates > > -- "y" before "x", which is totally wrong. > > > > pseq :: a -> b -> b > > pseq x y = x `seq` lazy y > > - does this mean pseq should be used instead of 'seq' when I want the > first argument to be evaluated first? And I am also curious about the > others, although par seems to be documented in Control.Parallel. > > Also, the following functions in Control.Parallel.Strategies are not > documented, at least in Haddock: Yes, I don't understand either why Control.Parallel.Strategies isn't documented. Please file a bug report! > As an aside, if you've read this far then you may know the answer to a > related question: is there a way to query how many processors the > current machine has? I am implementing a parallel sort, and in cases There's no builtin way, but there's an open trac ticket for this. > such as sorting where one can decompose an algorithm into an > arbitrarily large number of threads, I am wondering how to tell what > the maximum useful number of threads is (usually this will be some > increasing function of the number of CPUs) to avoid the overhead of > spawning a thread when it is not needed. (I'm about to read > "Lightweight concurrency primitives for GHC" by Li et al, if that's > the right place to look) I usually just ensure the 'n' value is available as a command line flag to my program. -- Don From eivuokko at gmail.com Sat Jul 14 20:29:09 2007 From: eivuokko at gmail.com (Esa Ilari Vuokko) Date: Sat Jul 14 20:22:26 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs In-Reply-To: <20070714223155.GD18263@a5.repetae.net> References: <20070714223155.GD18263@a5.repetae.net> Message-ID: Hi, On 7/15/07, Frederik Eaton wrote: > As an aside, if you've read this far then you may know the answer to a > related question: is there a way to query how many processors the > current machine has? I am implementing a parallel sort, and in cases In Windows there's Win32-package and System.Win32.getSystemInfo (field siNumberOfProcessors.) HTH, Esa From bulat.ziganshin at gmail.com Sun Jul 15 04:01:00 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jul 15 04:00:08 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <20070714234715.GA22345@matrix.chaos.earth.li> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> <20070714234715.GA22345@matrix.chaos.earth.li> Message-ID: <1782715722.20070715120100@gmail.com> Hello Ian, Sunday, July 15, 2007, 3:47:15 AM, you wrote: >> well, i don't know FilePath library but if it has some sort of >> canonizeFilename function, this function should make this check >> yourself and shouldn't strip trailing '\' after ':' for obvious reason >> - 'c:' and 'c:\' are different directories > The normalise function doesn't affect whether or not there is a trailing > separator: > Prelude System.FilePath.Windows> normalise "c:" > "C:" > Prelude System.FilePath.Windows> normalise "c:\\" > "C:\\" > Prelude System.FilePath.Windows> normalise "c:\\foo" > "C:\\foo" > Prelude System.FilePath.Windows> normalise "c:\\foo\\" > "C:\\foo\\" well, i mean that FilePath libarry should contain some sort of normalization function that omits '\' at end of path unless it's a ":\" combination. in other words, function that you now write should be a part of FilePath library because it's a standard functionality although this probably will not solve your problem if you need tro be compatible with existing FilePath version -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From igloo at earth.li Sun Jul 15 07:03:20 2007 From: igloo at earth.li (Ian Lynagh) Date: Sun Jul 15 06:56:37 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <1782715722.20070715120100@gmail.com> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> <20070714234715.GA22345@matrix.chaos.earth.li> <1782715722.20070715120100@gmail.com> Message-ID: <20070715110319.GA29549@matrix.chaos.earth.li> Hi Bulat, On Sun, Jul 15, 2007 at 12:01:00PM +0400, Bulat Ziganshin wrote: > > well, i mean that FilePath libarry should contain some sort of > normalization function that omits '\' at end of path unless it's a > ":\" combination. in other words, function that you now write should > be a part of FilePath library because it's a standard functionality Ah, I see. Yes, that would work too, although I think Neil and I would prefer the more general *Drive functions being exposed (shout if I'm wrong, Neil). > although this probably will not solve your problem if you need tro be > compatible with existing FilePath version We don't. Thanks Ian From bulat.ziganshin at gmail.com Sun Jul 15 09:33:57 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jul 15 09:32:47 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <20070715110319.GA29549@matrix.chaos.earth.li> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> <20070714234715.GA22345@matrix.chaos.earth.li> <1782715722.20070715120100@gmail.com> <20070715110319.GA29549@matrix.chaos.earth.li> Message-ID: <189751109.20070715173357@gmail.com> Hello Ian, Sunday, July 15, 2007, 3:03:20 PM, you wrote: >> well, i mean that FilePath libarry should contain some sort of >> normalization function that omits '\' at end of path unless it's a >> ":\" combination. in other words, function that you now write should >> be a part of FilePath library because it's a standard functionality > Ah, I see. Yes, that would work too, although I think Neil and I would > prefer the more general *Drive functions being exposed (shout if I'm > wrong, Neil). with direct use of *Drive function your code will become windows-specific. if the same functionality will be implemented inside FilePath library, you will use only portable canonize* function nevertheless, exporting *Drive and other internal functions will be great anyway - it's hard to predict all the possible ways of using library -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From igloo at earth.li Sun Jul 15 09:46:44 2007 From: igloo at earth.li (Ian Lynagh) Date: Sun Jul 15 09:40:00 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <189751109.20070715173357@gmail.com> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> <20070714234715.GA22345@matrix.chaos.earth.li> <1782715722.20070715120100@gmail.com> <20070715110319.GA29549@matrix.chaos.earth.li> <189751109.20070715173357@gmail.com> Message-ID: <20070715134644.GA662@matrix.chaos.earth.li> Hi Bulat, On Sun, Jul 15, 2007 at 05:33:57PM +0400, Bulat Ziganshin wrote: > > Sunday, July 15, 2007, 3:03:20 PM, you wrote: > > >> well, i mean that FilePath libarry should contain some sort of > >> normalization function that omits '\' at end of path unless it's a > >> ":\" combination. in other words, function that you now write should > >> be a part of FilePath library because it's a standard functionality > > > Ah, I see. Yes, that would work too, although I think Neil and I would > > prefer the more general *Drive functions being exposed (shout if I'm > > wrong, Neil). > > with direct use of *Drive function your code will become > windows-specific. Not so! Prelude System.FilePath.Posix> isDrive "" True Prelude System.FilePath.Posix> isDrive "/" True Prelude System.FilePath.Posix> isDrive "/foo" False Prelude System.FilePath.Posix> isDrive "/foo/" False > nevertheless, exporting *Drive and other internal functions will be > great anyway - it's hard to predict all the possible ways of using > library I agree. Thanks Ian From ctm at cs.nott.ac.uk Sun Jul 15 15:20:25 2007 From: ctm at cs.nott.ac.uk (Conor McBride) Date: Sun Jul 15 15:13:47 2007 Subject: Functor (Either a) Message-ID: <2A2DE7E1-C2C6-4D66-82A4-5C000B6621EB@cs.nott.ac.uk> Hi all I read TFM http://haskell.org/ghc/docs/latest/html/libraries/base/ Prelude.html#t%3AFunctor and it does rather suggest that there's an instance of Functor for (Either a). Yet, ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Prelude> fmap not (Right True) :1:0: No instance for (Functor (Either a)) arising from use of `fmap' at :1:0-20 Am I being dim? Conor From igloo at earth.li Sun Jul 15 15:27:51 2007 From: igloo at earth.li (Ian Lynagh) Date: Sun Jul 15 15:21:06 2007 Subject: Functor (Either a) In-Reply-To: <2A2DE7E1-C2C6-4D66-82A4-5C000B6621EB@cs.nott.ac.uk> References: <2A2DE7E1-C2C6-4D66-82A4-5C000B6621EB@cs.nott.ac.uk> Message-ID: <20070715192751.GA9353@matrix.chaos.earth.li> Hi Conor, On Sun, Jul 15, 2007 at 08:20:25PM +0100, Conor McBride wrote: > > and it does rather suggest that there's an instance of Functor for > (Either a). Yet, > > Prelude> fmap not (Right True) > > :1:0: > No instance for (Functor (Either a)) > arising from use of `fmap' at :1:0-20 It's in Control.Monad.Instances: Prelude> :m + Control.Monad.Instances Prelude Control.Monad.Instances> fmap not (Right True) Right False I don't know if there's a way of deducing that from the haddock documentation. Thanks Ian From bos at serpentine.com Sun Jul 15 18:16:17 2007 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sun Jul 15 18:10:09 2007 Subject: Functor (Either a) In-Reply-To: <20070715192751.GA9353@matrix.chaos.earth.li> References: <2A2DE7E1-C2C6-4D66-82A4-5C000B6621EB@cs.nott.ac.uk> <20070715192751.GA9353@matrix.chaos.earth.li> Message-ID: <469A9CB1.7040000@serpentine.com> Ian Lynagh wrote: > It's in Control.Monad.Instances: > > Prelude> :m + Control.Monad.Instances > Prelude Control.Monad.Instances> fmap not (Right True) > Right False > > I don't know if there's a way of deducing that from the haddock > documentation. There doesn't seem to be. I didn't discover that module until I finally sat down and spent 15 minutes trying to answer the question "why is importing, or omitting, some completely unrelated mtl module influencing my program's ability to compile?" Wonderful as haddock is, there's no substitute for having the GHC sources and half of hackage unpacked on your hard disk, to make possible a few rounds of "grep -r". References: <2A2DE7E1-C2C6-4D66-82A4-5C000B6621EB@cs.nott.ac.uk> <20070715192751.GA9353@matrix.chaos.earth.li> <469A9CB1.7040000@serpentine.com> Message-ID: <272086103.20070716095835@gmail.com> Hello Bryan, Monday, July 16, 2007, 2:16:17 AM, you wrote: > There doesn't seem to be. I didn't discover that module until I finally > sat down and spent 15 minutes trying to answer the question "why is > importing, or omitting, some completely unrelated mtl module influencing > my program's ability to compile?" instances are standard answer. they are as viruses, imperceptibly filtering through any import lists :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From sascha.boehme at gmx.de Mon Jul 16 07:49:31 2007 From: sascha.boehme at gmx.de (Sascha =?iso-8859-1?Q?B=F6hme?=) Date: Mon Jul 16 07:44:10 2007 Subject: System.Posix.User.getAllUserEntries can be called only once Message-ID: <20070716114931.GG11748@eloas> Hello, are there special constraints why the function System.Posix.User.getAllUserEntries of the unix package can be called only once? Beginning with the second call, it only returns the empty list. Thus, this function cannot be used for a long running process which needs to query the user database from time to time, again and again. Thanks, Sascha From claus.reinke at talk21.com Mon Jul 16 08:03:51 2007 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jul 16 07:57:26 2007 Subject: Control.Concurrent.Chan: how do i close a channel? Message-ID: in principle, Chan looks like a nice way to do pipes within haskell code, or to avoid unsafeInterleaveIO, in combination with getChanContents (which explicitly mentions hGetContents in its API doc). however, i seem to be missing a way to close a channel? am i misinterpreting this library? claus From dons at cse.unsw.edu.au Mon Jul 16 08:18:20 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Mon Jul 16 08:11:35 2007 Subject: Control.Concurrent.Chan: how do i close a channel? In-Reply-To: References: Message-ID: <20070716121820.GA19094@cse.unsw.EDU.AU> claus.reinke: > in principle, Chan looks like a nice way to do pipes within > haskell code, or to avoid unsafeInterleaveIO, in combination > with getChanContents (which explicitly mentions hGetContents > in its API doc). > > however, i seem to be missing a way to close a channel? > am i misinterpreting this library? They're not attached to Handles -- that's the IO loop that does the writing to the Chan's job -- so they dont' really have a 'close'. When you're done writing, just stop writing. I often use Chan (Maybe a), with Nothing to tell the reader thread that EOF is reached -- perhaps something like that is what you're looking for? -- Don From claus.reinke at talk21.com Mon Jul 16 08:32:24 2007 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jul 16 08:25:54 2007 Subject: Control.Concurrent.Chan: how do i close a channel? References: <20070716121820.GA19094@cse.unsw.EDU.AU> Message-ID: >> however, i seem to be missing a way to close a channel? >> am i misinterpreting this library? > > They're not attached to Handles -- that's the IO loop that does the > writing to the Chan's job -- so they dont' really have a 'close'. i was indeed looking for a haskell-internal replacement for Handles, being somewhat surprised that i can't seem to create unattached Handles with the uls (usual library suspects;-). think pipes: if an external process takes input via a handle and provides output via a handle, the haskell equivalent could do the same via a Chan, so it'd be easy to write mixed pipes. > When you're done writing, just stop writing. yes, but any user of getChanContents will be left hanging! that kind of function doesn't really work well without a way to tell it that it has nothing more to wait for. > I often use Chan (Maybe a), with Nothing to tell the reader thread that > EOF is reached -- perhaps something like that is what you're looking > for? yes. but that would add another slight indirection, and it still doesn't make getChanContents itself any more useable. if you "often" have to modify/expand the API when you use it, perhaps there is something missing in that API? the "much like hGetContents" comment does seem to suggest that as well. claus From igloo at earth.li Mon Jul 16 08:46:43 2007 From: igloo at earth.li (Ian Lynagh) Date: Mon Jul 16 08:39:56 2007 Subject: System.Posix.User.getAllUserEntries can be called only once In-Reply-To: <20070716114931.GG11748@eloas> References: <20070716114931.GG11748@eloas> Message-ID: <20070716124642.GA21407@matrix.chaos.earth.li> On Mon, Jul 16, 2007 at 01:49:31PM +0200, Sascha B?hme wrote: > > are there special constraints why the function > > System.Posix.User.getAllUserEntries > > of the unix package can be called only once? It's a bug, fixed in the HEAD. To do it in 6.6.1 you'd have to call C's setpwent and endpwent yourself, before and after calling getAllUserEntries. Thanks Ian From claus.reinke at talk21.com Mon Jul 16 10:21:16 2007 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jul 16 10:14:50 2007 Subject: Control.Concurrent.Chan: how do i close a channel? References: <20070716121820.GA19094@cse.unsw.EDU.AU> Message-ID: > think pipes: if an external process takes input via a handle and provides > output via a handle, the haskell equivalent could do the same via a Chan, > so it'd be easy to write mixed pipes. for illustration, here is the kind of utility that i find missing in System.Process, using the Maybe lifting of Chan contents. this doesn't do any error handling, but allows for simple-minded pipes like: $ ghc -e 'cmd "cat" >|> fun (map Data.Char.toUpper) >|> cmd "grep WO" >>= \(i,o)->i "hello\nWORLD\n">>o >>= putStr' ProcUtils.hs WORLD $ ghc -e 'cmd "ls" >|> fun (map Data.Char.toUpper) >|> cmd "grep .HS" >>= \(i,o)->o >>= putStr' ProcUtils.hs PROCUTILS.HS X.HS Y.HS Z.HS lifting contents to Maybe is easy enough, i just find it hard to see the use-case for getChanContents without such lifting or any way to close Chans? claus ---------------------------------------------------pipe utitlities import System.Process import Control.Concurrent import System.IO import Data.Maybe cmd c = runInteractiveCommand c >>= \(i,o,e,p)->return (hPutStr i,hGetContents o) fun f = do i <- newChan o <- newChan forkIO $ fromChan i >>= toChan o . f return (toChan i,fromChan o) infixr >|> c1 >|> c2 = do (i1,o1) <- c1 (i2,o2) <- c2 forkIO $ o1 >>= i2 return (i1,o2) toChan c str = writeList2Chan c $ map Just str ++ [Nothing] fromChan c = getChanContents c >>= return . map fromJust . takeWhile isJust From wnoise at ofb.net Mon Jul 16 11:52:13 2007 From: wnoise at ofb.net (Aaron Denney) Date: Mon Jul 16 11:48:18 2007 Subject: Control.Concurrent.Chan: how do i close a channel? References: <20070716121820.GA19094@cse.unsw.EDU.AU> Message-ID: On 2007-07-16, Claus Reinke wrote: >> When you're done writing, just stop writing. > > yes, but any user of getChanContents will be left hanging! that kind > of function doesn't really work well without a way to tell it that it has > nothing more to wait for. Yeah, getChanContents is not suitable for streams that may end. A note in the documentation to this effect may be useful. Some sort of unfold-like combinator to lazily read from a Chan (Maybe a) into a list may be useful instead. -- Aaron Denney -><- From Malcolm.Wallace at cs.york.ac.uk Mon Jul 16 12:13:38 2007 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Mon Jul 16 12:07:01 2007 Subject: Proposal: expose the drive functions in the filepath package In-Reply-To: <20070715110319.GA29549@matrix.chaos.earth.li> References: <20070714123932.GA4572@matrix.chaos.earth.li> <491280032.20070714230113@gmail.com> <20070714234715.GA22345@matrix.chaos.earth.li> <1782715722.20070715120100@gmail.com> <20070715110319.GA29549@matrix.chaos.earth.li> Message-ID: <20070716171338.568efbc6.Malcolm.Wallace@cs.york.ac.uk> Ian Lynagh wrote: > Ah, I see. Yes, that would work too, although I think Neil and I would > prefer the more general *Drive functions being exposed (shout if I'm > wrong, Neil). Neil is on holiday. Regards, Malcolm From Malcolm.Wallace at cs.york.ac.uk Mon Jul 16 12:16:29 2007 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Mon Jul 16 12:12:00 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs In-Reply-To: <20070714223155.GD18263@a5.repetae.net> References: <20070714223155.GD18263@a5.repetae.net> Message-ID: <20070716171629.69289a6c.Malcolm.Wallace@cs.york.ac.uk> Frederik Eaton wrote: > In particular, I wonder: How is pseq different from seq? Under what > circumstances is it used? `pseq` is a "genuine" operational sequence operator. Haskell'98's x `seq` y does not guarantee that x is evaluated to WHNF before y, whereas `pseq` does guarantee exactly this. Regards, Malcolm From dons at cse.unsw.edu.au Mon Jul 16 22:53:34 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Mon Jul 16 22:46:56 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs In-Reply-To: <20070716171629.69289a6c.Malcolm.Wallace@cs.york.ac.uk> References: <20070714223155.GD18263@a5.repetae.net> <20070716171629.69289a6c.Malcolm.Wallace@cs.york.ac.uk> Message-ID: <20070717025327.GL9525@cse.unsw.EDU.AU> Malcolm.Wallace: > Frederik Eaton wrote: > > > In particular, I wonder: How is pseq different from seq? Under what > > circumstances is it used? > > `pseq` is a "genuine" operational sequence operator. Haskell'98's > x `seq` y > does not guarantee that x is evaluated to WHNF before y, whereas `pseq` > does guarantee exactly this. Good to see the documentation for parallel strategies is improved! http://www.haskell.org/ghc/dist/current/docs/parallel/Control-Parallel-Strategies.html what can we do to make it easier to get into concurrent and parallel haskell programming? Its really one of the killer features, but is under-documented and under-blogged-about. Meanwhile the erlang guys use parMap in every blog I see, despite their slow compiler and awful string support ;) -- Don (pondering how to steal parallel programming mindshare) From dons at cse.unsw.edu.au Tue Jul 17 01:54:01 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Tue Jul 17 01:47:16 2007 Subject: ANNOUNCE: Haskell Hackathon 07 II: Freiburg: Oct 5-7 Message-ID: <20070717055401.GA12073@cse.unsw.EDU.AU> ------------------------------------------------------------------------ Hac 2007 II Haskell Hackathon 2007 II October 5-7, 2007 Freiburg, Germany http://haskell.org/haskellwiki/Hac_2007_II ------------------------------------------------------------------------ We are pleased to announce the 2nd Haskell Hackathon for 2007! The event will be held over 3 days, October 5-7 2007, at the University of Freiburg, in Germany, after ICFP. The plan is to hack on serious Haskell infrastructure, tools, libraries and compilers. To attend please register, and get ready to hack those lambdas! Code to hack on: * Hackage * Cabal * Porting foreign libraries * Bug squashing * You decide! At the last Hackathon, in January at Oxford, resulted in: * Cabal, Hackage, Haddock improvements * Data.Binary and DeferedBinary libraries * GHCi debugger improvements * ghc-api interface from Emacs * Crypto lirbary improvments * A native Haskell 'tar' implementation * And more And we hope to be similarly productive this time around. Before you attend, do start thinking and familiarising yourself with 1 or 2 projects you wish to work on, to ensure no wasted effort during the Hackathon. A list of possible projects is available on the website == Registration: We ask that you register you interest. Follow the instructions on the registration page: http://haskell.org/haskellwiki/Hac_2007_II/Register Once you've registered, do add your info to the attendees self-organising page, http://haskell.org/haskellwiki/Hac_2007_II/Attendees if you are looking to share costs, or meet up prior to the hackathon, with other attendees. N.B. if you already expressed interest via the wiki, do confirm by registering `officially' anyway. == Important dates: Hackathon: October 5-7, 2007 == Organisers: Duncan Coutts Ian Lynagh Don Stewart With local arrangements courtesy: Stefan Wehr Phillip Heidegger From simonmarhaskell at gmail.com Tue Jul 17 05:34:31 2007 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Tue Jul 17 05:27:49 2007 Subject: documentation in GHC.Conc, Control.Parallel.Strategies; querying number of CPUs In-Reply-To: <20070717025327.GL9525@cse.unsw.EDU.AU> References: <20070714223155.GD18263@a5.repetae.net> <20070716171629.69289a6c.Malcolm.Wallace@cs.york.ac.uk> <20070717025327.GL9525@cse.unsw.EDU.AU> Message-ID: <469C8D27.5050500@gmail.com> Donald Bruce Stewart wrote: > what can we do to make it easier to get into concurrent and parallel > haskell programming? Its really one of the killer features, but is > under-documented and under-blogged-about. We have some new tools coming, perhaps for GHC 6.8. Michael Adams has ported the GramSim parallel performance-analysis tools to GHC, so we can generate graphs of runnable/running/blocked threads over time, amongst other things. This should make it much easier to get a handle on parallel performance, which I think is the area that we're most lacking at the moment. I'll try to get the patches in as soon as possible. Cheers, Simon From golubovsky at gmail.com Tue Jul 17 12:52:02 2007 From: golubovsky at gmail.com (Dimitry Golubovsky) Date: Tue Jul 17 12:45:11 2007 Subject: Proposal: add exeExtension to System.Info Message-ID: Hi, While adopting my older program to the newer (GHC 6.6) infrastructure, I came across the issue: OS-dependent functions like exeExtension are missing in the newer version of the FilePath package. I checked with Neil who currently maintains FilePath, and he agreed with me on this idea. I am proposing to add the following to the System.Info module (which seems to be the best place to collect OS-specific things) - the code was found in Distribution.Compat.FilePath and slightly modified (#if directive) in the same way as the current System.FilePath distinguishes between Posix and Windows interfaces: ------------------------------- begin -------------------------------------- -- | Extension for executable files -- (typically @\"\"@ on Unix and @\"exe\"@ on Windows or OS\/2) exeExtension :: String #if defined(mingw32_HOST_OS) || defined(__MINGW32__) exeExtension = "exe" #else exeExtension = "" #endif -- | Extension for object files. For GHC and NHC the extension is @\"o\"@. -- Hugs uses either @\"o\"@ or @\"obj\"@ depending on the used C compiler. objExtension :: String objExtension = "o" -- | Extension for dynamically linked (or shared) libraries -- (typically @\"so\"@ on Unix and @\"dll\"@ on Windows) dllExtension :: String #if defined(mingw32_HOST_OS) || defined(__MINGW32__) dllExtension = "dll" #else dllExtension = "so" #endif ------------------------------- end -------------------------------------- Thanks -- Dimitry Golubovsky Anywhere on the Web From bulat.ziganshin at gmail.com Tue Jul 17 13:41:44 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jul 17 13:40:52 2007 Subject: Proposal: add exeExtension to System.Info In-Reply-To: References: Message-ID: <972028542.20070717214144@gmail.com> Hello Dimitry, Tuesday, July 17, 2007, 8:52:02 PM, you wrote: > I am proposing to add the following to the System.Info module (which > seems to be the best place to collect OS-specific things) - the code why not to add them to FilePath library instead? base isn't good place for any improvements because one cannot use newer base versions without upgrading GHC itself -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From zednenem at psualum.com Tue Jul 17 15:33:31 2007 From: zednenem at psualum.com (David Menendez) Date: Tue Jul 17 15:26:37 2007 Subject: Control.Concurrent.Chan: how do i close a channel? In-Reply-To: References: <20070716121820.GA19094@cse.unsw.EDU.AU> Message-ID: <49a77b7a0707171233l7714d45dqe9827cbf7e0dc93b@mail.gmail.com> On 7/16/07, Claus Reinke wrote: > > I often use Chan (Maybe a), with Nothing to tell the reader thread that > > EOF is reached -- perhaps something like that is what you're looking > > for? > > yes. but that would add another slight indirection, and it still doesn't > make getChanContents itself any more useable. if you "often" have to > modify/expand the API when you use it, perhaps there is something > missing in that API? the "much like hGetContents" comment does > seem to suggest that as well. If STM is available, you could use a TChan for content and a TVar for signalling. Here's a quick sketch: import Control.Concurrent.STM import Control.Monad import System.IO.Unsafe (unsafeInterleaveIO) import qualified Control.Exception as X data ClosableChan a = CC { open :: TVar Bool, chan :: TChan a } newCChan :: STM (ClosableChan a) newCChan = liftM2 CC (newTVar True) newTChan writeCChan :: ClosableChan a -> a -> STM () writeCChan c a = writeTChan (chan c) a closeCChan :: ClosableChan a -> STM () closeCChan c = writeTVar (open c) False readCChan :: ClosableChan a -> STM a readCChan c = readTChan (chan c) `orElse` (readTVar (open c) >>= \b -> if b then retry else error "Closed") getCChanContents :: ClosableChan a -> IO [a] getCChanContents c = unsafeInterleaveIO $ (do hd <- atomically (readCChan c) tl <- getCChanContents c return (hd:tl) ) `X.catch` \_ -> return [] From wnoise at ofb.net Tue