Re: [Haskell-cafe] (Co/Contra)Functor and Comonad
On 12/23/10 16:43, Mario Blažević wrote: Cofunctor and Comonad IMHO, as you say, there is only one design of cofunctor. class Cofunctor cf where cofmap :: (a - b) - cf b - cf a The only question is capitalization and spelling.* Since there are multiple designs of Comonad floating around, it'll take slightly more design work to make sure a standard design works for everyone. -Isaac *(CoFunctor or Cofunctor, cofmap or comap etc. IMHO your choices are fine. And to choose a module to put it in.). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functor = Applicative = Monad
On 12/14/10 03:13, John Smith wrote: I would like to formally propose that Monad become a subclass of Applicative, with a call for consensus by 1 February. The change is described on the wiki at http://haskell.org/haskellwiki/Functor-Applicative-Monad_Proposal, That page isn't written as a proposal yet, it's written as a bunch of ideas. I would be happy to see something along the lines of Bas van Dijk's work http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/14740 . -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Rewriting a famous library and using the same name: pros and cons
On 06/08/10 11:08, Don Stewart wrote: Are there any other arguments I'm missing? Also parsec3 had an issue as an upgrade that it was slower at runtime (at least for a few years). (and some people were using parsec in the real world for performance-critical applications.) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Proposal to solve Haskell's MPTC dilemma
On 05/29/10 21:24, Carlos Camarao wrote: The situation is as if we a FD: Well, that is indeed equivalent here in the second argument of class F, but I constructed the example to show an issue in the class's *first* argument. Notice you needed to add type-signatures, on the functions you named g -- in particular their first arguments -- to make the example work with only FDs? module C where class F a b | a-b where f :: a - b class O a where o :: a module P where import C; instance F Bool Bool where f = not instance O Bool where o = True g:: Bool - Bool g = f k::Bool k = g o module Q where import C instance F Int Bool where f = even instance O Int where o = 0 g::Int-Bool g = f k :: Bool k = g o you can inline these k-definitions into module Main and it will work (modulo importing C). module Main where import C import P import Q main = do { print (((f :: Bool - Bool) o) :: Bool); print (((f :: Int - Bool) o) :: Bool) } These are two different expressions that are being printed, because :: Bool - Bool is different from :: Int - Bool. In my example of using your proposal, one cannot inline in the same way, if I understand correctly (the inlining would cause ambiguity errors -- unless of course the above distinct type-signatures are added). If your proposal was able to require those -- and only those -- bits of type signatures that were essential to resolve the above ambiguity; for example, the ( :: Int) below, module Q where import C instance F Int Bool where f = even instance O Int where o = 0 k = f (o :: Int) , then I would be fine with your proposal (but then I suspect it would have to be equivalent to FDs -- or in other words, that it's not really practical to change your proposal to have that effect). I stand by my assertion that the same expression means different things in two different modules is undesirable, (and that I suspect but am unsure that this undesirability is named incoherent instances). I'm trying to work out whether it's possible to violate the invariants of a Map by using your extension (having it select a different instance in two different places, given the same type).. I think, no it is not possible for Ord or any single-parameter typeclass, though there might be some kind of issues with multi-parameter typeclasses, if the library relies on a FD-style relationship between two class type-parameters and then two someones each add an instance that together violate that implied FD-relationship (which is allowed under your scheme, unlike if there was an actual FD). Er, odd, I need to play with some actual FD code to think about this, but I'm too sleepy / busy packing for a trip. Did any of the above make sense to you? It's fine if some didn't, type systems are complicated... and please point out if something I said was outright wrong. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal to solve Haskell's MPTC dilemma
On 05/27/10 17:42, Carlos Camarao wrote: On Thu, May 27, 2010 at 5:43 PM, David Menendezd...@zednenem.com wrote: On Thu, May 27, 2010 at 10:39 AM, Carlos Camarao carlos.cama...@gmail.com wrote: Isaac Dupree: Your proposal appears to allow /incoherent/ instance selection. This means that an expression can be well-typed in one module, and well-typed in another module, but have different semantics in the two modules. For example (drawing from above discussion) : module C where class F a b where f :: a - b class O a where o :: a module P where import C instance F Bool Bool where f = not instance O Bool where o = True k :: Bool k = f o module Q where import C instance F Int Bool where f = even instance O Int where o = 0 k :: Bool k = f o module Main where import P import Q -- (here, all four instances are in scope) main = do { print P.k ; print Q.k } -- should result, according to your proposal, in -- False -- True -- , am I correct? If qualified importation of k from both P and from Q was specified, we would have two *distinct* terms, P.k and Q.k. I think Isaac's point is that P.k and Q.k have the same definition (f o). If they don't produce the same value, then referential transparency is lost. -- Dave Menendezd...@zednenem.com http://www.eyrie.org/~zednenem/http://www.eyrie.org/%7Ezednenem/ The definitions of P.k and Q.k are textually the same but the contexts are different. f and o denote distinct values in P and Q. Thus, P.k and Q.k don't have the same definition. Oh, I guess you are correct: it is like defaulting: it is a similar effect where the same expression means different things in two different modules as if you had default (Int) in one, and default (Bool) in the other. Except: Defaulting according to the standard only works in combination with the 8 (or however many it is) standard classes; and defaulting in Haskell is already a bit poorly designed / frowned upon / annoying that it's specified per-module when nothing else in the language is*.(that's a rather surmountable argument) It may be worth reading the GHC user's guide which attempts to explain the difference between incoherent and non-incoherent instance selection, http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#instance-overlap I didn't read both it and your paper closely enough that I'm sure anymore whether GHC devs would think your extension would require or imply -XIncoherentInstances ... my intuition was that IncoherentInstances would be implied... *(it's nice when you can substitute any use of a variable, such as P.k, with the expression that it is defined as -- i.e. the expression written so that it refer to the same identifiers, not a purely textual substitution -- but in main above, you can't write [assuming you imported C] print (f o) because it will be rejected for ambiguity. (Now, there is already an instance-related situation like this where Main imports two different modules that define instances that overlap in an incompatible way, such as two different instances for Functor (Either e) -- not everyone is happy about how GHC handles this, but at least those overlaps are totally useless and could perhaps legitimately result in a compile error if they're even imported into the same module.)) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal to solve Haskell's MPTC dilemma
On 05/26/10 15:42, Carlos Camarao wrote: What do you think? I think you are proposing using the current set of instances in scope in order to remove ambiguity. Am I right? ..I read the haskell-cafe thread so far, and it looks like I'm right. This is what I'll add to what's been said so far: Your proposal appears to allow /incoherent/ instance selection. This means that an expression can be well-typed in one module, and well-typed in another module, but have different semantics in the two modules. For example (drawing from above discussion) : module C where class F a b where f :: a - b class O a where o :: a module P where import C instance F Bool Bool where f = not instance O Bool where o = True k :: Bool k = f o module Q where import C instance F Int Bool where f = even instance O Int where o = 0 k :: Bool k = f o module Main where import P import Q -- (here, all four instances are in scope) main = do { print P.k ; print Q.k } -- should result, according to your proposal, in -- False -- True -- , am I correct? Also, in your paper, example 2 includes m = (m1 * m2) * m3 and you state In Example 2, there is no means of specializing type variable c0 occurring in the type of m to Matrix. I suggest that there is an appropriate such means, namely, to write m = (m1 * m2 :: Matrix) * m3 . (Could the paper address how that solution falls short? Are there other cases in which there is more than just a little syntactical convenience at stake?, or is even that much added code too much for some use-case?) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 04/20/10 06:56, Simon Marlow wrote: On 09/04/2010 12:14, Bertram Felgenhauer wrote: Simon Marlow wrote: On 09/04/2010 09:40, Bertram Felgenhauer wrote: timeout t io = mask $ \restore - do result- newEmptyMVar tid- forkIO $ restore (io= putMVar result) threadDelay t `onException` killThread tid killThread tid tryTakeMVar result I'm worried about the case when this function is called with exceptions already blocked. Then 'restore' will be the identity, and exceptions will continue to be blocked inside the forked thread. You could argue that this is the responsibility of the whole chain of callers (who'd have to supply their own 'restore' functions that will have to be incorporated into the 'io' action), but that goes against modularity. In my opinion there's a valid demand for an escape hatch out of the blocked exception state for newly forked threads. It could be baked into a variant of the forkIO primitive, say forkIOwithUnblock :: ((IO a - IO a) - IO b) - IO ThreadId I agree with the argument here. However, forkIOWithUnblock reintroduces the wormhole, which is bad. The existing System.Timeout.timeout does it the other way around: the forked thread sleeps and then sends an exception to the main thread. This version work if exceptions are masked, regardless of whether we have forkIOWithUnblock. Arguably the fact that System.Timeout.timeout uses an exception is a visible part of its implementation: the caller must be prepared for this, so it is not unreasonable for the caller to also ensure that exceptions are unmasked. But it does mean that a library cannot use System.Timeout.timeout invisibly as part of its implementation. If we had forkIOWithUnblock that would solve this case too, as the library code can use a private thread in which exceptions are unmasked. This is quite a nice solution too, since a private ThreadId is not visible to anyone else and hence cannot be the target of any unexpected exceptions. So I think I'm convinced that forkIOWithUnblock is necessary. It's a shame that it can be misused, but I don't see a way to avoid that. [forkIOWithUnblock in the implementation of 'timeout'?] I thought that System.Timeout.timeout runs the IO in the original thread for a good reason. Was it just so that it could receive asynchronous exceptions correctly? Or also so that myThreadID returned the correct value? If just the former is what we're concerned about, we *could* make it behave differently when exceptions are unblocked vs. when it's uninterruptible, except that they can be restored to an unblocked state somewhere within the io. [Oh wait, Simon was suggesting that the library should run forkIOWithUnblock as a wrapper to its use of 'timeout'.] Yes, that sounds relatively safe. None of the exceptions thrown to the original thread will be discharged unexpectedly as a result of this unblocking, because of the forkIO. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Move MonadIO to base
On 04/19/10 02:15, Anders Kaseorg wrote: I would be very happy to get the simpler interface to work, because it’s Haskell 98. However, if I write joinIO m = morphIO (\w - m= w) morphIO' f = joinIO (f return) and define catch using morphIO' instead of morphIO: m `catch` h = morphIO $ \w - w m `Control.Exception.catch` \e - w (h e) m `catch'` h = morphIO' $ \w - w m `Control.Exception.catch` \e - w (h e) then catch' fails to actually catch anything: *Main throwIO NonTermination `catch` \NonTermination - return moo moo *Main throwIO NonTermination `catch'` \NonTermination - return moo *** Exception:loop Am I doing something wrong? Well, let's see what happens if we apply it to the fairly easy instance MonadMorphIO IO where morphIO f = f id then joinIO m = morphIO (\w - m = w) = (\w - m = w) (id) = m = id = join m morphIO' f = joinIO (f return) = join (f return) morphIO = f id m `catch` h = morphIO $ \w - w m `Control.Exception.catch` \e - w (h e) [w = id] = id m `Control.Exception.catch` \e - id (h e) m `catch'` h = morphIO' $ \w - w m `Control.Exception.catch` \e - w (h e) [w = return] = join (return m `Control.Exception.catch` \e - return (h e)) Do you see the difference? The effects are sequenced in different places. The return/join pair moves all the effects *outside* the operations such as catch... thus defeating the entire purpose of morphIO. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 04/08/10 04:23, Simon Marlow wrote: On 07/04/2010 18:54, Isaac Dupree wrote: On 04/07/10 11:12, Simon Marlow wrote: It's possible to mis-use the API, e.g. getUnmask = mask return ...incidentally, unmask a = mask (\restore - return restore) = (\restore - restore a) That doesn't work, as in it can't be used to unmask exceptions when they are masked. The 'restore' you get just restores the state to its current, i.e. masked, state. oh good point. Then you're right, anyone who was trying to work around it would be doing something obviously wrong. mask :: ((IO a - IO a) - IO b) - IO b It needs to be :: ((forall a. IO a - IO a) - IO b) - IO b so that you can use 'restore' on two different pieces of IO if you need to. (alas, this requires not just Rank2Types but RankNTypes. Also, it doesn't cure the loophole. But I think it's still essential.) Sigh, yes I suppose that's true, but I've never encountered a case where I needed to call unmask more than once, let alone at different types, within the scope of a mask. Anyone else? FWIW, the function I made up to test my theory was as below; I haven't thought of any actual uses yet: finally2 :: IO a1 - IO a2 - IO b - IO (a1, a2) finally2 a1 a2 b = mask $ \restore - do r - (liftM2 (,) (restore a1) (restore a2)) `onException` b b return r -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 04/07/10 17:50, Simon Marlow wrote: On 07/04/10 21:23, Bas van Dijk wrote: On Wed, Apr 7, 2010 at 5:12 PM, Simon Marlowmarlo...@gmail.com wrote: Comments? I really like this design. One question, are you planning to write the MVar utility functions using 'mask' or using 'nonInterruptibleMask'? As in: withMVar :: MVar a - (a - IO b) - IO b withMVar m f = whichMask? $ \restore - do a- takeMVar m b- restore (f a) `onException` putMVar m a putMVar m a return b Definitely the ordinary interruptible mask. It is the intention that the new nonInterruptibleMask is only used in exceptional circumstances where dealing with asynchronous exceptions emerging from blocking operations would be impossible to deal with. The more unwieldy name was chosen deliberately for this reason. The danger with nonInterruptibleMask is that it is all too easy to write a program that will be unresponsive to Ctrl-C, for example. It should be used with great care - for example when there is reason to believe that any blocking operations that would otherwise be interruptible will only block for short bounded periods. it could be called unsafeNonInterruptibleMask (unsafeUninterruptibleMask?)... after all, 'mask' is uninterruptible for most/many operations, that's its point, but if we put 'mask' and 'nonInterruptibleMask' next to each other, I think people are likely to be confused (..less so if there's good Haddock documentation. But i'm fearing the 'forkOS' debacle where people still wrongly recommend that because the name sounds good...) I still would like to see examples of where it's needed, because I slightly suspect that wrapping possibly-blocking operations in an exception handler that does something appropriate, along with ordinary 'mask', might be sufficient... But I expect to be proved wrong; I just haven't figured out how to prove myself wrong. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 04/08/10 19:56, Bas van Dijk wrote: Control.Concurrent.Thread.fork is a similar and simpler example of why nonInterruptibleMask is needed: http://hackage.haskell.org/packages/archive/threads/0.1/doc/html/src/Control-Concurrent-Thread.html#fork If an asynchronous exception is thrown during the 'putMVar res' any waiters on the thread will never be woken up. OK, thanks for the link! In fact, [tell me if my reasoning is wrong...], in that fork-definition, the 'putMVar' will never block, because there is only putMVar one for each created MVar. I seem to remember that any execution of putMVar that does not *actually* block is guaranteed not be interrupted by asynchronous exceptions (if within a Control.Exception.block) -- which would be sufficient. Is my memory right or wrong? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 04/07/10 11:12, Simon Marlow wrote: It's possible to mis-use the API, e.g. getUnmask = mask return ...incidentally, unmask a = mask (\restore - return restore) = (\restore - restore a) mask :: ((IO a - IO a) - IO b) - IO b It needs to be :: ((forall a. IO a - IO a) - IO b) - IO b so that you can use 'restore' on two different pieces of IO if you need to. (alas, this requires not just Rank2Types but RankNTypes. Also, it doesn't cure the loophole. But I think it's still essential.) nonInterruptibleMask :: ((IO a - IO a) - IO b) - IO b nonInterruptibleMask_ :: IO a - IO a which is just like mask/mask_, except that blocking operations (e.g. takeMVar) are not interruptible. What would be an appropriate use of this? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Asynchronous exception wormholes kill modularity
On 03/25/10 12:36, Simon Marlow wrote: I'd also be amenable to having block/unblock count nesting levels instead, I don't think it would be too hard to implement and it wouldn't require any changes at the library level. Wasn't there a reason that it didn't nest? I think it was that operations that block-as-in-takeMVar, for an unbounded length of time, are always supposed to C.Exception.unblock and in fact be unblocked within that operation. Otherwise the thread might never receive its asynchronous exceptions. Thus, if within a C.Exception.block, you call an IO that might block, such as takeMVar, modifyMVar_, or an arbitrary IO x argument to your function, then you must take care to handle its exceptions (for example, in the case of modifyMVar_'s implementation, to rollback the MVar to its previous value). -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Documentation design
(for reference, here's the blog-post I wrote that inspired me to ask this list for advice. I'll explain everything in this email anyway though. http://haddock2009.wordpress.com/2009/06/23/how-to-navigate-your-code/ ) My challenge: getting to know an existing code-base quickly and easily, so that I can hack on it. Haddock and HsColour are already pretty helpful at this, but they could be more helpful. (haddock with --ignore-all-exports, i.e. cabal haddock --internal, especially) My dream situation: both haddock-pages and hscolour-pages would be super-hyperlinked and super-readable. For example, haddock would list all a module's definitions, not just its exports. In HsColoured source, every identifier would link to its definition or the haddockumentation of its definition. and so forth. It would be so much easier to generate and browse this in HTML, than to get an IDE working, and it would be so much more readable than a mere text-editor (even with syntax hilighting) and quicker clicking on hyperlinks than grepping for everything. Actually I don't have the resources to worry about designing any HsColour stuff right now (its current design is mainly just a lexeme highlighter). But, with your advices, I can design an improvement on Haddock's ignore-exports mode, which currently has a few shortcomings: 1. you can't tell which identifiers in a module are exported 2. it doesn't document a module's re-exports at all 3. it still obeys {-# OPTIONS_HADDOCK hide #-} et al, even when they're not appropriate for reading documentation of internals 4. 2+3 means that some things may be found nowhere in the documentation at all! Not quite satisfying for something invoked by `cabal haddock --internal`. (Here's a haddock-generated page you can look at so you can figure out the formatting-details I'll be describing: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html and its source code http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html ) The ideal haddockumentation-formatting for this purpose isn't quite obvious though. For example, sometimes you want to think about a module in terms of its abstract interface, but sometimes you want to figure out how it's implemented (without reverting completely to text based code browsing). Maybe a compromise of some sort would be good. so... Here's a proposal, for a new mode (`haddock --all-internal`?, to be invoked by `cabal haddock --internal` rather than --internal's current effect of ignore-all-exports) : Files with no explicit export list can be treated as-is anyway. For all files that have an explicit export list, generate the synopsis-of-exports near the top, as usual. But have the index link, generally, to where functions are originally defined (modulo being from a non-internally-documented separate package, where it should link to the appropriate place), and have the fuller documentation below be a compilation of the identifiers *defined* in this module. Actually that would need some revision because the sections and subsections -- *, -- **, etc. defined in the export-list in the .hs, actually are displayed 1. above the table of contents, linking to places in 2. the full list of definitions. Which might be defined in the module in a different order than they're listed in the export list. Why not add the sections into the synopsis? In this case, instead of adding them to the main doc section. But hmm... in ordinary non-internal documentation, would it be nice to *additionally* have the sections marked in the synopsis (in addition to in the Contents and in the main docs section)? Maybe this mode should also abstain from hiding any module, because that would cause missing docs. Etc. Questions? Comments? Opinions? Does anyone want this feature, and/or not think it's particularly useful? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Definition of tail recursive wrt Folds
Tillmann Rendel wrote: Now consider a variant: if' a b c = if a then b else c variant x = if' (p x) (f x) (g x) I would say that if' has the same operational behavior as an if-then-else expressions, and therefore, (f x) and (g x) are still tail cails, even if they now appear in the context of another function call. yes, and the if' is also a tail-call. I guess I would say that (f x) and (g x) are tail-calls out of if' and if' is a tail-call out of variant. I think that a definition of tail calls in Haskell should take the strictness properties of functions into account. sometimes the optimizer does this, and makes more functions behave like tail- call than you'd expect! But sometimes it doesn't. And I think that this makes for a much more friendly migration path. Instead of telling people: No, forget about tail calls, in Haskell, you need something else, you could tell them: Yes, tail calls are the way to go, but in Haskell, they look different. Sometimes you do need something different though... if you're *producing* a lazy data structure. foldr f z (x:xs) = x `f` (foldr f z xs) If f is : then this is an efficient non-tail-call (later someone will demand the later parts of the list) whereas foldl f z (x:xs) = foldl f (z `f` x) xs is tail-recursion, which means that it needs to traverse the whole input-list before producing *any* output -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haddock GSoC project
Okay, I've written a draft Haddock-GSOC application: would any of you like to review it / suggest how it could be improved? (or should I just submit it to Google?) I'm particularly wondering whether my proposed time-line seems realistic. -Isaac * What is the goal of the project you propose to do? To improve Haddock, the Haskell documentation tool, both substantively in the short term and to be better factored in the long term. * Can you give some more detailed design of what precisely you intend to achieve? Resolve many Haddock Trac tickets. Specific projects: Make cross-package documentation work; and refactor the comment-parsing out of GHC and into the Haddock code-base. * What deliverables do you think are reasonable targets? Can you outline an approximate schedule of milestones? In the first week I will get Haddock and GHC compilation and patch-making set up, fix some minor bugs and send/apply the fixes. Next I will start to determine and converse about the implementation difficulties with making Haddock work across packages. At the same time, I'll continue working on more minor bugs/features (increasing my familiarity with the code and with the coding process). By the end of June I hope to get cross-module docs working. [Is this a realistic goal?] By this time, I'll have some familiarity with the parsing code (having fixed some of its bugs/infelicities), and I can confront the problem of how to refactor the comment-parsing out of GHC. I can imagine I might only be able to find a partial solution easily, but I'll do whatever I have time for. Optimistic timeline to finish this by the end of July; if I get ahead of schedule, I'm sure I'll know enough about Haddock's infelicities by then to know other mini-projects that would be worth doing. For example, I could improve the layout of the index page Haddock generates (Python docs do it better, for reference, according to http://trac.haskell.org/haddock/ticket/70.) Due to the process of testing my changes, I might even write some documentation, if I see an atrociously documented function in some library :-) * In what ways will this project benefit the wider Haskell community? Better documentation (documentation that is less difficult to successfully write) makes everything flow more smoothly in source-code-land. Especially core (even Haskell-98) library documentation has broken multiple times due to Haddock deficiency, and other library authors suffer from everything from `type` annotations not working, to Haddock-2 parsing being more strict, to... every possible issue, really. The cross-package documentation failure specifically makes people reluctant to refactoring into smaller packages, even when that would increase code re-use. Making Haddock/GHC more composable should make it easier for everyone to make small improvements to Haddock, without delving into GHC as much. Perhaps it might even make possible some new tool different from Haddock that looks at information in comments, should someone desire such a thing. * What relevant experience do you have? e.g. Have you coded anything in Haskell? Have you contributed to any other open source software? Been studying advanced courses in a related topic? I substantially improved Spiderweb Software's scenario-editor for Blades of Avernum (once they made it open-source), adding 3D support and other improvements. (C programming language). I worked on Battle for Wesnoth scenarios some, and I hacked on the C++ code for lexing/parsing their markup language, and I learned my lesson when I failed to coordinate successfully with the development team. :-) They used Doxygen to document their code, though it was not used nearly as thoroughly (at least, not back a few years ago) as a lot of Haskell code is documented today. I hacked on GHC, and this code has been committed: I improved the parsing of negative unboxed literals, and I refactored several places in the code that used language extensions unnecessarily. Also I've contributed to discussions on Haskell development mailing-lists over the years (leading to at least one bug-fix), and reported several more bugs in Trac as I ran into them while hacking in Haskell. I took an advanced-level Artificial Intelligence class in which I programmed in Haskell and got an A. I've read many research papers related to Haskell or compilation. I've used Darcs; I've used Linux and followed its open-source coordination travails for four years now (formerly I used Mac OS). I know (X)HTML and CSS well enough to write my own W3C-validated webpage (and my parents work in web-design so I hear a lot about it), so I should be able to work on Haddock's HTML-generating code easily. * In what ways do you envisage interacting with the wider Haskell community during your project? e.g. How would you seek help on something your mentor wasn't able to deal with? How will you get others
[Haskell-cafe] Haddock GSoC project
I'm interested in being a GSoC student, and the Haddock-related tickets looked like a good place to start http://hackage.haskell.org/trac/summer-of-code/ticket/1567 http://hackage.haskell.org/trac/summer-of-code/ticket/1568 http://hackage.haskell.org/trac/summer-of-code/ticket/1569 ... haddock could use some love! And I love documentation. I think I'd start by hacking on some relatively easy Haddock tickets to find my way around the code and the hacking process. Then it might be time to move into one of the bigger projects (I'm tempted to say #1567, Haddock: allow documentation to propagate between packages), depending on priorities; probably still working on some smaller but important Haddock tickets. Then it depends how much time we have left in the summer, there's a lot that can be done! - I've hacked on the GHC lexing/parsing code a bit, and I know darcs, haskell, etc., and I've been around watching on mailing-lists since before Haddock 2.x, so I feel like I have a fair amount of context with which to approach this project. What do you think, is this a good project to look towards? What's the next step... should I elaborate my proposal by looking at Haddock tickets and their priorities? But I should have your feedback first; what do the mentors, or the Haskell community, want most to be improved about Haddock? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haddock GSoC project
Simon Marlow wrote: Obviously I think these tickets are important, since I wrote them :-) In terms of priority, I think #1567 is at the top: not having this harms our ability to reorganise and abstract things, it puts an arbitrary barrier between packages. It's possible my perspective is slightly skewed though, since most of the packages that are affected by this are in GHC's core package collection. still, -reorganization happens in others' packages too, and we want to encourage this! -everyone uses GHC's core packages and complains when the documentation is broken (and unfixable!) :-) but sure, we should find out if other people have higher priorities elsewhere. (cafe citizens and hackers, tell us what you think!) #1568 is just refactoring, but it's a high priority: we need to get this code out of GHC and back into Haddock. This is important for Haddock's long term future and general maintainability, though it won't have any visible effect on the way Haddock works. yes, I agree, things will keep being a little unpleasant until we do this. My intuition says that with 2-3 months I should have time to do this refactoring too, but then, I haven't actually spent a week figuring out just how difficult it is :-). Probably needs some refactoring the data-types that GHC emits comments as, and then possibly-more-complicated having Haddock parse and structure the Haddock-syntax within the comments (and as it relates to the actual code!) The index page really isn't working right now, since we added the search-box functionality it has become unusable for the GHC library docs (small libraries are ok). Thank goodness we have Hoogle and Hayoo. We should really just revert to the old A-Z links, I'm not sure if there's a Haddock ticket for this. maybe http://trac.haskell.org/haddock/ticket/70 is related? There's lot of other stuff that could be done. For instance I'd really like someone with some CSS expertise to have another go at Haddock's HTML layout. I've done some manual HTML/CSS on my own website (W3C validated!)... don't know if it comes anywhere near expertise though :-) One random haddock problem I remember bothering me recently is: no view source link on each instance in the list of instances for a data-type (so I clicked a nearby view source and scrolled to find the instance source, which was in the same module) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] ANN: The Typeclassopedia, and request for feedback
Natural numbers under min don't form a monoid, only naturals under max do (so you can have a zero element) Brent Yorgey wrote: Hi all, If you've noticed the lack of a HWN this week, that's because I've been doggedly finishing my article entitled 'The Typeclassopedia', which I have just submitted for publication in the Monad.Reader. Here's the abstract: The standard Haskell libraries feature a number of type classes with algebraic or categorical underpinnings. Becoming a fluent Haskell hacker requires intimate familiarity with them all, yet acquiring this familiarity often involves combing through a mountain of tutorials, blog posts, mailing list archives, and IRC logs. The goal of this article is to serve as a starting point for the student of Haskell wishing to gain a firm grasp of its standard type classes. The essentials of each type class are introduced, with examples, commentary, and extensive references for further reading. My hope is that this will be a valuable resource to the Haskell community, especially those who are learning. Any feedback would be greatly appreciated, especially if it helps improve the article before publication. A draft can be found here: http://www.cis.upenn.edu/~byorgey/papers/typeclassopedia-draft-090216.pdf Also see my blog post for a bit more info: http://byorgey.wordpress.com/2009/02/16/the-typeclassopedia-request-for-fee dback/ happy haskelling! -Brent ___ Haskell mailing list hask...@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] ANN: The Typeclassopedia, and request for feedback
I'm really confused that when I replied (not reply-to-all, not reply-to-list, just reply) to that message, it went to the lists and not to you Brent! (KMail 1.10.3) -- so I totally edited the To lines, to send this message... Brent Yorgey wrote: Hi all, If you've noticed the lack of a HWN this week, that's because I've been doggedly finishing my article entitled 'The Typeclassopedia', which I have just submitted for publication in the Monad.Reader. Here's the abstract: The standard Haskell libraries feature a number of type classes with algebraic or categorical underpinnings. Becoming a fluent Haskell hacker requires intimate familiarity with them all, yet acquiring this familiarity often involves combing through a mountain of tutorials, blog posts, mailing list archives, and IRC logs. The goal of this article is to serve as a starting point for the student of Haskell wishing to gain a firm grasp of its standard type classes. The essentials of each type class are introduced, with examples, commentary, and extensive references for further reading. My hope is that this will be a valuable resource to the Haskell community, especially those who are learning. Any feedback would be greatly appreciated, especially if it helps improve the article before publication. A draft can be found here: http://www.cis.upenn.edu/~byorgey/papers/typeclassopedia-draft-090216.pdf Also see my blog post for a bit more info: http://byorgey.wordpress.com/2009/02/16/the-typeclassopedia-request-for-fee dback/ happy haskelling! -Brent ___ Haskell mailing list hask...@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Use of abbreviations in Haskell
Ketil Malde wrote: A module may be defined in a file with a name corresponding to the module name, or any dot-separated prefix of it? I.e. the file Foo/Bar.hs will define module Foo.Bar and optionally Foo.Bar.Baz as well? GHC should then be able to find it, and I believe it already has a prioritized search mechanism (presumably, the file could be named Foo.Bar.hs, too). I don't think GHC actually allows that (Foo.Bar.hs, ever). But your suggestion could work. 1. Try Foo/Bar/Baz.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as the file's top-level module). 2. Try Foo.Bar.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as a sub-module). 3. Try Foo.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as a sub-module... or possibly as a sub-sub-module?). 4. give up :-) Note though, that local modules tempt us to a couple other things too, even though they're not necessary to the proposal and would complicate it: - access-controlled modules (e.g. if other code can't import Foo.Bar.Baz) - relative-path imports / module names (e.g. if in Foo/Bar.hs we make Baz and try to import it some way with import Baz) and as we already mentioned, it would likely involve some implicit importing of the sub-module. translating into ordinary haskell: I think my module-search mechanism makes a well-defined, deterministic way to find the right module, no complex translation necessary (except layout rule madness maybe?). Implicit importing: submodule syntax implies adding an import The.Module.Name line at that point in the containing file. This would suggest that submodules must be at the top, among the imports, because all imports must syntactically be at the beginning of the file -- and there's a reason for this. Bother! Even if the reason is dependency chasing, one would think same-file dependencies aren't important, but the submodules themselves can import things from other files, so those lines should need to be near the beginning anyway. so an example could be module MyData ( module MyData.Sub, -- or equivalently, D(..) transform ) where module MyData.Sub --or module Sub ?? that seems a bit too ad-hoc though where data D = E | F transform :: D - D transform F = E transform E = F ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Use of abbreviations in Haskell
Derek Elkins wrote: I haven't been able to find any semantic difficulties with this addition. I like it too... what I run into is that there's an implicit assumption that module of name Foo.Bar.Baz *must* be found in a file Foo/Bar/Baz.[l]hs . module Main seems to be the only one exempted from it. GHC uses this all the time when going looking for a module's source code. (it does help make sure that for any module name in a package, there's only one version of the source-code for that module...) So I think we need to accomplish working out the kinks we may get in trying to break this assumption. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The Haskell re-branding exercise
(responding with just a bit of possibly relevant context, not always directly) Paul Johnson wrote: I've lived through a couple of corporate rebranding exercises in my time, and I've read about some others. They follow a pattern: ... 2. The new branding is released with as much fanfare as possible. Press releases are released. Staff are given briefings about the significance of the whole exercise and the bold new future that it symbolises. I don't think our choice of logo is quite as significant as a corporate logo. We could even use more than one logo if we wanted (maybe different people or different places). The current logo is prominent on the haskell.org (and wikipedia), mainly... places I rarely see, when working on Haskell. I see a couple things people are trying to do - Self-descriptive, without trying to change the way we are as a community or a language - Inviting to newcomers, mostly independent of how we actually work (although better if we advertize things we can actually provide, of course) I don't think it's trying to create a change in the language or the community, mostly it's to reflect the change that has already happened. 3. The staff universally agree that the new logo is not a patch on the old one. The old one was a much loved friend; it stood for something; people have spent years working for it. The new one is obviously a piece of cheap gimcrackery yup, I'll miss the old logo. To me, it still looks beautiful, clean and fitting. A paradox of the Haskell world is that, while the language is Vulcan, the community around it is dominated by Warm Fuzziness. Clearly the two are not mutually exclusive. nice observation! A rebranding exercise needs to start with a short list of adjectives that the brand is to represent, good idea... although we could just be attracted by whatever proposed logo happens to have beauty instead, if our only purpose is not to be stuck with an ugly logo. and I think that the Haskell community needs to decide this before it fires up Inkscape. or in parallel with :-) -- random creativity can help us start thinking about what we don't want to see, and why we don't want to see it, too -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Fwd: [Haskell-cafe] Haskell as a religion
Henning Thielemann wrote: Alberto G. Corona schrieb: But many features need other features. For example, the option to use referential transparency will be common in future languages for multicore programming purposes. This creates the problem of separating side-effect-free code from side-effect code. In C/C++ referential transparent functions code can be declared by appending a 'const' to the prototype, right? not quite. GCC allows __attribute__((__const__)) or __attribute__((__pure__)), to declare that, though (one of them allows reading global variables, the other doesn't, I forget which). In C and C++ per standard, const can only be applied to types, e.g. function arguments (including C++'s implicit *this, via funny location of const). Maybe C99 made up an additional way to use it, as it introduced restrict, I forget -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Time for a new logo?
okay, I want a t-shirt like this (but with all the greek letters and formatting) back: \t. 2^-t kg is equally[or: sometimes] bothered by math front: \gbtq is [sometimes] bothered by acronyms :-) or, sometimes likes each of them :-) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] Wait for *either* MVar to be set
Peter Verswyvelen wrote: ... by spawning and killing two threads (which might be an expensive operation, I'm not sure) pretty cheap in GHC -- they're not system threads Am I wrong in this? If so, is this something that might be considered as a future enhancement in the GHC libraries and runtime? Also, look at STM (e.g. TVars), which is designed to do what you want more directly, I think. (timeouts might still use the GHC-thread thing. Don't worry about its performance unless you're measurably suffering from it...) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Prototype of a syntax reference
Maurício wrote: • It should be an example of valid code, not good one. The idea is to show what can be done, not what should :) then put lots of semicolons somewhere: while they are at minimum a separator, it's generally allowed to insert as many extra semicolons as you want at the beginning, end, or wherever you could put a single semicolon. (I wish the same were true for commas.) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
C.M.Brown wrote: I don't really see this as being any kind of real issue at all. Surely all GHC needs to do is to concatenate all the modules together, alpha-reduce the import/export relations and do a compile/type check over the concatenated module. FWIW, I agree (in principle -- I haven't looked at the GHC implementation enough to see whether its internal representations could easily do type inference involving symbols in multiple modules, and GHC HQ understandably isn't interested in implementing it themselves http://hackage.haskell.org/trac/ghc/ticket/1409 ). There is a bit of a question in my mind about what to do with .hi/.o files for the combined blob. There's also a scalability / memory use issue, that is also the plug for separate compilation: if you make really big modules (whether manually or programmatically), compiling them takes lots of memory and time, significantly more total time and maximum memory than you need for via separate compilation. I consider this a bug. (Well, I don't know if what I said is true -- it's just an excuse that's often given for why GHC compiling things together is a bad idea. And there are several compile-time performance bugs in Trac.) Admittedly, it's a challenging problem to automatically segment a large module so you only need to do a little work at once. Essentially, the module system partly has the purpose of telling the compiler how not to try to optimize, even if it would be beneficial; and thereby you get reasonable compilation times. This would be inexcusable in my mind if the same sort of module segmentation didn't also help *humans* understand the contents of the modules :-). I wonder if there can be some sort of system with pragmas that accomplishes the same purpose of guiding the compiler... probably not for Haskell so much as in general -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fw: patch applied (ghc): Remove the OpenGL family of libraries fromextralibs
Malcolm Wallace wrote: As a package author (rather than a user), I would see this as a primary benefit of having my packages added to the Platform. And as a package user (rather than author), there is the corresponding antibenefit of removing a package like HOpenGL from the Platform: a diminished likelihood of the maintainer being already aware of packaging flaws. perhaps we can work on getting set up automatic testing etc. with a relatively basic Haskell Platform. If that turns out to be easily done, we can look at making a facility for all package authors (at least, ones on Hackage) to volunteer to have their packages automatically checked for such breakages. Sure, it could still help a little to be part of an official Haskell Platform, but there are reasons we're trying to designate a Haskell Platform smaller than Hackage. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ansi2html - one program, several issues
Dan Doel wrote: On Sunday 20 July 2008, John Meacham wrote: I do not believe that is the case, since the return type of runParser Either ParseError a means that before you can extract the result of the parse from the 'Right' branch, it must evaluate whether the result is 'Left' or 'Right' meaning it needs to parse the whole input in order to determine whether the parse was succesful. ... It doesn't stop it from parsing the entire file strictly. However, what it does do is prevent the parser from backtracking out of arbitrary amounts of lookahead. So, unless you use try (which allows for lookahead), when any token is consumed by the parser, it can be garbage collected (assuming the parser is the only thing pointing to the token stream). So, it consumes its input strictly, but with limited overhead (ideally using try only for some small bounded lookahead where it's needed). So with Parsec, you can keep the *input* from filling up memory, but if you do, the *result* will still take up space (e.g. Right (value)). For a simple transformation where the output is a similar string to the input, it will be just as large, so not much space is actually saved (maybe a factor of 2 -- just keeping the output, not also the input), it seems. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Searchig for modules
fero wrote: Actually I have already found the way how to do it but not in eclipsefp. Either I run ghci and when both modules are in the same dir it works or I use -idirs but in eclipsefp it doesn't. Can somebody help me how to configure eclipsefp. I don't want to go to command prompt every time I want to run my program. I don't know anything about IDEs, but... ghc --make, should work to find the module on the command-line, and so should `runghc` (like interpreter but runs 'main'). There is also a way to install it more globally but I'm not sure what is a simple way to do that (it could involve making a .cabal file, I think) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] uvector and the stream interface
Evan Laforge wrote: An abstraction stack: Impure Pure How about strict vs. lazy? I ask because I assumed there were lazy variants of uvector or storablevector, using the bytestring list of chunks approach, but apparently not? wait list of chunks makes something that behaves not like a random-access array, and yet is still rather strict in the elements. How about strict vs. lazy as in UArray vs. Array: whether the elements are evaluated lazily (although UArray has the complication that the elements must also be Storable: e.g. what if you want a strict random-access array of functions -- so there is not such an easy solution for a strict but boxed array). so do we have at least three different variables here? :-) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Human-friendly compiler errors for GHC
wren ng thornton wrote: Max Bolingbroke wrote: Agreed: I've implemented this too. I've also added fuzzy matching to package search: $ stage2/ghc-inplace --make ../Test1.hs ../Test1.hs:3:7: Could not find module `Data.Lost': Use -v to see a list of the files searched for. Maybe you meant `Data.List' $ stage2/ghc-inplace --make ../Test2.hs [1 of 1] Compiling Main ( ../Test2.hs, ../Test2.o ) ../Test2.hs:7:14: Not in scope: `isSpace' Maybe you meant `Char.isSpace' In terms of making error messages more helpful, I don't find general typos are much of an issue, but this part would be really nice! I've always been annoyed that GHC just says no rather than offering suggestions (-v is rarely helpful), especially since it knows about what modules are installed et al. It sounds like it only searches for modules you've imported (after all they might've been brought into scope with an as-clause, and ghc has no business poking in un-imported modules), but perhaps since in GHCi all modules are in scope (under their original names -- in addition to any imports in an interpreted file), it (ghci) searches all modules then? If I want a perhaps you meant to import message, I want it to be a *complete* listing of modules available that export that symbol, both local ones and library ones, ideally :-) (certainly don't want a recommendation to import e.g. List without at least an equal recommendation of Data.List...) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Human-friendly compiler errors for GHC
Marc Weber wrote: There is a friendlier shell (don't remember it's name) which takes another approach: Change color if the word is known.. In case of ghci the commandline could switch color to green before pressing enter to indicate there are no errors left.. fish, the friendly interactive shell, which I use, although it has lots of minor friendliness problems (compared to ideal, not to bash) that could be fixed by more hacking on its C code :-P -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Qualified import syntax badly designed (?)
Neil Mitchell wrote: Hi declaration with a regular syntax. For example: import Data.Map as Map unqualified (Map, (\\)) qualified (lookup, map, null) hiding (filter) I think I prefer this to my proposal, plus its closer to the current syntax. I think its also nearly equal to what Tom Davie came up with, given some keyword renaming. If we dropped the unqualified keyword, and just required unqualified things to come directly after, we get the full benefits of not introducing any keywords. We're still not introducing any keywords either way, fortunately :-). 'qualified', 'as' and 'hiding' are not keywords: the syntax after 'import' has no place for lowercase identifiers, so we can use as many new words as we want, here, as long as module names stay capitalized and import lists remain parenthesized (or, import lists could equally well be in layout after 'where', 'of', 'let' or 'do' if we adopt the layout syntax) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] http://www.haskell.org/ghc/reportabug
Galchin, Vasili wrote: Isaac, which different trac page? I have tried several times to no avail! any one that says you're not logged in. Probably you're having a different problem than I was, if it's that hard to solve... -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] http://www.haskell.org/ghc/reportabug
Galchin, Vasili wrote: I am logging in as a client running Ubuntu Linux. Is this a problem? (I think not ). no, I use Ubuntu. If you have cookies disabled (am I one of the few people who sets this option?) without having an exception for hackage.haskell.org, that would cause trouble. Not sure what else. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] history of tuples vs pairs
Lennart Augustsson wrote: Yes, early ML had nested pairs. We introduced n-tuples in Lazy ML because in a lazy language n-tuples are not isomorphic to nested pairs (whereas they are in a strict language). So n-tuples are nasty because they are not inductive, but they are in many ways much more reasonable than lazy nested pairs. although it is possible in a slightly different (and less left-right symmetric) way in Haskell: data P a b = P a !b pair: P Int (P Bool ()) triple: P Char (P Int (P Bool ()) single: P Bool () unit: () BTW, early ML also had binary sums. Again, they are not isomorphic to n-ary sums. data E a b = L a | R !b data Z --since Haskell Prelude provides us with the unit type () but not the uninhabited zero type, I'll use GHC's EmptyDataDecls syntax for this. either: E Int (E Bool Z) 3: E Char (E Int (E Bool Z) 1: E Bool Z 0: Z Still, these don't have isomorphic *representations*: the efficiency is lacking. I wonder if it would be possible to allow {-#UNPACK#-} for those polymorphic arguments in such a way that either/both of the above were actually equivalent to n-tuple/sums. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Pipe 1.0
Don Stewart wrote: Interesting. Does it depend on an unreleased version of the process library? by the way, is there a policy for when new versions of packages maintained by [EMAIL PROTECTED] are *released*? Or do patches just collect in the darcs repository until they're picked up by some major release like GHC's? I would tend to think that for any change nontrivial enough to be discussed on libraries@, why not quickly release the newer version with an appropriately incremented version number? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Design your modules for qualified import
Henning Thielemann wrote: On Mon, 9 Jun 2008, Duncan Coutts wrote: On Mon, 2008-06-09 at 16:04 +0200, Ketil Malde wrote: And - is there a way to make GHCi use aliased qualification? I find my self typing detailed taxonomies all the time there. The ghci syntax currently is: :m Data.Set wouldn't it be much nicer as: import Data.Set then we could have the obvious: import Data.Set as Set This would be nice! Feature request? feature request filed for this, http://hackage.haskell.org/trac/ghc/ticket/2362 . For extending the import syntax in general, I wasn't sure we knew quite what we wanted yet, so it seemed a little premature for a feature request. (the first step in implementing the feature request would have to be specifying an exact design and probably asking for community feedback). So let's talk about what we do or don't want for that one some more, perhaps. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Design your modules for qualified import
Duncan Coutts wrote: Right. That's exactly why we've not done something like that. With 100+ modules in the Gtk package it's totally infeasible to do qualified imports of them all. If we get a proper way to export a non-flat namespace then Gtk2Hs will certainly switch to using it. Using 'buttonBlah' is horrible but there is currently nothing better. okay, it's horrible! It's no more manually-traceable than anything else either, if you just import Gtk2Hs unqualified. Is there any way it could possibly be acceptably concise *and* traceable? let's see If GTK appears in every usage (e.g. GTK.buttonBlah, gtkButtonBlah...), probably not at all concise enough for GUI code! But if it doesn't, then we would need at minimum to list each of those ones that we used (probably not all 100 of them). It couldn't get any more concise than this to use Button.blah etc.: import GTK.modules (Button, Window, ...) never mind the exact syntax yet -- is listing them acceptable? (and if there are so many, is it practically traceable by humans anyway? Perhaps we're assuming that these humans at least have search this file editor-capabilities?) Are there multiple blah functions among the GTK modules? I.e. would GTK.blah be unambiguous, not mentioning that it's a button function. (And would it be too confusing not to mention that it's a button function...) If it would be ambiguous, would typeclasses work to fix that (or renaming functions that have no good reason to have the same name, or occasionally including blahButton sort of names)? If 100 modules is too much, would it be a reasonable compromise between clarity and conciseness to export coarser-grained, so there are only maybe half a dozen GTK modules that your typical program imports? There have been a few suggestions along these lines. Check the archives. I'm not sure what is proposed for haskell', probably nothing since nothing is currently implemented and we're only supposed to be standardising existing practise. I had trouble in my first attempt to search the archives... Googling for import in haskell-cafe found too much code, and my personal e-mail records back to March 2007 found nothing else relevant with import in the title. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lazy IO.
Sebastiaan Visser wrote: Hi, I've got a question about lazy IO in Haskell. The most well known function to do lazy IO is the `hGetContents', which lazily reads all the contents from a handle and returns this as a regular [Char]. The thing with hGetContents is that is puts the Handle in a semi-closed state, no one can use the handle anymore. This behaviour is understandable from the point of safety; it is not yet determined when the result of hGetContents will actually be computed, using the handle in the meantime is undesirable. The point is, I think I really have a situation in which I want to use the handle again `after' a call to hGetContents. I think I can best explain this using a code example. readHttpMessage :: IO (Headers, Data.ByteString.Lazy.ByteString) readHttpMessage = do myStream - accept http connection from client request - hGetContents myStream header - parseHttpHeader request bs - Data.ByteString.Lazy.hGetContents myStream return (header, body) that's impure because parseHttpHeader doesn't return anything telling you how much of the stream it's looked at. Maybe it looked ahead more than it needed to, thus deleting part of the body. I was going to suggest, if you can't change parseHttpHeader to use ByteStrings, bs - Data.ByteString.Lazy.hGetContents myStream header - parseHttpHeader (Data.ByteString.Lazy.unpack bs) but you still have to get parseHttpHeader (or perhaps if it has similar friends) to tell you how much of the string it consumed! I don't know what parsing functions you have available to work with, so I can't tell you whether it's possible. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Design your modules for qualified import
Sebastian Sylvan wrote: On 6/14/08, Henning Thielemann [EMAIL PROTECTED] wrote: On Sat, 14 Jun 2008, Sebastian Sylvan wrote: On 6/14/08, Henning Thielemann [EMAIL PROTECTED] wrote: On Sat, 14 Jun 2008, Sebastian Sylvan wrote: On 6/14/08, Henning Thielemann [EMAIL PROTECTED] wrote: The problem would be again that no one knows, where Window comes from. Better would be I really don't see how this is a big problem. Lots of languages do hierarchical import (e.g. .Net languages) and I don't think I've ever heard anyone complain about this particular aspect of it. It's not a problem for you and thus you do not pay attention to these complaints, I suspect. Maybe the people who would complain about the importing style, simply don't use the mentioned languages. The worst case scenario is that you need a little bit of tool support to help you sort it out. Plus, it's not like you can't just qualify the import to make it easier to see where it comes from if you really think it's a problem: Cf. http://www.haskell.org/haskellwiki/Import_modules_properly Haskell can re-export modules, which makes tracing identifiers more difficult. I want to be able to read modules without using a tool. I'm not sure I understand you point. You're so opposed to the *option* of allowing hierarchical exports (even though you can still import it qualified if you personally like having to specify at each callsite exactly where some identifier is coming from), I was concerned with the _import_ part of your proposal. (I haven't thought about the export part so far.) that you'd rather any library making use of a module hierarchy is forced to either make the user add dozens of boilerplate import statements (with qualified and as) or the more common strategy of prefixing each function call with the module name (buttonNew)? To me a module system that requires the latter in practice is horribly broken, and I'm suggesting a low-impact way of fixing it. It may not be the best system available, but it's a tiny extension of the current. I really don't see why adding this option hurts you, when it clearly helps enable doing what this thread advocates (use qualified modules to distinguish between functions of the same name, rather than adding a bunch of prefixes/suffixes to the functions). Button.new is my favorite, because with current import variants I can easily lookup, what Button and Button.new refer to. I understand your proposal in that way that import Graphics.UI.Gtk brings module qualifications Window and Button into scope although they are not explicitly mentioned. Thus I could no longer find out easily what Butten.new means. I don't see why this is so bad when it's exactly what we have for other identifiers? E.g. if you import Control.Monad you get mapM, but you can't really say for sure where this identifier comes from, which is no better than not knowing where Button.new comes from. In both cases you have the option to qualify the module import so you have to say Monad.mapM or GTK.Button.new which makes it more apparent. I suppose you would make the hiding clause and the import list thing work with modules too for consistency, so if you really wanted to you could list the modules/identifiers that you bring in. yeah, we could come up with a syntax. one that gives privileged meaning to hierarchy. If used according to design your modules for qualified import, it would still allow fairly easy use and looking up function uses. import Graphics.UI.GTK (import qualified Button, import qualified Window) then you get Button.f (because Graphics.UI.GTK wasn't imported qualified), Graphics.UI.GTK.Button.f, (not f or Graphics.UI.GTK.f because of qualified Button) ... they're normal import statements inside. What it saves is the duplication of Graphics.UI.GTK and Button as Button. Not sure I like how long import qualified is, repeated there, but it seemed much less confusing than anything shorter. import Data (import qualified Map, Map.Map) or import Data (import qualified Map, import Map(Map)) or a shortcut for that common pattern of importing a few things unqualified import Data (import qualified Map and (Map)) aka. import qualified Data.Map as Map and (Map) aka. import qualified Data.Map as Map (empty,singleton,...) and (Map) or perhaps unqualifying rather than and personally I would like it if we could also import (f as g) if we wanted to rename an f we were importing, to g in the module and re-exports, without having to be concerned about (for lowercase) monomorphism restriction, (for types) whether a synonym will work properly everywhere (not without extensions!), (for constructor, record fields, and classes) simple *impossibility*. That wish is only related in that it's a related generalization, though. hmm. -Isaac Are you saying that you prefer the situation where to use GTK the user would have to explicitly import every single sub-module in the hierarchy (import
Re: [Haskell-cafe] Documenting the impossible
Neil Mitchell wrote: * abort - deliberate aborting because the user made some mistake. This is an exception. The signature of a function must reflect this by a Maybe, Either type etc. Disagree. I mean more like: when (Delete `elem` flags Keep `elem` flags) $ abort User cannot pick both keep and delete on the command line Think die in Perl world. in that case should use abort :: String - IO a, not abort :: String - a. abort as pure function is just for messy scripting convenience a-la Perl. (Which is not to say that's never useful, of course -- I would just try my hardest to avoid it in my code, probably.) On the other hand, Control.Exception.throw, if it's ever useful, obviously isn't meant to indicate a programmer error, but to throw an exception (that will probably be caught somewhere in the program's IO). So there's a reason for _|_ besides programmer error (well, there's also user-driven nontermination such as when an interpreter is told to execute an infinite loop :-) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] ANN: random-access-list-0.1
Stephan Friedrichs wrote: Isaac Dupree wrote: [...] Great to see it, it deserved implementing, IIRC! I don't remember enough about it.. (and don't have Okasaki anywhere handy). Can it be lazy or infinitely long? No, it has to be finite as it's actually a list of complete binary trees whose size depend on the skew binary representation of the list's size. I'll document this. okay then [...] Is RandomAccessList the best name for something that's not O(1), just O(log n)? Or just that RandomAccessList is just much longer than []? Well Chris Okasaki called them Skew Binary Random-Access Lists, which is even longer :) :) hmm.. IndexableList? (just a thought, not sure whether I like it any better) don't use those unorthodox infix function names.. `cons` is hardly worse than .:. , `append` or `mappend` than .+. , and .!. than, hmm.. . Export a ++ and ! (!! ?) if you're really dedicated. But I'd prefer an `at` that's the same partial indexing operation, rather than the name .!. (I think this at was a new name being put somewhere else? partly because ! is trying to be gradually used only to refer to strictness?) Good point! extractHead is an ugly name for a nevertheless standardish-meaning function... what is it usually called? uncons? headTail? (Data.Sequence, which is meant to be left-right symmetric, calls it viewr... except your version doesn't have the Maybe, it's partial instead, fails on empty lists) Yes, I wasn't happy with that one either. The view-concept of Data.Sequence is a good idea. yeah, it's a good idea, although I'm not sure how much I like the particular syntax of how it's done in Data.Sequence (the view-types' constructor names, mostly) For index, don't use Monad, use Maybe (I think that's what the recent [EMAIL PROTECTED] discussion concluded, in the context of switching Data.Map back to Maybe). I was just copying the idea from Data.Map and it's usually a good thing to have functions as general as possible, or why is it not? To summarize: Monad isn't the proper abstraction for failable/Maybe. Maybe is an algebraic data type that *exactly* represents the spirit of what you're trying to do: e.g. Conor McBride said: Maybe is the most general abstraction. Requiring (=), or even (*) seems excessive. What we need is any f with zero and return, so why not pick the canonical, initial, inductively defined such thing? In this case the typeclass adds no generality to the function's behaviour (Maybe can be trivially converted to any other type, with a combinator even). And the confusion that results, when the function is almost always used at type Maybe anyway. If you want to read the whole discussion... if you haven't been subscribed to [EMAIL PROTECTED] , it's archived: http://thread.gmane.org/gmane.comp.lang.haskell.libraries/9082 Also, Data.List has genericLength etc, to At the moment, I'm using the Int type for size and indexing only for one reason: I haven't found a proper way to generalize it. I'd really like to use the Ix class, but it doesn't provide enough functionality, it only works on fixed-size intervals (i. e. for arrays, which don't change their size, but a list does). Maybe someone has an idea of how to realize lists with a variable starting index and size? fair enough. If your implementation only supports sizes up to that of Int (which is reasonable for a strict finite type... whereas something like ([1..2^34] `genericIndex` (2^33)) can probably complete in a small amount of memory and only a moderate amount of time on a modern machine, even a 32-bit one, due to laziness and garbage collection) support. Isn't index (like Data.List.genericIndex) supposed to be a name for a partial operation, not one that returns a Maybe? Shouldn't size be named length (or exported as both names, since e.g. Data.Map.size, .List.length) (why is it O(1) not O(log n)? Is it possible for these RandomAccessLists to be longer than maxBound::Int?)? The size function is in O(1) because I cache it, otherwise it would be size (RandomAccessList xs) = sum (map fst xs) which is O(log n). I consider the caching useful, as most applications will check 0 = i size quite often. sounds good for e.g. toList, is the O(n) cost spread over traversing/demanding the items of the generated list, or all up-front, or somewhere in between? Why is zip slow with unbalanced lists? Obviously, it could be implemented O(min(m,n)*(log m + log n)) just indexing each one, which would be faster for really unbalanced-size lists... Obviously, I don't If two lists have exactly the same size, all the complete binary trees holding the data have the same size as well. This can be zipped directly and is a bit (~5% in my tests) faster. okay, that sounds like a fair optimization, since zipping same-size lists is a nice thing to do anyway. But the asymptotic speed ideally should still be O(min(m,n)), if possible? understand
Maybe-summary was: Re: [Haskell-cafe] Re: [Haskell] ANN: random-access-list-0.1
Claus Reinke wrote: To summarize: Monad isn't the proper abstraction for failable/Maybe. Maybe is an algebraic data type that *exactly* represents the spirit of what you're trying to do: e.g. Conor McBride said: Maybe is the most general abstraction. Requiring (=), or even (*) seems excessive. What we need is any f with zero and return, so why not pick the canonical, initial, inductively defined such thing? In this case the typeclass adds no generality to the function's behaviour (Maybe can be trivially converted to any other type, with a combinator even). And the confusion that results, when the function is almost always used at type Maybe anyway. If you want to read the whole discussion... if you haven't been subscribed to [EMAIL PROTECTED] , it's archived: http://thread.gmane.org/gmane.comp.lang.haskell.libraries/9082 Thanks for the summary. I had been wondering about this change of mood, and I disagree with the suggestion that Maybe Nothing is the right replacement for Monad fail. Whether fail should be in Monad, or whether we really want MonadZero, MonadPlus, MonadError, or something else entirely has been open for discussion, but it is easily shown that Maybe is not the most general abstraction - it loses information wrt to (Either String), for instance: Prelude let {f [] = fail empty; f [_] = fail singleton; f l = return l } okay, I see, it's just that most partial functions in Data.* / container libraries don't really have multiple failure modes that need distinguishing. You could say, in a type/information-theoretic mindset, that even your f [_] above loses information because it doesn't vary based on the _ (and so it isn't reversible) (and this is very common and normal especially for error messages, but there's a large design space for places where they're needed, depending on whether a machine needs to understand the message, etc.) I think we didn't conclude much about e.g. parser-library return types, because we (thankfully) weren't trying to. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] ANN: random-access-list-0.1
Henning Thielemann wrote: On Wed, 11 Jun 2008, Isaac Dupree wrote: extractHead is an ugly name for a nevertheless standardish-meaning function... what is it usually called? uncons? headTail? (Data.Sequence, which is meant to be left-right symmetric, calls it viewr... except your version doesn't have the Maybe, it's partial instead, fails on empty lists) I like the 'viewL' and 'viewR' kind of functions, they are safer than 'head' and 'tail', 'init' and 'last'. But since in most cases I used 'viewL' in connection with 'maybe', the continuation style functions switchL :: b - (a - Seq a - b) - Seq a - b switchR :: b - (Seq a - a - b) - Seq a - b I think you got L and R backwards? it's a little confusing to me, but following Data.Sequence I think they're meant to match whether repeated L or R makes a foldl or a foldr. are even more convenient. They replace 'case' on those structures where you do not have access to the constructors. on the other hand, they look harder to use with the upcoming (in GHC 6.9/6.10) view patterns, a simple example being foo (viewr - Nothing) = ... foo (viewr - Just (a, as)) = ... equivalent to foo s = case viewr s of Nothing - ... Just (a, as) - ... (for view patterns, it's also proposed but not implemented to have special syntax for Maybe and/or tuples to make it even more convenient for these purposes... I'm not sure if it'd be a good idea either) I also mentioned the continuation style functions for Data.Map's maybe-returning in the discussion... they're most convenient if you want to destruct them right away, but harder to apply combinators to (e.g. Maybe monad. which doesn't work for Data.Sequence because they use their own custom view datatype -- was that a bad choice for them? Maybe of a tuple has an extra laziness-spot that shouldn't really be there, though) Anyway, people didn't seem to respond to that idea of continuation-style returning, not sure why. On the other hand, also, the only thing defending the function from using the arguments in a way it shouldn't, is parametricity... less obvious than with algrebraic data returns -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: [Haskell] ANN: random-access-list-0.1
Henning Thielemann wrote: On Thu, 12 Jun 2008, Isaac Dupree wrote: Henning Thielemann wrote: On Wed, 11 Jun 2008, Isaac Dupree wrote: extractHead is an ugly name for a nevertheless standardish-meaning function... what is it usually called? uncons? headTail? (Data.Sequence, which is meant to be left-right symmetric, calls it viewr... except your version doesn't have the Maybe, it's partial instead, fails on empty lists) I like the 'viewL' and 'viewR' kind of functions, they are safer than 'head' and 'tail', 'init' and 'last'. But since in most cases I used 'viewL' in connection with 'maybe', the continuation style functions switchL :: b - (a - Seq a - b) - Seq a - b switchR :: b - (Seq a - a - b) - Seq a - b I think you got L and R backwards? Why do you think so? http://cvs.haskell.org/Hugs/pages/libraries/base/Data-Sequence.html#v%3Aviewl Because I was confused. Looking again, you seem to be right... it's a little confusing to me, but following Data.Sequence I think they're meant to match whether repeated L or R makes a foldl or a foldr. viewl is like a 'case' for distinction of [] and (:) and thus can be used to implement both foldl and foldr. yes, but in the sense that foldr is more natural for lists than foldl, requiring just replacing the constructors directly ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] ANN: random-access-list-0.1
Stephan Friedrichs wrote: Hello, I've implemented Chris Okasaki's random-access list[1] which provides typical list operations (cons, head, tail) in O(1) and yet offers indexed random-access in O(log n). It's uploaded on hackage[2]. It's still an early version which I'll extend, but especially at this eary stage I'd appreciate your feedback concerning what's still missing / to be fixed / to be improved. Great to see it, it deserved implementing, IIRC! I don't remember enough about it.. (and don't have Okasaki anywhere handy). Can it be lazy or infinitely long? (Data.Sequence can't, but it's fast on both ends and has fast concatenation.) Anyway, document that. If it can't be lazy/infinite, does it have any advantage over using Data.Sequence?(constant factor of speed?, possible operations?, something I'm forgetting?) Is RandomAccessList the best name for something that's not O(1), just O(log n)? Or just that RandomAccessList is just much longer than []? don't use those unorthodox infix function names.. `cons` is hardly worse than .:. , `append` or `mappend` than .+. , and .!. than, hmm.. . Export a ++ and ! (!! ?) if you're really dedicated. But I'd prefer an `at` that's the same partial indexing operation, rather than the name .!. (I think this at was a new name being put somewhere else? partly because ! is trying to be gradually used only to refer to strictness?) extractHead is an ugly name for a nevertheless standardish-meaning function... what is it usually called? uncons? headTail? (Data.Sequence, which is meant to be left-right symmetric, calls it viewr... except your version doesn't have the Maybe, it's partial instead, fails on empty lists) For index, don't use Monad, use Maybe (I think that's what the recent [EMAIL PROTECTED] discussion concluded, in the context of switching Data.Map back to Maybe). Also, Data.List has genericLength etc, to support. Isn't index (like Data.List.genericIndex) supposed to be a name for a partial operation, not one that returns a Maybe? Shouldn't size be named length (or exported as both names, since e.g. Data.Map.size, .List.length) (why is it O(1) not O(log n)? Is it possible for these RandomAccessLists to be longer than maxBound::Int?)? for e.g. toList, is the O(n) cost spread over traversing/demanding the items of the generated list, or all up-front, or somewhere in between? Why is zip slow with unbalanced lists? Obviously, it could be implemented O(min(m,n)*(log m + log n)) just indexing each one, which would be faster for really unbalanced-size lists... Obviously, I don't understand the implementation. BTW, looking at the file, data RandomAccessList a = RandomAccessList {-# UNPACK #-} !Int ![(Int, CBTree a)] Marking a list strict like that doesn't have much effect because it only makes the first (:) or [] strict. Did you mean for an element-strict or spine-strict(which would necessarily be non-infinite) list? -Isaac Regards, Stephan [1] Chris Okasaki: Purely Functional Data Structures [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/random-access-list ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Implementing ParseChart with Data.Map
Duncan Coutts wrote: modify :: k - Map k e - (e, Maybe e - Map k e) so it's a lookup that returns the element at k and also a continuation that lets you rebuild a new map with an altered element. I guess that doesn't account for the element not existing. There's probably a generalisation that does. isn't it just adding the necessary Maybe?: modify :: k - Map k e - (Maybe e, Maybe e - Map k e) ? -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Mutually Recursive Modules
Richard Giraud wrote: Hello I'm using GHC 6.8.2 with mutally recursive modules. I'm familiar with how to do simple cases in GHC ({-# SOURCE #-} and .hs-boot files) but I can't figure out how to get it to work for a particular set of modules. Is it known (i.e., proven) that GHC 6.8.2 can compile any set of mutually recursive modules without refactoring? Are there known limitations? With the old (6.2 and before) .hi-boot scheme where there was no abstraction in boot-files, it could probably do anything that it could do. But I'm not convinced with .hs-boot... it can resolve one level of cycle, and I don't know how to *prove* that it *can't* do any given thing, but I strongly suspect there are things it can't do. Luckily, it is very often the case that your code will be better off anyway if refactored to have less module recursion. (though not always.) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Default definitions for associated type synonyms
Dreixel wrote: Hello, Does anyone know if it is possible to specify a default definition for an associated type synonym? When I tried: class A a where type B a = a GHC (version 6.9.20080309) told me: Type declaration in a class must be a kind signature or synonym default. However, when I look at the parser I see no way to specify such synonym default. Is this possible? I'm curious... so, cc'ing glasgow-haskell-users mailinglist because the question is more likely to be noticed by relevant people there. Thanks, Zé Pedro ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Copying Arrays
it makes me wonder: can we support concatenation with sharing (e.g. the rope data structure) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type-level integers using type families
Peter Gavin wrote: Has anyone else tried implementing type-level integers using type families? I tried using a couple of other type level arithmetic libraries (including type-level on Hackage) and they felt a bit clumsy to use. I started looking at type families and realized I could pretty much build an entire Scheme-like language based on them. In short, I've got addition, subtraction, multiplication working after just a days worth of hacking. I'm going to post the darcs archive sometime, sooner if anyone's interested. I really like the type-families based approach to this, it's a lot easier to understand, and you can think about things functionally instead of relationally. (Switching back and forth between Prolog-ish thinking and Haskell gets old quick.) Plus you can do type arithmetic directly in place, instead of using type classes everywhere. nice, it's been tried before, etc. etc.. And of course it doesn't work with a released version of GHC, so maybe it's hoping too much that it would be on Hackage. What I was going to say was, see if there is one on hackage, otherwise there should be one there to be polished. But I guess searching haskell-cafe is your man :-) (your way to try to find any. Or the Haskell blogosphere too.) One thing that I'd like to be able to do is lazy unification on type instances, so that things like ... will work if the non-taken branch can't be unified with anything. Is this planned? Is it even feasible? I'm pretty sure it would be possible to implement a Lambda like this, but I'm not seeing it yet. Any ideas? Yeah -- that would be neat but generally tends to lead to undecidability (unless you're really careful making it a lot(?) less useful). That is, potential nontermination in the type inferencer/checker, not just in runtime. Then you'll want it to be well-defined when something is type-level-lazy, so you can reliably write your type-level algorithms. And *that* is bound to be rather difficult to define and to implement and maintain. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ambiguous constraint errors
Evan Laforge wrote: I have two related questions: #1 I'm getting some annoying type errors that I don't fully understand, and wind up having to do a workaround that I don't totally like. Here's a simplified version of my situation: data Ambi m = Ambi { ambi_monad :: m Int , ambi_int :: Int } some_ambi :: Monad m = Ambi m some_ambi = Ambi (return 5) 10 ambi_table :: Monad m = [(String, Ambi m)] ambi_table = [(default, some_ambi)] get_int :: String - Maybe Int get_int sym = fmap ambi_int (lookup sym ambi_table) --- get_int produces: Ambiguous type variable `m' in the constraint: `Monad m' arising from a use of `ambi_table' at ambi.hs:13:40-49 So I guess this means I'm not telling it which 'm', so it doesn't know how to resolve the 'return'... but the thing is, I'm not even using that value, so it doesn't matter what it resolves to. So it works if I pick some random monad: get_int sym = fmap ambi_int (lookup sym ambi_table :: Maybe (Ambi Maybe)) Note that I can't leave it as 'Monad m = Ambi m' because I still get an ambiguous type variable complaint. I'm a little disconcerted by having to pick some random dummy monad. Even worse, everything this type touches starts requiring explicit type declarations everywhere. Is there some easier way to do this? #2 This is somewhat related to another issue I've been having, which is that I have some kind of complicated type, e.g. '(SomeMonad some, Monad m) = some (SomethingM m Status)' that I use in a lot of places. It would be a lot less typing and easier to modify later if I wrote a type alias: type Command = (Monad some, Monad m) = some (State.StateT () m Status) but of course, this isn't allowed, since the type variables don't appear on the lhs, and if I put a context there, it's a syntax error. -fglasgow-exts (not sure which extension) allows the above, though I'm not quite sure what it *means*. It also allows type Command some m = (Monad some, Monad m) = some (State.StateT () m Status) which allows the polymorphism in the types to be shared across more of the function that's defined using Command: more opportunity for explicitness. While I can write it with data: data (Monad some, Monad m) = Command some m = Command (some (State.StateT () m Status)) I've been told this doesn't mean what I expect it to, which is that the context constraints propagate up to and unify with the containing type (out of curiosity, since it's accepted, what *does* this do? I think I read it somewhere once, but now I forget and can't find it). And sure enough, using this type doesn't make my type declarations have the right contexts. That Haskell-98 syntax only tells the compiler to break some times when the context isn't met. But you want the compiler to not-break at other times by supplying the information about the context being available when something else requires it. with {-# LANGUAGE GADTs #-} you should be able to use a different syntax for the same sort of thing but with the meaning you wanted: (beware of layout messed up by e-mail line wrapping) : data Command some m where Command :: (Monad some, Monad m) = some (State.StateT () m Status) - Command some m This might be a better choice than the type synonym actually, since it's in some ways less unpredictable in meaning to the type system (well, again assuming that GHC is the only Haskell implementation that matters to you). So the first problem means that I have to declare types in various inconvenient places, and the second one means that I have to type out all the various class constraints (I can still alias away the non-polymorphic bits), and all my type declarations start looking much more complicated than they are. It's a really annoying problem! The multi-param-type-class hack Daniil Elovkov mentioned is another way it's done sometimes, that also uses a few compiler extensions. CPP macros are even uglier but they can work too. Choose whatever suits you best. None of the solutions that make polymorphism more syntactically convenient will get rid of your ambiguity annoyances, and I'm not sure if the Haskell98 default()ing system is willing to default Monads. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Aren't type system extensions fun? [Further analysis]
Another valid type for foo can be done AFAICS with intersection types: foo :: (Char - a /\ Bool - b) - (a,b) But I can not comment about their inference, or usefulness in practice. Again, undecidable :) In fact, I believe that an inference algorithm for intersection types is equivalent to solving the halting problem. Type checking however is decidable, but expensive. a.k.a. find some value that matches both Char-a and Bool-b for some a and b. Could use type-classes to do it. But why, when we can just use standard tuples instead? foo :: (Char - a , Bool - b) - (a,b) Admittedly this function is isomorphic to type (Char,Bool)... but that's a different issue, with the arbitrariness of our choice of example function. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Aren't type system extensions fun? [Further analysis]
foo :: (Char - a /\ Bool - b) - (a,b) a.k.a. find some value that matches both Char-a and Bool-b for some a and b. Could use type-classes to do it. Uhmm... you mean something like (neglecting TC-related issues here) class C a b where fromChar :: Char - a fromBool :: Bool - b Oops: i meant something like class C x a b | x - a,b where fromChar :: x - Char - a fromBool :: x - Bool - b no... let me figure out what I meant. Just somehow to have a single function that takes an argument of two different types without completely ignoring it. class Arg a where whatYouPass :: a - Something instance Arg Char where whatYouPass = ... instance Arg Bool where whatYouPass = ... Then (foo whatYouPass) :: (Something, Something). Or if it was class Arg a where whatYouPass :: a - a then (foo whatYouPass) :: (Char, Bool). And I'm sure there are ways to make the return type different if you want to think about FDs etc. Zun. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ambiguous constraint errors
Evan Laforge wrote: get_int sym = fmap ambi_int (lookup sym ambi_table :: Maybe (Ambi Maybe)) Of you and the type system you're the only one who knows that that value is not used. The type system doesn't use (all) the rules you have in your mind. It follows more simple ones. You judge by values, not only types here. That is, you look at the value of ambi_int and see that it's just 10 in your (value again) some_ambi. You see that it's not ambi_int = (some_return_from_monad ambi_monad) * 3 I'm not totally understanding, but I think you're saying that I could write ambi_int in a way that it still had type Ambi m - Int but depended on the type of 'm'. I guess that makes sense, because it could run m internally and return an Int based on the result, which therefore depends on the type of 'm'. It's more obvious with other type classes. e.g. the snd of a value of type (Num a) = (a, Bool) Because what if the record/tuple was: canOverflow = (ridiculous, ridiculous = 40) ridiculous = 40 ^ 5 Then it depends on whether you pick Int or Integer (or something else) for a, even if you only look at the Bool. -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Aren't type system extensions fun? [Further analysis]
Chaddaï Fouché wrote: - Why are top-level variables and function arguments treated differently by the type system? They aren't In a sense, they are. id :: (forall a. a - a) useId :: (forall a. a - a) - (Int,Bool) brokenUseId :: (forall a. (a - a) - (Int,Bool)) brokenUseId :: (a - a) - (Int,Bool) Note that polymorphic variables in function argument types scope over the function results too by default. And that's a good thing. Otherwise, id :: a - a would be understood as brokenId :: (forall a. a) - (forall a. a) which is not at all intended (id specialized to _|_ values only). Basically, you only want higher-rank types in Haskell when you know what you're doing: due to parametric polymorphism it is less often useful to apply an argument function to, e.g., both Int and Bool than you might find in Python, for example. In Haskell, more often you would just take two functions as arguments e.g. useFunctions :: (Int - Int) - (Bool - Bool) - (Int,Bool) or more interestingly, let's make the caller be able to choose any kind of number: useFunctions2 :: (Num a) = (a - a) - (Bool - Bool) - (a,Bool) a.k.a. useFunctions2 :: forall a. (Num a) = (a - a) - (Bool - Bool) - (a,Bool) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] relational data representation in memory using haskell?
Marc Weber wrote: On Thu, May 22, 2008 at 03:34:36PM +0200, Marc Weber wrote: On Thu, May 22, 2008 at 09:11:28AM -0400, Isaac Dupree wrote: to whoever in this thread hasn't realized it: Map String (Map Int Foo) == Map (String,Int) Foo (at least to an approximation) There is another difference if you want to query ,=,,= say String = city and Int = age. Now take Map (Int, String) rec and use this index to filter all tuples having an age = 80 and beeing city there are two problems: Data.Map doesn't have a very good API for that (splitLookup is about the best you can get for ranges) Whether tupled or not, the order of the two indices matters (Int,String) vs. (String,Int) for what you can look up efficiently. It's essentially a binary tree either way (Map x (Map y rec)) or (Map (x,y) rec), sorted in the same order. (tuples sort by lexicographical order) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: MD5 performance optimizations, and GHC -via-C producing segfaulting binary
Simon Peyton-Jones wrote: | [1] I'm not sure if this is true... if it has to rebox the Int, you get | another copy floating around, not the original, right? Correct. If you have data T = MkT {-# UNPACK #-} !Int then given case x of { MkT y - h y } then GHC must re-box the 'y' before passing it to h. That's why unpacking strict fields isn't an unambiguous win. Perhaps it should be the default, though, which can be switched off, rather than the reverse. perhaps there are certain types that the compiler almost always manages to pass around unboxed -- Ints, for example? (Or at least that the extra copies aren't likely to persist for a long time, wasting some memory. Especially not if they're always unboxed in strict fields -- except for strict polymorphic fields, unfortunately.) And other types that aren't usually passed around unboxed? If this is clear, then maybe it's useful to do it by default for those types. Perhaps there should be a {-# NOUNPACK #-} pragma just in case someone wants to make sure a strict field isn't represented unboxed (not even if you give -funbox-strict-fields). -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] C++ interface with Haskell
Evan Laforge wrote: To threadjack a little bit, I've been interfacing haskell with c++. It gets awkward when the c++ structures use STL types like string and vector. Of course those are too complex for haskell to marshal to. What I've been doing is defining an XMarshal variant of the X c++ class, that uses plain c arrays. Then I marshal to that, and construct the c++ object properly from XMarshal in the c-c++ wrapper layer. On a few occasions, when the c++ class is really big and only has one STL member, I make a partially constructed c++ object, pass the array separately, and then construct the proper c++ class from the broken haskell generated one. Possibly dangerous as all get-out because I'm dealing with unconstructed c++ objects, but it seems to work. you mean, you hack around with the internal representation of those structures? Well, if you want to avoid double-copying, C++ can't access Haskell sequences, and Haskell can't access C++ sequences, I guess I don't see an alternative. Passing back to haskell is easier since I can use *vec.begin(), which according to the internet should be safe because STL guarantees that vector contents are contiguous. safe until either: the vector's contents change, if Haskell is assuming it's immutable, or more seriously, if the vector's length is changed, the pointers are invalidated and it might crash (due to reallocating for a bigger continuous memory chunk) I'm only saved by the fact that I don't have that many different kinds of classes to pass. This would be much more drudgery if I had more. Does anyone have a better solution or convention for marshalling c++ objects? not better, but, you could wrap the methods of the class and call back into C++ (through C wrappers) to do anything with the class, if it suited your purposes better and wasn't too slow I've also noticed warnings from g++ about hsc2hs's use of the OFFSETOF macro on c++ classes, but some googling of g++ mailing lists implied that it's harmless if you don't have virtual bases, and what sane person does, so I suppress it now :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] C++ interface with Haskell
you could write a C++ function to marshal a Sequence (or any Container IIRC, maybe Forward Container) to a vector (or whatever you wanted -- there are choices), and then okay let's see if I remember C++ well enough This design has extra copying. but anyway templatetypename Container std::vectortypename Container::value_type container_to_vector(Container const c) { return std::vectortypename Container::value_type(c.begin(), c.end()); } and templatetypename Container Container vector_to_sequence(std::vectortypename Container::value_type const c) { return Container(c.begin(), c.end()); } extern C { /* the temporary returned variable doesn't last long enough here */ (char*, int)/*I know C++ doesn't have this syntax of tuples*/ string_to_array(std::string const s) { return (*container_to_vector(s).begin()) } } In other words I suspect that it's possible with a minimum of boilerplate per type, (possibly including the use of macros), but I'm not sure exactly what you need to do, and I got tired of being a C++-fu expert a few years ago ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] C++ interface with Haskell
if you'd normally be linking using g++, you'll need (IIRC) -lstdc++ added to linking-ghc's command line Alfonso Acosta wrote: Although you could use gcc to link the code I wouldn't recommend it (mainly for the problems you are currently having) SImply call GHC to compile both the C and Haskell code. It will take care of finding the headers and supplying the necessary linker arguments. ghc -ffi -c foo.hs myfoo_c.c BTW, you don't need to compile viaC 2008/4/17 Miguel Lordelo [EMAIL PROTECTED]: Well Isaac...I became now a little bit smarter then yesterday!!! I show you the example that I found and on which I´m working with. File: foo.hs module Foo where foreign export ccall foo :: Int - IO Int foo :: Int - IO Int foo n = return (length (f n)) f :: Int - [Int] f 0 = [] f n = n:(f (n-1)) To get the C wrapper you insert the following command: ghc -ffi -fvia-C -C foo.hs After execution you will have these following additional files: foo.hc foo.hi foo_stub.c foo_stub.h foo_stub.o What I did next was to create a file named: myfoo_c.c, where I will call the foo function (implemented in Haskell). (you can see this example on http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html ) But the problem is to compile with gcc (must I put any flag or whatever set something) The gcc output is: myfoo_c.c:2:19: error: HsFFI.h: No such file or directory I downloaded this header file from: (I know that is not the correct way, but it was the only idea that occurs at the moment) http://www.koders.com/c/fidD0593B84C41CA71319BB079EFD0A2C80211C9337.aspx I compiled again and the following return error appears: myfoo_c.c:(.text+0x1c): undefined reference to `hs_init' myfoo_c.c:(.text+0x31): undefined reference to `foo' myfoo_c.c:(.text+0x50): undefined reference to `hs_exit' collect2: ld returned 1 exit status These functions are necessary to setup GHC runtime (see: http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html ) What I want to know is how to compile myfoo_c.c?! Is it with GCC or GHC?! Chears, Miguel Lordelo. On Wed, Apr 16, 2008 at 9:16 PM, Isaac Dupree [EMAIL PROTECTED] wrote: perhaps haskell: foreign export foo_func foo :: Int - IO Int -- I forget the rest of the syntax here C++: extern C { int foo_func(int i); } int some_cplusplus_function() { int bat = 3; int blah = foo_func(bat); return blah; } Is that all you need to do? Miguel Lordelo wrote: Hi all, Well...somehow I'm a beginner in Haskell. But actually my interest in Haskell will increase if it is possible to call a haskell function in C++. Something like GreenCard ( http://www.haskell.org/greencard/ ) simplifying the task of interfacing Haskell programs to external libraries (usually). But is there also a task to interface a foreign language with Haskell, but calling Haskell functions. Or c2hs which is an interface generator that simplifies the development of Haskell bindings to C libraries. I want to know this, because in my company some guys are doing some testing with Frotran and MatLab and I want to show them the power of haskell and the software which we are using is implemented in C++ (there is the reason to make Haskel - C++). I read somewhere that the only way for C++ calling a haskell function is to create a binding between Haskell and C and from C to C++, but a easy Hello World example was not there. Unfortunatelly I couldn't found anything usefull, like an complete example, or how to compile the code from haskell to C to C++. Can sombody help me, please :P Chears, Miguel Lordelo. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] C++ interface with Haskell
perhaps haskell: foreign export foo_func foo :: Int - IO Int -- I forget the rest of the syntax here C++: extern C { int foo_func(int i); } int some_cplusplus_function() { int bat = 3; int blah = foo_func(bat); return blah; } Is that all you need to do? Miguel Lordelo wrote: Hi all, Well...somehow I'm a beginner in Haskell. But actually my interest in Haskell will increase if it is possible to call a haskell function in C++. Something like GreenCard ( http://www.haskell.org/greencard/ ) simplifying the task of interfacing Haskell programs to external libraries (usually). But is there also a task to interface a foreign language with Haskell, but calling Haskell functions. Or c2hs which is an interface generator that simplifies the development of Haskell bindings to C libraries. I want to know this, because in my company some guys are doing some testing with Frotran and MatLab and I want to show them the power of haskell and the software which we are using is implemented in C++ (there is the reason to make Haskel - C++). I read somewhere that the only way for C++ calling a haskell function is to create a binding between Haskell and C and from C to C++, but a easy Hello World example was not there. Unfortunatelly I couldn't found anything usefull, like an complete example, or how to compile the code from haskell to C to C++. Can sombody help me, please :P Chears, Miguel Lordelo. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] naming a data structure for weighted random selection without replacement
Michał Pałka wrote: On Mon, 2008-02-18 at 11:37 +, Luke Palmer wrote: On Feb 18, 2008 5:11 AM, Stuart Cook [EMAIL PROTECTED] wrote: A while ago I wrote a little data structure that allows weighted random selection-without-replacement from a collection of values in O(log n) time.[1] I'm now in the process of packaging it up for Hackage, but I'm looking for good names for both the type and its operations. I'm pretty sure it should have Random in the name whatever it is called. Obvious idea: How about WeightedRandom? the without replacement thing is more specific. Although maybe the design could accomodate selection-with-replacement in the same package too or RandomPool? RandomHat? OutOfAHat? :-) -Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Implementing fixed-sized vectors (using datatype algebra?)
Alfonso Acosta wrote: So type-level + parametrized-data is my vote. But don't let's spend too much time discussing the name. ;-) Fair enough. type-level + parameterized-data it is then (unless someone else has a better suggestion). I'm going to begin coding now. hang on, parametrized or parameterized? -- both seem like plausible spellings, but there's an e different between what you two said! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Implementing fixed-sized vectors (using datatype algebra?)
Wolfgang Jeltsch wrote: Am Freitag, 1. Februar 2008 05:11 schrieben Sie: Wolfgang Jeltsch wrote: Well, the representation (D1,D2,D9) might be considered more readable. It has the disadvantage of a fixed maximum size for the numbers. Which takes me to a point I had already considered some time ago: Wouldn’t it be good if we had just a type data Pair val1 val2 = Pair val1 val2 and if then (val1,val2,…,valn) would just be syntactic sugar for this: val1 `Pair` (val2 `Pair` (…(valn `Pair` ())…)) I've thought of that too.. besides the asymmetry, the presence of _|_/seq makes them actually not equivalent though, unfortunately ~Isaac With Ryan’s proposal (using strictness annotations) the new representation should be equivalent to the old one. Or am I missing something? adding the strictness annotation seems to make them equivalent, yes I agree (I hadn't seen that post when I wrote that reply) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Implementing fixed-sized vectors (using datatype algebra?)
Wolfgang Jeltsch wrote: Well, the representation (D1,D2,D9) might be considered more readable. It has the disadvantage of a fixed maximum size for the numbers. Which takes me to a point I had already considered some time ago: Wouldn’t it be good if we had just a type data Pair val1 val2 = Pair val1 val2 and if then (val1,val2,…,valn) would just be syntactic sugar for this: val1 `Pair` (val2 `Pair` (…(valn `Pair` ())…)) I've thought of that too.. besides the asymmetry, the presence of _|_/seq makes them actually not equivalent though, unfortunately ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Fwd: Re: [Haskell-cafe] Re: Implementing fixed-sized vectors (using datatype algebra?)
You could solve it this way: data PairL a b = PairL a !b where (a,b,c) is syntactic sugar for PairL a (PairL b (PairL c ())) There are still potential efficiency issues, although this could be worked out in the compiler; right now it's a single operation to get from a tuple to any member, but in PairL it takes n operations to get from the root to the nth elment of the tuple. The unbox-strict-fields optimization can fix this. can it really fix that for polymorphic members? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Poor libraries documentation
Johan Tibell wrote: I imagine the laziness here was because these all match their names in the traditional libc, accessable via manpages. You may not consider that an excuse :) I don't! To do something about it I'll adopt Network.Socket and document that (I did the same with some other base module half a year ago.) I invite others to do the same, the Prelude would be a good start. It doesn't take much time. There are interesting things to document like how error conditions are handled, etc. maybe start from http://www.haskell.org/onlinereport/standard-prelude.html ... hmm, wait, that doesn't give much comments, but at least it gives a specification-style implementation and type signature, which must be why I look there ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] Re: [Haskell-cafe] Why functional programming matters
Michael Reid wrote: The power of Haskell's type system makes it feel like you are programming in a dynamic language to some degree, yet all of it is type-checked, and that is just *really* cool. to some degree, (in current Haskell compilers), it *is* more like a dynamic than a static language: except when optimized away, values of all types are represented by a pointer to their actual value. (this helps with parametric polymorphism and laziness (take :: Int - [a] - [a]).) (at least this is a difference compared to C++) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] Re: [Haskell-cafe] Why functional programming matters
Derek Elkins wrote: On Sat, 2008-01-26 at 20:49 -0500, Isaac Dupree wrote: Michael Reid wrote: The power of Haskell's type system makes it feel like you are programming in a dynamic language to some degree, yet all of it is type-checked, and that is just *really* cool. to some degree, (in current Haskell compilers), it *is* more like a dynamic than a static language: except when optimized away, values of all types are represented by a pointer to their actual value. (this helps with parametric polymorphism and laziness (take :: Int - [a] - [a]).) (at least this is a difference compared to C++) Boxing is orthogonal to dynamic/static. You can have boxing in statically typed languages, e.g. Haskell, Java, C# yes I know, although we are talking about communicating to people who don't necessarily know as much as we do. and you can have unboxed values in dynamically typed languages. really? Sure that's possible as an optimization, but I thought that to explicitly specify that would require a known static type. Or perhaps the bit-tagging by which some Scheme implementations are able to hold small integers without a pointer (IIRC)? ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: ByteString Parsec clone
Johan Tibell wrote: I tried to get Dan's thoughts on cloning parts of the Parsec interface and some of the documentation but none of the emails addresses I've tried seem to work. What's allowed when it comes to duplicating something like an API? What about the documentation? I intend it to be released under BSD3 which I believe is used for Parsec as well. legally, since it's released under BSD, you're allowed to do all that (as long as you don't delete the bit of attribution that the BSD requires :-) although a friendly attempt to contact him might be nice anyway, but don't worry too much if he's disappeared from the face of cyberspace, is the usual practice, I believe. Anyone know how I can reach Dan? not me ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why functional programming matters
fewer frustratingly unsolvable bugs down-the-road? When I have bugs in my Haskell programs (and usually I get type errors instead), I've always found them eventually and they're either a silly mistake or I realize that I misunderstood the problem I was trying to solve (it needs to be solved a different way)... which is great, being able to realize that and rewrite things! Usually not everything has to be rewritten because Haskell is pretty modular (unless used poorly :-). ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] CPP and INLINE pragmas
Adam Langley wrote: Since CPP mode removes newlines in the out macro expansion. It appears to be impossible to have a macro expand to a function with an INLINE pragma since it appears to need to be in its own line. that's because INLINE uses layout like everything else, so you can use semicolons for it too. For example: #define GETHOSTWORD(name, m, type) \ {-# INLINE name #-} \ name :: m type ; \ name = getPtr (sizeOf (undefined :: type)) \ something like #define GETHOSTWORD(name, m, type) \ {-# INLINE name #-} ; \ name :: m type ; \ name = getPtr (sizeOf (undefined :: type)) \ ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Filter by several predicates at once
Neil Mitchell wrote: Hi passall, passany :: [a - Bool] - a - Bool passall ps v = and $ map ($v) ps passany ps v = or $ map ($v) ps or something similar defined anywhere? Such that one can write nearly; using Prelude: passall ps v = all ($v) ps passany ps v = any ($v) ps One thing I have often wanted is something like: or1 a b x = a x || b x or2 a b x y = a x y || b x y yep, there's the idea of putting Bools in a typeclass that allows you to (||) functions-returning-Bool-class-instance for example, which I haven't used much but seems like a good idea (though potentially confusing, especially if the Prelude-Bool-specific names are reused) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Compiling Blobs
Peter Verswyvelen wrote: However I'm using GHC 6.8.2 on Fedora 8. BTW what do you think is the best distro for doing Haskell development? they all suck if you want to be able to try/use the latest stuff, in my experience; just install a GHC and cabal stuff in your home directory (you can install more than one GHC-version there if you want to test things with multiple versions...). There's a semi-good reason for this: distros don't like to package broken things, and usually something breaks with each different version of GHC, but not necessarily something you're relying on, and as you're doing Haskell development you may be able to help fix it. so that is, you compile (configure) things with --prefix=$HOME (or --prefix=$HOME/unix or so if you don't like your home-directory being cluttered with names like bin, lib etc.). and when using cabal you also, if it's a system-wide-installed ghc, need to give --user when configuring. And then you add whatever-you-put-for-prefix/bin to your path, e.g. in ~/.bashrc adding PATH=$HOME/bin:$PATH so that the programs (ghc, happy, alex, xmonad, whatever) will be found if you want to run them. Did I leave anything important out? now, there might be a distro system that actually worked well for this. Maybe in a couple years and once cabal-install is reasonably stable, some unconventional distro like GoboLinux or NixOS might meet my standards :-) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] the trivial monad- thoughts and a question
Brian Hurt wrote: The second question I have is: is there any hope of getting something like this into the standard library? the newtype Identity in module Control.Monad.Identity in package `mtl` is what you describe: http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Identity.html in other words, it already is practically in the standard library. The type-synonym technique doesn't work very well because, e.g., is (TrivialMonad (IO ())) = an IO function or a Trivial function? It has been thoroughly discussed before, IIRC... ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] US Homeland Security program language security risks
Bryan O'Sullivan wrote: Yitzchak Gale wrote: Perhaps Coverity's interest could be piqued if they were made aware of Haskell's emergence as an important platform in security-sensitive industries such as finance and chip design, and of the significant influence that Haskell is having on the design of all other major programming languages. During one of Simon PJ's tutorials at OSCON last year, a Coverity engineer was in the audience. He told us afterwards that he downloaded the GHC source and gave a try at analysing it while Simon talked. He didn't get far, of course; their software wasn't built for the tricks that -fvia-C plays. But they have at least one person who was that interested. unregisterised, it should be standard C without tricks, though still nothing like ordinary C and therefore possibly not analyzable ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Please allow beginners to vocalize code. = :: - - -
Wolfgang Jeltsch wrote: Am Dienstag, 8. Januar 2008 21:36 schrieb Richard Kelsall: Now supposing you were on the phone to a Haskell programmer and you wanted to say this f :: Int - Int I imagine you might say f maps Int to Int or function f has type Int to Int. Both symbols have been translated directly to words. Nobody would say f, colon colon, Int, dash greater than, Int. I would say: “f double-colon Int arrow Int”. and so we could have several columns, for exmple: symbol symbol-pronunciation meaningful-pronunc. definition-term - arrow to function (except that it's used in lots of different places in syntax... function type, lambda, case at least) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: The Worker/Wrapper Transformation
Achim Schneider wrote: Achim Schneider [EMAIL PROTECTED] wrote: [...] I'm trying to grok that [] = id ++ = . in the context of Hughes lists. they are also known as difference lists, and also used at type String in the Prelude as ShowS, to help avoid quadratic behavior when making complicated Strings. the [a]-[a] is not an ordinary function -- it's expected not to examine its argument, just to use it exactly once (is there a formal way to say that?) ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The Worker/Wrapper Transformation
Achim Schneider wrote: ...is a paper about automatic specialisation of functions by unboxing arguments, one could say. I'm only on page 6, but already survived the first formalisms, which is bound to mean that the rest of the paper is likewise accessible, as hinted on at ltu. http://www.cs.nott.ac.uk/~gmh/wrapper.pdf The transformation itself is mindbogglingly easy, which makes this a good start: You only have to understand the formalisms, not so much what the formalisms are representing. To quote spj: It usually turns out to be more interesting and challenging than it seemed at first. I'm tempted to write that this is a paper for everyone trying to figure out what the heck Jonathan is talking about. I like it! Of course the technique itself doesn't provide guidance on what type you want to transform a function to. on page 6, stronger vs weaker seemed backwards to me... isn't (wrap ◦ unwrap = idA) a stronger condition than (wrap ◦ unwrap ◦ body = body), because it tells you more, and is true in fewer cases? (which is also why you want to assume (wrap ◦ unwrap = idA) when you can, because it's the most useful one for subsequent program transformation) and then the inevitable minor copy-editing :-) p. 22. intentional properties -- intensional (right?) p. 27. typo 'unwarp' for 'unwrap' BTW. GHC currently does allow e.g. (I# (1# +# 2#)), not just (case (1# +# 2#) of n# - I# n#) -- the strictness implications seem pretty straightforwards (it's trivial to transform away). p. 29. in both these system - systems ~Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A commutative diagram conjecture about applicative functors
Twan van Laarhoven wrote: Robin Green wrote: I am proving various statements relating to applicative functors, using the Coq proof assistant (I am considering only Coq terms, which always terminate so you don't have to worry about _|_). However, I'm not sure how to go about proving a certain conjecture, which, translated back into Haskell and made more specific to make it easier to think about, looks like this (assuming Control.Applicative and Control.Arrow are imported): For all applicative functors: \f x - fmap second f * fmap ((,) (0::Int)) x is equivalent to \f x - fmap ((,) (0::Int)) (f * x) Using the laws from the Control.Applicative haddock page, and some puzzling: good! I was still confused whether 'second' was necessarily in the (,) arrow (it is, here). So I used GHCi (6.8.2), and seemed to discover a GHC bug afterwards? Prelude Control.Arrow Control.Applicative :t \f x - fmap second f * fmap ((,) (0::Int)) x \f x - fmap second f * fmap ((,) (0::Int)) x :: (Applicative f) = f (b - c) - f b - f (Int, c) :t \f x - fmap ((,) (0::Int)) (f * x) \f x - fmap ((,) (0::Int)) (f * x) :: (Applicative f) = f (a1 - a) - f a1 - f (Int, a) Unfortunately, I get puzzling type errors if I annotate either one of them with their type (e.g. (Applicative f) = f (a - b) - f a - f (Int, b) ) in an expression. The very answer doesn't seem to typecheck. :t \f x - fmap ((,) (0::Int)) (f * x) :: (Applicative f) = f (a1 - a) - f a1 - f (Int, a) interactive:1:14: Couldn't match expected type `f a1 - f (Int, a)' against inferred type `(Int, a11)' Probable cause: `(,)' is applied to too many arguments In the first argument of `fmap', namely `((,) (0 :: Int))' In the expression: fmap ((,) (0 :: Int)) (f * x) :: (Applicative f) = f (a1 - a) - f a1 - f (Int, a) :t \f x - fmap second f * fmap ((,) (0::Int)) x :: (Applicative f) = f (b - c) - f b - f (Int, c) interactive:1:13: Couldn't match expected type `f b - f (Int, c)' against inferred type `(d, c1)' Probable cause: `second' is applied to too many arguments In the first argument of `fmap', namely `second' In the first argument of `(*)', namely `fmap second f' Of course if I leave out :t and leave out all type signatures then it complains that it needs monomorphism, which is fair, but... \f x - fmap second f * fmap ((,) (0::Int)) x interactive:1:8: Ambiguous type variable `f' in the constraint: `Applicative f' arising from a use of `*' at interactive:1:8-46 Probable fix: add a type signature that fixes these type variable(s) Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A commutative diagram conjecture about applicative functors
Twan van Laarhoven wrote: Isaac Dupree wrote: Unfortunately, I get puzzling type errors if I annotate either one of them with their type (e.g. (Applicative f) = f (a - b) - f a - f (Int, b) ) in an expression. The very answer doesn't seem to typecheck. :t \f x - fmap ((,) (0::Int)) (f * x) :: (Applicative f) = f (a1 - a) - f a1 - f (Int, a) Here the type annotation applies to the *body* of the lambda abstraction, adding parentheses around the whole thing solve your problem. :t (\f x - fmap ((,) (0::Int)) (f * x)) :: (Applicative f) = f (a1 - a) - f a1 - f (Int, a) Aside from the fact that ghci has some trouble formating the output. thank you, oops, how annoying. I wonder if GHCi should output parentheses to make its :type result be a valid expression... Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Wikipedia on first-class object
Bulat Ziganshin wrote: here T is any type. you said that values of ANY TYPE can be saved to disk, so show us the way ... try to prove that this mean that value of ANY type may be saved to disk Run another program that uses lots of memory, and watch the entire Haskell program's memory be swapped out to disk. Better yet, suspend-to-disk (or hibernate) your computer. Voila -- values of any and all types have been saved to disk! In a limited fashion, of course. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring
Paulo J. Matos wrote: On Dec 23, 2007 12:44 PM, Isaac Dupree [EMAIL PROTECTED] wrote: -- this should work too parseHeader3 :: BS.ByteString - Maybe (Int, Int) --note accurate type signature, which helps us use Maybe failure-monad, --although losing your separate error messages Oh gee, I just noticed that my type sig is in fact not correct. How come GHC doesn't complain? well, it is correct for Haskell if you want program failure for parse failure... it's just not a _total_ function unless you use Maybe (which determines whether you can have the code that uses parseHeader decide what to do in the case of a failure) parseHeader3 bs = do (x, rest) - BS.readInt $ BS.dropWhile (not . isDigit) bs (y, _) - BS.readInt $ BS.dropWhile (not . isDigit) rest return (x, y) What happens then if the first BS.readInt return Nothing??? --or to be clearer without syntactic sugar, that is parseHeader3 bs = (BS.readInt $ BS.dropWhile (not . isDigit) bs) = \(x, rest) - (BS.readInt $ BS.dropWhile (not . isDigit) rest) = \(y, _) - return (x, y) when the first one returns Nothing, the whole expression becomes Nothing without examining the later parts of computation (as Chaddaï said) Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring
Brandon S. Allbery KF8NH wrote: On Dec 24, 2007, at 13:18 , Isaac Dupree wrote: Paulo J. Matos wrote: On Dec 23, 2007 12:44 PM, Isaac Dupree [EMAIL PROTECTED] wrote: parseHeader3 bs = do (x, rest) - BS.readInt $ BS.dropWhile (not . isDigit) bs (y, _) - BS.readInt $ BS.dropWhile (not . isDigit) rest return (x, y) What happens then if the first BS.readInt return Nothing??? when the first one returns Nothing, the whole expression becomes Nothing without examining the later parts of computation (as Chaddaï said) One thng that's not obvious here is that pattern match failure translates to a call to fail, which in the definition of Monad for Maybe becomes Nothing. (Hm. Isaac: I thought that translation only happened for the do sugar, and in the direct case you must do it yourself or Haskell raises the incomplete pattern match exception?) Tuple-matching never fails (except for _|_) -- there's only one constructor. In this case it's only the intrinsic failure of BS.readInt. You're thinking of something like do [a,b] - readListOfInts foo return (a+b) --readListOfInts is a function I made up :: String - Maybe [Int] which can fail (1) if readListOfInts returns Nothing (2) because of the do-notation, also if the list doesn't have exactly two elements in it. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments on reading two ints off Bytestring
-- this should work too parseHeader3 :: BS.ByteString - Maybe (Int, Int) --note accurate type signature, which helps us use Maybe failure-monad, --although losing your separate error messages parseHeader3 bs = do (x, rest) - BS.readInt $ BS.dropWhile (not . isDigit) bs (y, _) - BS.readInt $ BS.dropWhile (not . isDigit) rest return (x, y) --or to be clearer without syntactic sugar, that is parseHeader3 bs = (BS.readInt $ BS.dropWhile (not . isDigit) bs) = \(x, rest) - (BS.readInt $ BS.dropWhile (not . isDigit) rest) = \(y, _) - return (x, y) Isaac Paulo J. Matos wrote: On Dec 23, 2007 12:32 PM, Paulo J. Matos [EMAIL PROTECTED] wrote: Hello all, It is either too difficult to get two integers of a bytestring, in which case something should be done to ease the process or I should learn much more Haskell. I guess the latter is the correct guess. I have a bytestring containing two naturals. I was to get them as efficiently as possible. Here's my code: Just tried a better one, what do you think of this: parseHeader2 :: BS.ByteString - (Int, Int) parseHeader2 bs = case (BS.readInt $ BS.dropWhile (not . isDigit) bs) of Nothing - error Couldn't find first natural. Just (x, rest) - case (BS.readInt $ BS.dropWhile (not . isDigit) rest) of Nothing - error Couldn't find second natural. Just (y, _) - (x, y) parseHeader :: BS.ByteString - (Int, Int) parseHeader bs = let first = BS.readInt $ BS.dropWhile (not . isDigit) bs in if(isNothing first) then error Couldn't find first natural. else let second = BS.readInt $ BS.dropWhile (not . isDigit) $ snd $ fromJust first in if(isNothing second) then error Couldn't find second natural. else (fst $ fromJust first, fst $ fromJust second) This seems to work: parseHeader $ BS.pack hello 252 359 (252,359) Is there a better way? Cheers, -- Paulo Jorge Matos - pocm at soton.ac.uk http://www.personal.soton.ac.uk/pocm PhD Student @ ECS University of Southampton, UK ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell performance
Jon Harrop wrote: On Thursday 20 December 2007 19:02, Don Stewart wrote: Ok, so I should revive nobench then, I suspect. http://www.cse.unsw.edu.au/~dons/nobench/x86_64/results.html that kind of thing? Many of those benchmarks look good. However, I suggest avoiding trivially reducible problems like computing constants (e, pi, primes, fib) true in general, but I know I use computed constants in real code because it's cleaner than using their expanded value, so it's worth checking whether a compiler can (still) do (how much of) that. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ghc overlapping instances
Steffen Mazanek wrote: Hi, Stefan and Isaac, thx for providing quick advice. @Stefan: Unfortunately I have to use a list. @Isaac: I do not get it. Could you please provide a short example of your approach? The question still remains. Which arguments do I have ghc to start with to get the same behavior than hugs with -98 +o (here it works). I provide my example for testing purposes: module Test where import Test.QuickCheck import Monad(liftM,liftM2) type Program = [Stmt] data Stmt = Text | IfElse Program Program | While Program deriving (Eq, Show) instance Arbitrary [Stmt] where arbitrary = sized genProg instance Arbitrary Stmt where arbitrary = sized genStmt genStmt::Int-Gen Stmt genStmt 0 = return Text genStmt 1 = return Text genStmt 2 = oneof [return Text, return (While [Text])] genStmt n | n2 = oneof ([return Text, liftM While (genProg (n-1))]++ [liftM2 IfElse (genProg k) (genProg (n-k-1))|k-[1..n-2]]) genProg::Int-Gen Program genProg 0 = return [] genProg 1 = return [Text] genProg n | n1 = oneof ((liftM (\x-[x]) (genStmt n)):[liftM2 (:) (genStmt k) (genProg (n-k))|k-[1..n-1]]) prop_ConstructParse progr = True where types = progr::Program main = mapM_ (\(s,a) - putStrLn s a) [(flowchart construct and parse, test prop_ConstructParse)] is prop_ConstructParse the only thing that breaks when you remove the instance Arbitrary [Stmt] where arbitrary = sized genProg, or have I missed something? If that's all, try this (untested) : prop_ConstructParse = forAll (sized genProg) (\progr - True) and similarly for other properties. Or, you _can_ use a newtype for quickcheck-only, something like this: newtype P = P { unP :: Program } instance Show P where show = show . unP instance Arbitrary P where arbitrary = sized genProg . unP prop_ConstructParse (P progr) = True Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ghc overlapping instances
Steffen Mazanek wrote: Hello, I want to quickcheck a property on a datatype representing programs (=[Stmt]) and need to define a specific instance instance Arbitrary [Stmt] (mainly to restrict the size of the list). you don't always need to use instances. for example, I have (where Predicate is a type I defined which I gave a separate normal Arbitrary instance) arbpredicate :: Gen Predicate arbpredicate = do ... prop_assocUnify :: Property prop_assocUnify = forAll arbpredicate $ \a - forAll arbpredicate $ \b - forAll arbpredicate $ \c - ...boolean result Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] IVar
A pure readIVar would be just like lazy I/O, with similar drawbacks. With readIVar, the effect that lets you observe the evaluation order is writeIVar; with hGetContents it is hClose. Conclusion: it's probably no worse than lazy I/O. Actually, it's considerably better. +: implementation may not evaluate something that may terminate/block, anyway IVar may change from blocking to non-blocking, unlike most pure expressions. This is only meaningful if trying to evaluate it would prevent it from gaining a value. It can only have such an effect (helping the IVar gain a value) if the same thread would do any IO (if it wasn't for the unnecessary evaluation). IO is generally observable, so getting stuck on a normal non-terminating expression wouldn't be any more acceptable than getting stuck on an IVar in that case. ... all assuming unsafeInterleaveIO doesn't exist, because it's unsafe, so the semantics are undefined of when it gets evaluated relative to later normally-sequenced IO actions, if it will be eventually evaluated for sure -- right? Nevertheless its intended use generally assumes that it will be evaluated as if its evaluation might not terminate, i.e. as late as possible. If it is in fact (a finite amount of) non-blocking IO, then evaluating it early will only have consequences on when the IO happens (and therefore its effect/result), not directly on the program's non-termination or actions. It gets more confusing the more I think about it! to modify Simon's example, it looks to me like treating readIVar as potentially non-terminating, and writeIVar as potentially having side-effects, is enough: main = do --irrelevant x - newIVar let y = last [1..] print test --was irrelevant writeIVar x 3 print y Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: is there a more concise way to generate helper functions for a datatype built on records?
apfelmus wrote: Benedikt Huber wrote: type Upd a = a - a data Ref cx t = Ref { select :: cx - t , update :: Upd t - Upd cx } Functional references are also called lens, I'm going to use that term from now on. As a minor note, I somehow prefer a single primitive data Lens s a = Lens { focus :: s - (a, a - s) } nice name. there cannot be a general parallel combinator () :: Lens a b - Lens a c - Lens a (b,c) with for example players = player1 player2 That's because the two arguments might not be parallel at all. For instance, consider dup :: Lens a (a,a) dup = id id Which component of the pair should put dup :: a - (a,a) - (a,a) change? The first, the second, or even both? put :: Lens s a - a - s - s put x = flip $ snd . focus x wouldn't put dup :: (a,a) - a - a ? Arrows IIRC resolve this dilemma by arbitrarily saying the first argument of () takes effect first... a solution I'm not entirely happy with. Here, first it would put the first element of the pair, then it would put the second, so the result would be the second element. If it were 2d vectors, x::Lens Vector Double, angle::Lens Vector Angle, it makes a difference whether x-coordinate or angle is changed first, and again, () could sequence. I wish there was some way to compose them that guaranteed order-independence, and didn't work otherwise, though. I suppose QuickCheck could be used to catch most parallel/disjoint-assumption-mistakes like that... Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why aren't Float and Double Bounded?
Henning Thielemann wrote: On Mon, 26 Nov 2007, Jason Dusek wrote: Among numeric types, it seems that only integer types are Bounded. Maybe because IEEE format supports Infinity? therefore, maxBound is Infinity and minBound negative infinity? Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why aren't Float and Double Bounded?
Among numeric types, it seems that only integer types are Bounded. Maybe because IEEE format supports Infinity? therefore, maxBound is Infinity and minBound negative infinity? But IEEE can be run with projective infinity in which case there is only one of them. Well, if Double becomes a proper member of Ord (which it already almost never is, because of NaN), then, since it is defined by a finite number of bits, it can be Bounded. Maybe this means projective infinity breaks Ord like NaN does. Any of this potential variation in Double obviously breaks referential transparency too, if it depends on what implementation you're using. succ/pred are odd for Double too; even if Bounded and defined by a finite number of bits, you would not be able to have a finite [minBound..0] or [minBound..maxBound]. Basically, it's not Bounded, not for a particular reason, but just because it's rather broken from a Haskell point of view anyway, IMHO. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] placing modules in the module hierarchy
Wolfgang Jeltsch wrote: Since the Control.Grapefruit subtree would probably only consist of Control.Grapefruit.Signal and submodules, I’d prefer to just use Control.Signal and Control.Signal.*. But this would pose the problem that no other FRP library could use Control.Signal without conflicting with Grapefruit. One _ideal_ is to develop a consensus in the community for a FRP Signal library, one that is good enough that Grapefruit could use it. (If the library is inherently Grapefruit-specific, do use Control.Signal.Grapefruit or Control.Grapefruit.Signal.) Of course that ideal is not always possible, and best-library consensuses do change over the years -- but we've been doing it a lot anyway. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Recipes for organizing HUnit tests
Mushfeq Khan wrote: I'm new to Haskell and am trying to find a good way to organize my HUnit tests. Having used some of the other XUnit frameworks, I tended towards trying to organize them all in a parallel test folder structure, but this seems to be a bad fit for Haskell, since the test modules cannot see the source modules unless they are either in the same folder or a folder above it. That's without modifying the module search path when I run the tests, which I would like to avoid. Well, it's certainly possible to use parallel directory structures -- this is one way to do it: Xyzzy/Gizmo.hs: module Xyzzy.Gizmo where ... Test/Gizmo.hs: module Test.Gizmo where import Xyzzy.Gizmo main = ... ghc --make -main-is Test.Gizmo.main Test/Gizmo.hs Or without -main-is, Tests.hs: module Main where import Test.Gizmo import Test.Bar ... main = testGizmo, testBar ... ghc --make Tests Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] newbie optimization question
Prabhakar Ragde wrote: You could try giving divisors type signature: divisors :: Int - [Int] Thank you. That brings the time down to 0.5 seconds. I'm glad it was something as simple as that. --PR I assume GHC was smart enough to do inlining and such in this case, so the difference is that it defaulted to Integer, whose operations are somewhat slower. Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] viewing HS files in Firefox
When I try to go to one of the Module.hs files, e.g. on darcs.haskell.org, it now has type HS and Firefox refuses to display it (and only lets me download it). Does anyone know how to make Firefox treat certain file types as others (HS as plain text, in particular)? so that I can browse them with any convenience Thanks, Isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe