Re: [GHC] #750: Set -M and -c values based on available virtual memory
#750: Set -M and -c values based on available virtual memory -+-- Reporter: simonmar | Owner: Type: feature request | Status: new Priority: normal | Milestone: _|_ Component: Runtime System |Version: 6.4.1 Severity: normal | Resolution: Keywords: | Difficulty: Easy (1 hr) Testcase: N/A | Architecture: Unknown Os: Unknown | -+-- Changes (by igloo): * summary: Set -M value based on available virtual memory = Set -M and -c values based on available virtual memory Old description: From John Meacham: perhaps if -M is not otherwise set, {{{getrlimit(RLIMIT_AS,..)}}} could be called and the maximum heap size set to just under that, since it is the point that the OS will forcefully kill the program anyway. New description: From John Meacham: perhaps if `-M` is not otherwise set, {{{getrlimit(RLIMIT_AS,..)}}} could be called and the maximum heap size set to just under that, since it is the point that the OS will forcefully kill the program anyway. Ravi Nanavati would like to be able to set the value to a percentage of physical RAM, e.g. `prog +RTS -H256m -M95% -RTS'. Bulat Ziganshin would like to be able to do the same with `-c`. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/750 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #750: Set -M, -H, -c and other memory-related values based on available virtual/physical memory
#750: Set -M, -H, -c and other memory-related values based on available virtual/physical memory -+-- Reporter: simonmar | Owner: Type: feature request | Status: new Priority: normal | Milestone: _|_ Component: Runtime System |Version: 6.4.1 Severity: normal | Resolution: Keywords: | Difficulty: Easy (1 hr) Testcase: N/A | Architecture: Unknown Os: Unknown | -+-- Changes (by Bulat): * summary: Set -M and -c values based on available virtual memory = Set -M, -H, -c and other memory-related values based on available virtual/physical memory Comment: -H and other memory-related settings, too. Also please note that original suggestion was about *virtual* memory which is hard lmit for any program, while Ravi and me wants to easily set values based on *physical* RAM installed on computer, which is just sort of optimization -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/750 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
[GHC] #1040: read::Float does not handle string that are all digits, but end in .
#1040: read::Float does not handle string that are all digits, but end in . -+-- Reporter: guest | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Compiler | Version: 6.6 Severity: normal|Keywords: Difficulty: Unknown |Testcase: Architecture: Unknown | Os: Unknown -+-- (read a)::Float fails if a is a string that is all digits but ends int . (read 20.)::Float fails but (read 20.3):: Float succeeds compare to the c atof function which succeeds in producing a correct value in both cases -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/1040 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #1034: Added examples, more detailed documentation to Data.List functions of Extracting sublists section
#1034: Added examples, more detailed documentation to Data.List functions of Extracting sublists section +--- Reporter: guest | Owner: Type: proposal| Status: new Priority: normal | Milestone: Component: libraries/base |Version: 6.6 Severity: minor | Resolution: Keywords: | Difficulty: Easy (1 hr) Testcase: | Architecture: Unknown Os: Multiple| +--- Comment (by Andriy): No dissent. Supported by Donald Bruce Stewart, Neil Mitchell, Ross Paterson. Neil Mitchell suggested to include corner cases which I did in the second version of the patch (attached). He later suggested to add QuickCheck style properties. I decided to leave this out of scope for this proposal. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/1034 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
profiling experience
People, I describe below my small experience with the time profiling in ghc-6.6. To make sure, consider first the following simple example: --- import List (sort) main = {-# SCC main #-} let n = 5*10^4 :: Int in putStr (shows (f [1 .. n]) \n) f :: [Int] - Int f xs = {-# SCC f #-} case xs of []- 0 x: ys - (g x) + (h x) + (f ys) where g x = {-# SCC g #-} last $ sort [0 .. (rem x 10)] h x = {-# SCC h #-} last $ sort [0 .. (rem x 20)] --- Making: ghc -O -prof --make Main Running: ./Main +RTS -p -M100m -RTS This produces the report (its indentation shows which center is called from which): total time =3.00 secs (60 ticks @ 50 ms) total alloc = 130,608,300 bytes (excludes profiling overheads) COST CENTREMODULE %time %alloc h Main 65.0 67.3 g Main 33.3 30.9 main Main 1.71.5 individualinherited COST CENTRE MODULE no.entries %time %alloc %time %alloc MAIN MAIN 1 0 0.00.0 100.0 100.0 mainMain 162 1 0.00.0 0.00.0 CAF Main 156 3 0.00.0 100.0 100.0 main Main 163 0 1.71.5 100.0 100.0 f Main 164 50001 0.00.398.3 98.5 hMain 166 5 65.0 67.365.0 67.3 gMain 165 5 33.3 30.933.3 30.9 CAF GHC.Handle 109 3 0.00.0 0.00.0 To my mind, these numbers look all right: like I expected. Only I do not so firmly understand what is CAF, a constant application form, a data which has cost, is assigned cost, but is out of the stack of calls. Is this profiling all right? Then, I need to find the main time eater in a certain concrete (and complex) example. Its profiling looks strange. I set SCC in all valuable inner loops in the modules Main.hs and LemmaSearch.hs. It shows - LemSearchList +RTS -p -M200m -RTS total time = 112.00 secs (2240 ticks @ 50 ms) total alloc = 3,813,365,740 bytes (excludes profiling overheads) COST CENTREMODULE %time %alloc CAFMain 95.5 96.1 splitDisjunctSchemeLemmaSearch2.52.2 addEquationsWithReduction LemmaSearch1.31.4 - My idea was that some of the loops inside LemmaSearch must take almost all time. Instead, it shows that some CAF (anonymous, to me) in Main takes almost everything, and among places which I marked with SCC, the two are shown as 2.5% and 1.4%, and all the rest shown as zero: --- MAIN MAIN \ 1 0 0.00.0 100.0 100.0 CAF Main 2 80 57 96.0 96.199.9 99.9 ... --- The whole user project is build under -prof (auto-all skipped). The test Main.hs is built also under -prof. SCC are set only inside the functions Main.main and LemmaSearch.searchLemmataInInitial. What may consitute this strange CAF cost of 96% ? Kirsten Chevalier [EMAIL PROTECTED] wrote I didn't look at your code all that carefully, but did you build the GHC libraries with -prof -auto-all? (Not just -prof.) If you don't build the libraries with -auto-all, then cost centres won't get inserted for library functions, and if it's really a standard library function that's taking all of that time, the profiling report won't indicate that. I made ghc-6.6 from the official source in a standard way: ./configure ...; make; make install Does this presume that this
large source for `bugs' e-list
Dear GHC lists administrators, Is this appropriate to send to glasgow-haskell-bugs@haskell.org a large source archive of 800 Kb to build an example ? The code has several SCC marks, and maybe someone could look into why ghc-6.6 profiling reports such strange numbers, or explain why they are not strange. Regards, - Serge Mechveliani [EMAIL PROTECTED] ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: large source for `bugs' e-list
goto http://hackage.haskell.org/trac/ghc login with guest/guest and add a New Ticket. There you can upload a large archive. Christian (a non-list administrator) Serge D. Mechveliani schrieb: Dear GHC lists administrators, Is this appropriate to send to glasgow-haskell-bugs@haskell.org a large source archive of 800 Kb to build an example ? The code has several SCC marks, and maybe someone could look into why ghc-6.6 profiling reports such strange numbers, or explain why they are not strange. Regards, - Serge Mechveliani [EMAIL PROTECTED] ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: % of memory unit to heap-controlling RTS flags
On Mon, Dec 04, 2006 at 01:15:16PM +0300, Bulat Ziganshin wrote: Monday, December 4, 2006, 4:19:45 AM, you wrote: and -H to (say) 25% of physical RAM. i had exactly the same idea. in particular, i want to setup -c value as percentage of available RAM I've added these suggestions to trac #750: http://hackage.haskell.org/trac/ghc/ticket/750 Thanks Ian ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: profiling experience
On 12/6/06, Serge D. Mechveliani [EMAIL PROTECTED] wrote: What may consitute this strange CAF cost of 96% ? Kirsten Chevalier [EMAIL PROTECTED] wrote I didn't look at your code all that carefully, but did you build the GHC libraries with -prof -auto-all? (Not just -prof.) If you don't build the libraries with -auto-all, then cost centres won't get inserted for library functions, and if it's really a standard library function that's taking all of that time, the profiling report won't indicate that. I made ghc-6.6 from the official source in a standard way: ./configure ...; make; make install Does this presume that this also generates the .p.o GHC library versions for -prof -auto-all ? No; you must have built the profiling libraries (i.e., building the libraries with -prof), otherwise you wouldn't have been able to compile your code for profiling. But, building the profiling libraries in the standard way doesn't add -auto-all to the compile flags. So if you want to build the libraries with -auto-all, do: make EXTRA_HC_OPTS=-auto-all but be careful! As I said in my previous message, adding cost centres disables some optimizations, so the profiling results you get from this may not be accurate with respect to what would happen if you ran your code after building it with -O and no profiling. Cheers, Kirsten -- Kirsten Chevalier* [EMAIL PROTECTED] *Often in error, never in doubt I cannot remember a time when I did not take it as understood that everybody has at least two, if not twenty-two, sides to him.--Robertson Davies ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: generic ghc binary Linux (x86_64) misses libHSghc
Christian Maeder schrieb: having just installed http://www.haskell.org/ghc/dist/6.6/ghc-6.6-x86_64-unknown-linux.tar.bz2 it occurs that libHSghc.a is missing, but ghc-pkg lists (ghc-6.6). I've rebuilt this binary distribution (having 38 MB now). It can be obtained from: http://www.informatik.uni-bremen.de/agbkb/forschung/formal_methods/CoFI/hets/linux/versions/ghc-6.6-x86_64-unknown-linux.tar.bz2 ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
'accept' behavior with an asynchronous exception inside of a 'block'
Chris Kuklewicz suggested I direct this question to the developers ^_^ If I use a network accept inside a block: block ( ... (clientSocket, sockAddr) - accept serverSocket ... ) and the 'accept' unblocks a pending asynchronous exception and the exception gets thrown, does this mean that the 'accept' won't have accepted a network connection? Certainly this seems like desirable behavior, since if the 'accept' call might accept a network connection and *then* raise the asynchronous exception, the reference to the accepted connection would be lost. However I couldn't tell from the library documentation whether this was intended to be a guarantee of the 'accept' function or not. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: [Haskell] GHC Error question
I agree that this is confusing. Here is a cut-down example: class C a b where op :: a - a -- f :: C a b = a - a f x = op x It doesn't get much simpler than that! Indeed not. I salaam in your general direction. With the type sig, GHC can't see that the (C a b) provided can satisfy the (C a b1) which arises from the call to op. However, without the constraint, GHC simply abstracts over the constrains arising in the RHS, namely (C a b1), and hence infers the type f :: C a b1 = a - a It is extremely undesirable that the inferred type does not work as a type signature, but I don't see how to fix it Pity. Do you see a way for the error message to avoid suggesting the 'possible fix', and indeed instead suggesting 'possible fix: remove the type signature from f'? Simon | -Original Message- From: | [EMAIL PROTECTED] [mailto:glasgow-haskell-users- | [EMAIL PROTECTED] On Behalf Of Norman Ramsey Sent: 06 December 2006 | 01:41 To: Simon Peyton-Jones Cc: GHC users Subject: Re: [Haskell] GHC | Error question | | [redirecting to ghc users] | | It looks like a splendid error to me. | | I'm not sure if you meant the error or the message was splendid :-) | I yelled for help because my usual strategy failed. That strategy is | | 1. Remove the type annotation. | 2. Get ghci to tell me what the 'right type' is. | 3. Put the 'right type' in the type annotation. | | I find it a bit depressing that the most general type inferred by ghci | does not work as a type signature. | | I can't say more without seeing the code. can you give a small repo | case? | | Yes, here's a case that fits in one screen of emacs :-) | | | {-# OPTIONS -fglasgow-exts #-} | module Ccomp where | | type Name = String | | data Inface = N | W | data Outface = S | E | | data Sink box = Boxin Inface box | Result | data Source box = Boxout Outface box | Arg Inface | | data Command = Send0 | | class (Monad b) = Builder b box where | box :: Command - b box | wire :: Source box - Sink box - b () | | type Env box = Name - Sink box | | empty = \x - error (x ++ not connected or multiply connected in | circuit) | | -- either of these explicit signatures causes the compiler to fail -- | although the inferred signature is the second. --compile1 :: (Builder b | box) = Name - Name - ANF - b Name compile1 :: (Builder t box) = t1 | - Name - ANF - t t1 -- generated by ghci compile1 f x body = do env - | compile body empty |wire (Arg W) (env x) |return f | | data ANF = ANF () | | compile :: (Builder b box) = ANF - Env box - b (Env box) | compile (ANF m) out = undefined | | | This program is rejected by GHC with the following message: | | | | Ccomp.hs:54:23: | | Could not deduce (Builder b box1) from the context (Builder b | | box) | | arising from use of `wire' at Ccomp.hs:54:23-42 | | Possible fix: | | add (Builder b box1) to the type signature(s) for `compile1' | | In the expression: wire (Arg W) (env x) | | In a 'do' expression: wire (Arg W) (env x) | | In the expression: | | do env - compile body empty | |wire (Arg W) (env x) | |return f | | | | Note that compile1 has an explicit type signature much along the | | lines suggested by GHC. If I *remove* this type signature, the | | function compiles successfully, and ghci reporets this type for | | compile1: | | | | compile1 :: (Builder t box) = t1 - Name - Ir.ANF - t t1 | | | | I believe this signature is isomorphic to the explicit signature I | | had attempted to use. | ___ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
[Haskell] Network accept loop with graceful shutdown implementation
I have a prospective implementation of a network accept loop with graceful shutdown. This email builds upon the previous discussion Help needed interrupting accepting a network connection. In this code, just the accept loop part has been factored out and put into its own module. My hope is that if a fully correct version can be written, it will be useful to other projects. The source is available at http://code.catdancer.ws/acceptloop/ and is in the public domain. This AcceptLoop module is currently experimental, relying on an either-or guarantee for interruptible operations... which I don't know yet whether Haskell implementations provide -- or even intend to provide. Chris Kuklewicz provided several critical insights: * The return value of the 'accept' call can be passed out of the accept thread, allowing the code which implements accept with graceful shutdown to be separated from the code which handles the incoming client connection. * Inside of a 'block', interruptible operations may not (will not?) allow an asynchronous exception to be raised if the operation does not block. * Clarification for me of the desirable property that inside of a 'block', interruptible operations are either-or: either they allow an asynchronous operation to be raised, or they perform their operation, but not both. I made the following design decisions: In my original implementation, I used a custom datatype to throw a dynamic asynchronous exception to the thread calling 'accept'. In Chris' rewrite, he used 'killThread', which throws a 'ThreadKilled' asynchronous exception. I choose to continue to throw (and catch) only the specific, custom exception for the purpose of breaking out of the 'accept'. A robust implementation may need to catch other exceptions, however the desired behavior of the thread on receiving an *unexpected* exception may be different, and so I choose to leave handling of such an unexpected exception unimplemented for now. Chris uses STM instead of MVar's for communication with the accept thread. The challenge of writing code with STM or MVar's in the presence of asynchronous exceptions is exactly the same: either a call to 'atomically' or a call to an MVar operation such as 'putMVar' may allow an asynchronous exception to be raised inside of a 'block', and the code then needs to deal with that. It seems to me that MVar's could be implemented in terms of STM, and so the question is: are MVar's a more natural, higher level description of the desired semantics in this case, and would composable transactions be useful? A key insight is that in this implementation, a separate thread is used not for the purposes of concurrency, but solely to limit the scope of the thrown asynchronous exception. Once a result is available from the accept thread (either Just an incoming connection, or Nothing to say that the accept loop has shutdown), that result can then be used in a concurrent fashion, such as being handled in a child thread, passed into an STM transaction or written to a channel, etc. But there is no need to use composable transactions *inside* of the AcceptLoop module. Thus the only reason to use STM instead of MVar's inside the implementation is if it turns out that STM has the desired either-or behavior but MVar's don't. To avoid the unlock (return ()) issue that Chris discovered, this implementation uses an additional MVar to indicate that a shutdown is in process. Thus (if the implementation is correct) the accept loop will shutdown either because of the MVar flag or by receiving the asynchronous exception inside of the 'accept'. To address the issue that Chris noticed of a race condition that new threads cannot be started in a 'block' state, yet another MVar is set by the accept thread to indicate that it is now inside of a 'block' and is ready to receive the asynchronous exception. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Re: GHC Error question
Norman Ramsey wrote: compile1 :: (Builder b box) = t - Name - Ir.ANF - b t compile1 f x body = do env - compile body empty wire (Arg W) (env x) return f class (Monad b) = Builder b box where wire:: Source box - Sink box - b () This program is rejected by GHC... He continued, [paraphrase] however, compile1 is accepted if the signature is removed. Furthermore, the inferred signature seems identical to the one given above. That is not a bug... What to do? If applicable, add a functional dependency ... Or, one may use the local type variable to the same end compile1 :: forall b t box. (Builder b box) = t - Name - Ir.ANF - b t compile1 f x body = do env - compile body empty wire ((Arg W)::Source box) (env x) return f the explicit `forall' binder is required. This suggestion, I like. I have always hated that ML and Haskell leave the foralls implicit. Bad design. To be sure I understand: the reason the explicit forall is required is to bring 'box' into scope so it can be used in the type constraint on (Arg W)? Norman ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Re: GHC Error question
Or, one may use the local type variable to the same end compile1 :: forall b t box. (Builder b box) = t - Name - Ir.ANF - b t compile1 f x body = do env - compile body empty wire ((Arg W)::Source box) (env x) return f the explicit `forall' binder is required. This suggestion, I like. I have always hated that ML and Haskell leave the foralls implicit. Bad design. I'm afraid I may disagree about the quantification. Also, I'm cautious about the phrase ML and Haskell. In GHC 6.4, local type variables behave pretty much like those in ML (actually, GHC 6.2 was closer). In GHC 6.6, the behavior is completely different! Regarding the quantification: in ML (OCaml) we can write let foo (x:'a) y = (x+1,(y:'a)) That does not mean that foo has the type forall 'a. 'a - 'a - ... Indeed, foo is not polymorphic and its inferred type is int - int - int * int. If there should be a quantifier in the above type, it probably should be 'exists' rather than 'forall'. It seems in ML, the type variables are better understood as names of some types; if two subterms are annotated with the same type variable, these two subterms must have the same type. Thus the annotation adds an equation/constraint to the pool of type equations to solve. I must admit I find that constraint-based view quite intuitive. GHC 6.6 has changed things dramatically for the sake of wobbly inference and boxy types (or boxy inference and wobbly types...). Now, a type variable is a rigid type variable. The new GHC rules are described in http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html in Section 7.4.10, Lexically scoped type variables. In particular, Subsection 7.4.10.2 confirms your understanding for the need of the explicit forall. Incidentally, as far as your example is concerned, forall as a binder is required already in GHC 6.4. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Re: GHC Error question
[EMAIL PROTECTED] wrote: I'm afraid I may disagree about the quantification. Also, I'm cautious about the phrase ML and Haskell. In GHC 6.4, local type variables behave pretty much like those in ML (actually, GHC 6.2 was closer). In GHC 6.6, the behavior is completely different! Regarding the quantification: in ML (OCaml) we can write let foo (x:'a) y = (x+1,(y:'a)) That does not mean that foo has the type forall 'a. 'a - 'a - ... Indeed, foo is not polymorphic and its inferred type is int - int - int * int. If there should be a quantifier in the above type, it probably should be 'exists' rather than 'forall'. It seems in ML, the type variables are better understood as names of some types; Be cautious about the phrase ML here as well. ;-) Because what you describe only applies to OCaml. In Standard ML, the semantics of type variables in annotations is saner: the equivalent of the above declaration would be rejected. AFAICS it is basically equivalent to the new behaviour of GHC 6.6. Cheers, - Andreas ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: infix MPTC?
droundy: I was just thinking today. Is there any reason we couldn't have infix multiparameter typeclasses? For typeclasses standing as witnesses of relationships it'd be much clearer, for example to have something like (a :: b) rather than the always-vague (LT a b) which either reads the same as the infix version or backwards. This isn't so much a proposal as a query regarding reasonableness. I certainly wouldn't like to have precedence rules for type classes, but perhaps if you simply always required parentheses it'd be more readable than always requiring prefix notation, and yet still not too insane to parse? I think they are valid now! Here's an example: class a :=: b where from: http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#infix-tycons Perhaps underappreciated, along with: f :: (a :=: b) = a - b -- Don ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: infix MPTC?
On Thu, Dec 07, 2006 at 12:39:35PM +1100, Donald Bruce Stewart wrote: droundy: I was just thinking today. Is there any reason we couldn't have infix multiparameter typeclasses? For typeclasses standing as witnesses of relationships it'd be much clearer, for example to have something like (a :: b) rather than the always-vague (LT a b) which either reads the same as the infix version or backwards. [...] I think they are valid now! Silly me! I didn't even think to try! Nice. And thanks! -- David Roundy Department of Physics Oregon State University ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: [Haskell-cafe] Re: Beginner: IORef constructor?
On Wednesday 06 December 2006 07:40, Bernie Pope wrote: On 05/12/2006, at 1:00 PM, Benjamin Franksen wrote: Bernie Pope wrote: If you want a global variable then you can use something like: import System.IO.Unsafe (unsafePerformIO) global = unsafePerformIO (newIORef []) But this is often regarded as bad programming style (depends who you talk to). Besides, isn't this example /really/ unsafe? I thought, at least the IORef has to be monomorphic or else type safety is lost? Perhaps your question is rhetorical, Half-way ;-) I was pretty sure but not 100%. Thanks for the nice example. Cheers, Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: (a - [b]) - [a - b] ?
while pondering over the four fours problem, I wondered: Is there a function of type (a - [b]) - [a - b] It looks a bit like sequence when applied in the ((-) a) Monad: sequence :: [a - b] - a - [b] but I was looking for the other direction. I came up with: \g - map (\n a - g a !! n) [1..] which has the desired type and functionality, but it looks rather inelegant and messy. Any better ideas? While you showed that there exists unsequence :: (a - [b]) - [a - b] , I doubt that it's very useful. The point is that (sequence) is not surjective: (a - [b]) has strictly more functions than [a - b]. (a - [b]) has the freedom to adjust the length of the resulting depending on a list whereas [a - b] hasn't. (sequence) converts an Applicative Functor to a Monad but there is no canonical other way round. In other words, unsequence . sequence === id butsequence . unsequence =/= id Regards, apfelmus ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] state updates and efficiency
I'll make a random comment... Tim Newsham wrote: I am writing some code with complex nested state. I have a question about performance with respect to the State monad and the Reader monad. A side comment is this code: instance MonadReader s (State s) where ask = get local f m = fmap (fst . runState m . f) get or local f m = do s - get put (f s) a - m put s return a With an instance like this you can mix in generic MonadReader code. Feel free to replace State with your own instance of MonadState. This is somewhat long, so a quick summary of the question up front: Can the compiler optimize out state updates that dont change the state? I am not the compiler expert, but I think this is unlikely. For GHC you should compile with optimizations and dump the Core code to see if it does what you want. (-ddump-simp option I think). The question inline with the code: module Test where import Control.Monad.State import Control.Monad.Reader I have some nested state. This is a simplified example where we have one record inside another. In my real-world example there is more nesting and there are lists and maps involved as well. data T1 = T1 { f1 :: Int, f2 :: T2 } deriving(Show) data T2 = T2 { f3 :: Int, f4 :: Int } deriving(Show) I want to build generic modifiers and reuse them often. A good example is modifying a numeric value: adjNum :: (Num a) = a - State a () adjNum n = modify (+ n) This is not much shorthand. But by way of example it is fine. I'm going to be writing state code for my T1 structure which is my master structure. If I'm going to be able to reuse adjNum I am ^ This is a slightly odd engineering goal. going to have to run a nested state action inside an enclosing ^ You want performance but this pushes more work to the compiler. If this were all functional instead of Monadic it might be simpler to start with. state monad. I can build a lifter that does this as long as I know how to extract the nested state and set it back in the enclosing state: withInnerM :: (o - i) - (i - o - o) - State i a - State o a withInnerM gettor settor act = do outer - get let inner = gettor outer (ret, inner') = runState act inner outer' = settor inner' outer put outer' return ret Now we can make lifters for each of the fields: withF1M = withInnerM f1 (\f r - r {f1=f}) withF2M = withInnerM f2 (\f r - r {f2=f}) withF3M = withInnerM f3 (\f r - r {f3=f}) withF4M = withInnerM f4 (\f r - r {f4=f}) Main *main comment* is to separate manipulating the complex data structure from the State commands. And to make it more abstract: get1,get3,get4 :: T1 - Int get2 :: T1 - T2 get1 = f1 get2 = f2 get3 = f3 . get2 get4 = f4 . get2 put1,put3,put4 :: Int - T1 - T1 put2 :: T2 - T1 - T1 put1 x o = o {f1=x} put2 x o = o {f2=x} put3 x o = mod2 (\o2 - o2 {f3=x}) o put4 x o = mod2 (\o2 - o2 {f4=x}) o mod1,mod3,mod4 :: (Int-Int) - T1 - T1 mod2 :: (T2-T2) - T1 - T1 mod1 f o = put1 (f (get1 o)) o mod2 f o = put2 (f (get2 o)) o mod3 f o = put3 (f (get3 o)) o mod4 f o = put4 (f (get4 o)) o And note the different but important design choice: You don't need to know how the data is nested to access a field. If you insert a T1'and'a'half data field between T1 and T2 then you just need to update get2/put2 to fix (get|put|mod)(3|4) and this also fixes all the code that uses any of these functions. which lets us write some state code for T1 using building blocks like adjNum. For example, the following code will add a value to f1, add another value to f2's f3 and finally return the value of f2's f4: tweakT1 :: Int - Int - State T1 Int tweakT1 v1 v3 = do withF1M $ adjNum v1 withF2M $ withF3M $ adjNum v3 withF2M $ withF4M $ get The above would break if you added T1'and'a'half since it needs to know the structure of the data. This is why withF3M is not a good abstraction. Now for my version of tweakT1: -- My choice is to use a strict modify that also returns the new value modify' :: (MonadState a m) = (a - a) - m a modify' f = do x - liftM f get put $! x return x -- Now tweakT1 can be a one-liner or longer tweakT1,tweakT1'long :: (MonadState T1 f) = Int - Int - f Int tweakT1 v1 v3 = liftM get4 (modify' (mod1 (+ v1) . mod3 (+ v3))) tweakT1'long v1 v3 = do modify (mod1 (+ v1)) modify (mod3 (+ v3)) liftM get4 get If you want something like adjNum, how about adjNum' :: (Num a) = a - ((a-a) - s-s) - State s a adjNum' x mod = modify' (mod (+ x)) tweakT1'adj v1 v3 = do adjNum' v1 mod1 adjNum' v2 mod3 liftM get4 get The compiler may or may not optimize the mod1 and mod3 into one T1 construction instead of two. If you modify parts 1 and 3 of the state in tandem a lot then mod13 g1 g3 o@(T1 {f1=v1,f2=v2@(T2
Re: [Haskell-cafe] non-blocking Socket
On Mon, Nov 13, 2006 at 12:44:05PM -0800, Donn Cave wrote: Threads, maybe? Is blocking I/O seriously incompatible with the GHC threading model (or one of the models)? The problem is that a blocking IO call would block all threads. We could execute all such calls in their own OS thread, but that would be expensive. There is a bug about not using blocking IO: http://hackage.haskell.org/trac/ghc/ticket/724 but I don't think there's a plan for what to do instead yet. If I have external library functions that use socket I/O internally, e.g., an OpenLDAP interface, that's effectively the same as a blocking socket created in Haskell, so whatever problem with one is the same with the other, right? The same problems occur, yes. If you want it to use an OS thread then use the threadsafe safety modifier on the foreign import declarations. Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: File locked unnecessarily
Ian Lynagh wrote: Does anyone know what could cause this locking and/or how to prevent it? Nothing else springs to mind. Are you able to send an example that shows the problem? (obviously the smaller the example, the better). I'll try to cut down the offending program to a workable size. This will take a while. By the way, the rewrite I mentioned (which introduced the unwanted locking) did not touch the code which deals with the file, but it did change the program to load that code dynamically (using hs-plugins). Could that possibly be related to the file locking problem? Thanks, Arie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] state updates and efficiency
I'll make a random comment... Thanks for the comments! instance MonadReader s (State s) where ask = get local f m = fmap (fst . runState m . f) get ahh, hadn't thought of doing that. You want performance but this pushes more work to the compiler. If this were all functional instead of Monadic it might be simpler to start with. My code has a lot of values in each record, maps of records, records with lists in them, etc. I actually wrote some of the code without using the state monad to start. It was a little complicated. Rewriting it with the state monad made it more modular and shorter (if you dont count all of the lifters I had to write). withF1M = withInnerM f1 (\f r - r {f1=f}) Main *main comment* is to separate manipulating the complex data structure from the State commands. And to make it more abstract: get1,get3,get4 :: T1 - Int get2 :: T1 - T2 get1 = f1 And note the different but important design choice: You don't need to know how the data is nested to access a field. My code doesnt only operate at the top-most layer. There are some complex state transformations that logically occur on one structure thats nested down several layers. So those operations are most naturally written with a State monad on that object. Other operations are written at a higher layer but may still need access to some lower layer state... So, if I were to follow your suggestion, I would have to make several variations of the accessors/modifiers depending on what level I were to access them from. One reason I went with the lifters was to avoid any blow-up in the number of accessors I had to write (and in hopes that later I can auto-generate them). If you insert a T1'and'a'half data field between T1 and T2 then you just need to update get2/put2 to fix (get|put|mod)(3|4) and this also fixes all the code that uses any of these functions. Yes. This is a downside. I do have some abstractions that try to hide this occasionally... -- My choice is to use a strict modify that also returns the new value modify' :: (MonadState a m) = (a - a) - m a modify' f = do x - liftM f get put $! x return x -- Now tweakT1 can be a one-liner or longer tweakT1,tweakT1'long :: (MonadState T1 f) = Int - Int - f Int tweakT1 v1 v3 = liftM get4 (modify' (mod1 (+ v1) . mod3 (+ v3))) I like it. The compiler may or may not optimize the mod1 and mod3 into one T1 construction instead of two. If you modify parts 1 and 3 of the state in tandem a lot then mod13 g1 g3 o@(T1 {f1=v1,f2=v2@(T2 {f3=v3})}) = o {f1=g1 v1,f2=v2 {f3=g3 v3}} not the prettiest function in the bunch. I can see maybe using something like that if profiling said I really really needed it... withRead $ withF2R $ withF4R $ ask And that was a very roundabout way to derive liftM get4 == withRead . withF2R . withF4R true, but its composable and usable at all layers. I could have written withRead $ withF4R $ ask in a State T2 a monad or withRead $ withXXX $ withYYY $ withF2R $ withF4R $ ask at a much higher level... Thanks for your comments. I need to think over my code to figure out if it makes sense to hide the nestings (I suspect the answer is sometimes), but I think I can definitely do that in some cases. I'm starting to think that it might make sense for me to eliminate some of the nesting using cross-references (something simple like an integer ID with maps mapping IDs to objects at the top level). Then perhaps most of my state manipulations will occur at the top level (among having other benefits)... Starting to feel more DB-like. Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Would someone explain this code to me?
I'm reading Chris Okasaki's Purely Functional Data Structures, and some of his Haskell is confusing me. He defines the type Color and RedBlackSet as: data Color = R | B data RedBlackSet a = E | T Color (RedBlackSet a) a (RedBlackSet a) and then later he defines a function insertSet: insertSet x s = T B a y b where ins E = T R E x E ... T _ a y b = ins s What I don't understand is his use of the T constructor, both at insertSet x s = T B a y b and in the where statement: T _ a y b = ins s Is T being redefined, so the T called in the first line is a new function that happens to be called T which is defined in the where statement? If that was the case, I would expect this to work: insertSet x s = foo B a y b where ins E = foo R E x E ... foo _ a y b = ins s but it does not. If anyone can explain what's going on here, I'd appreciate it. Thank you! Justin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Would someone explain this code to me?
Justin Bailey [EMAIL PROTECTED] writes: I'm reading Chris Okasaki's Purely Functional Data Structures, and some of his Haskell is confusing me. He defines the type Color and RedBlackSet as: data Color = R | B data RedBlackSet a = E | T Color (RedBlackSet a) a (RedBlackSet a) and then later he defines a function insertSet: insertSet x s = T B a y b where ins E = T R E x E ... T _ a y b = ins s What I don't understand is his use of the T constructor, both at insertSet x s = T B a y b Here it creates a new RedBlackSet and in the where statement: T _ a y b = ins s Here it's a pattern match. So if ins s returns (T x a' y' b'), then a = a'; y = y'; b = b' are used in the expresion covered by the where clause. -- Jón Fairbairn [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Would someone explain this code to me?
On 06 Dec 2006 19:33:51 +, Jón Fairbairn [EMAIL PROTECTED] wrote: and in the where statement: T _ a y b = ins s Here it's a pattern match. So if ins s returns (T x a' y' b'), then a = a'; y = y'; b = b' are used in the expresion covered by the where clause. Great, thanks for clearing that up. Sometimes Haskell is a bit too concise! Justin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Would someone explain this code to me?
What I don't understand is his use of the T constructor, both at insertSet x s = T B a y b Here it creates a new RedBlackSet and in the where statement: T _ a y b = ins s Here it's a pattern match. So if ins s returns (T x a' y' b'), then a = a'; y = y'; b = b' are used in the expresion covered by the where clause. If you're wondering how the compiler tells the difference, have a look at section 2.4 of the Haskell 98 Report (Identifiers and Operators). Roughly, an identifier beginning with a lowercase letter or underscore must be a variable identifier, while an identifier beginning with an uppercase letter must be a constructor identifier. In other words, the second example above cannot be the definition of a function called T, because T cannot be the name of a function. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] GADTs vs arrows/typeclasses
I don't think I'm the only one confused here. Henrik Nilson in his paper on adding GADTs to Yampa comments that: However, the recent addition of Generalized Algebraic Data Types (GADTs) [26] to the list of Haskell extensions supported by the Glasgow Haskell Compiler (GHC) gives programmers a lot more freedom. GADTs are a limited form of dependent types, offering a considerably enlarged scope for capturing and thus en- forcing important code and data invariants statically. In particular, GADTs are just what is needed to address the problem discussed above since the key idea is to allow constructors that have more spe- cific types than usual, and to take that extra type information into account in individual case branches. GADTs would no doubt also offer an interesting alternative to the methods described by Baars and Swierstra [1] and Hughes [19]. [1] and [19] are papers about Arrows. I guess I'm also not sure what belongs in a GADT and what belongs in a typeclass e.g. here is an Arrow GADT data Arrow b c where Arr::(b-c) - Arrow b c Compose::Arrow b c - Arrow c d - Arrow b d First::Arrow a b - Arrow (a,c) (b,c) When Arrow is defined like this, rather than write instances you just various evaluation functions for the Arrow GADT. -Alex- __ S. Alexander Jacobson tel:917-770-6565 http://alexjacobson.com On Tue, 5 Dec 2006, Neil Mitchell wrote: Hi It seems like Haskell has two emerging idioms for parsing and fsms: GADTs and Arrows. What about something else? If you limit yourself to the two things that look new and cool (where emerging is another word for new, and idiom seems to be the current Haskell word for cool), you miss out on all the tried and tested stuff. I am thinking about using one of these idioms to represent server structure in a future version of HAppS but I'm not sure where to start. Why would one choose one or the other? I would pick Arrows (over GADTs) because Arrows are Haskell, and are supported by multiple Haskell compilers. Other than that (as far as I was aware) these two things are massively different, so I wouldn't have thought it was a one or the other choice usually. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: File locked unnecessarily
Yes. I've run into similar issues with hs-plugins (albeit not the same). What platform are you running on? How are you compiling your code? Try compiling it with the -threaded flag and see if it fixes your problem. On 12/6/06, Arie Peterson [EMAIL PROTECTED] wrote: Ian Lynagh wrote: Does anyone know what could cause this locking and/or how to prevent it? Nothing else springs to mind. Are you able to send an example that shows the problem? (obviously the smaller the example, the better). I'll try to cut down the offending program to a workable size. This will take a while. By the way, the rewrite I mentioned (which introduced the unwanted locking) did not touch the code which deals with the file, but it did change the program to load that code dynamically (using hs-plugins). Could that possibly be related to the file locking problem? Thanks, Arie ___ 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] Would someone explain this code to me?
Justin Bailey wrote: I'm reading Chris Okasaki's Purely Functional Data Structures, and some of his Haskell is confusing me. He defines the type Color and RedBlackSet as: data Color = R | B data RedBlackSet a = E | T Color (RedBlackSet a) a (RedBlackSet a) and then later he defines a function insertSet: insertSet x s = T B a y b where ins E = T R E x E ... T _ a y b = ins s What I don't understand is his use of the T constructor, both at insertSet x s = T B a y b and in the where statement: T _ a y b = ins s ... If anyone can explain what's going on here, I'd appreciate it. Thank you! If you ask correctly GHC will explain for you, with utmost verbosity. It would be a lot more productive for you to look over the Haskell Report and ask questions, but I had more fun working out this approach. So, shall we continue this long and useless but hopefully interesting journey? To turn a module into a program that dumps the AST for the definitions in that module, Replace module *Name* where *imports* *definitions* with {-# OPTIONS -fth #-} module Main where *imports* import Language.Haskell.TH main = do {print = runQ [d| *definitions |]} I can wrap up your example like this {-# OPTIONS -fth #-} module Main where import Language.Haskell.TH main = do {print = runQ [d| data Color = R | B data RedBlackSet a = E | T Color (RedBlackSet a) a (RedBlackSet a) insertSet x s = T B a y b where ins E = T R E x E T _ a y b = ins s |]} Build like this ~$ ghc --make ExplainExample and run to get this ~$ ./ExplainExample [DataD [] Color [] [NormalC R [],NormalC B []] [],DataD [] RedBlackSet [a_0] [NormalC E [],NormalC T [(NotStrict,ConT Color),(NotStrict,AppT (ConT RedBlackSet) (VarT a_0)),(NotStrict,VarT a_0),(NotStrict,AppT (ConT RedBlackSet) (VarT a_0))]] [],FunD insertSet [Clause [VarP x_1,VarP s_2] (NormalB (AppE (AppE (AppE (AppE (ConE T) (ConE B)) (VarE a_4)) (VarE y_5)) (VarE b_6))) [FunD ins_3 [Clause [ConP E []] (NormalB (AppE (AppE (AppE (AppE (ConE T) (ConE R)) (ConE E)) (VarE x_1)) (ConE E))) []],ValD (ConP T [WildP,VarP a_4,VarP y_5,VarP b_6]) (NormalB (AppE (VarE ins_3) (VarE s_2))) [ This is very similar -ddump-parsed GHC flag, except that pretty prints the AST back into normal Haskell syntax, losing all the unambiguous labels. If there was some way to get the AST printed with reasonable newlines and indentation, you might actually be able to match this back to your syntax. Maybe combining Data.Generics with some pretty printer library could do that easily, but that's a story for another time. Supposing you could match this back to your syntax, you would find that ins E = T B a y b became FunD ins_3 [Clause [ConP E []] (NormalB (AppE (AppE (AppE (AppE (ConE T) (ConE R)) (ConE E)) (VarE x_1)) (ConE E))) []] and T _ a y b = ins s became ValD (ConP T [WildP,VarP a_4,VarP y_5,VarP b_6]) (NormalB (AppE (VarE ins_3) (VarE s_2))) [] Matching these back to the grammar in the Haskell Report (the docs for Language.Haskell.TH.Syntax should really include references) would presumably tell you something about how the expression parsed. Brandon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GADTs vs arrows/typeclasses
On Thursday 07 December 2006 09:44, S. Alexander Jacobson wrote: I guess I'm also not sure what belongs in a GADT and what belongs in a typeclass e.g. here is an Arrow GADT data Arrow b c where Arr::(b-c) - Arrow b c Compose::Arrow b c - Arrow c d - Arrow b d First::Arrow a b - Arrow (a,c) (b,c) When Arrow is defined like this, rather than write instances you just various evaluation functions for the Arrow GADT. How would the GADT solution handle the behaviours captured in the other Arrow classes, eg ArrowIf, ArrowLoop etc? It doesn't seem right to just add constructors for all those extra functions. Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Typeclass question
Stefan O'Rear wrote: [...] Unfortunately, it turns out that allowing foralls inside function arguments makes typechecking much harder, in general impossible. Just a tiny correction: AFAIK, it is type /inference/ which becomes undecidable in the presence of higher rank types -- checking works just fine (it could be true that it's harder, though). Cheers Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: GADTs vs arrows/typeclasses
Hi Alex, S. Alexander Jacobson wrote: I guess I'm also not sure what belongs in a GADT and what belongs in a typeclass e.g. here is an Arrow GADT data Arrow b c where Arr::(b-c) - Arrow b c Compose::Arrow b c - Arrow c d - Arrow b d First::Arrow a b - Arrow (a,c) (b,c) When Arrow is defined like this, rather than write instances you just various evaluation functions for the Arrow GADT. Indeed, there is a free choice (no pun) between this datatype and a class instance. The way I think about it, the datatype 'Arrow' above is the universal/free/(most general) instance of the class 'Arrow'. As you mention, specific instances of the class correspond to evaluation functions on this datatype. (In fact, this datatype presumably is the colimit of all instances of the 'Arrow' class, suitably interpreted as a functor.) In practice, you usually just want an instance; the universal datatype is only an extra layer of indirection. Sometimes however this datatype keeps useful extra information. I have used this approach once to allow algebraic manipulation of some kind of arrows: the GADT constructors make it possible to do pattern matching on the structure of the arrow. This is impossible if your arrow is some opaque function. Regards, Arie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: File locked unnecessarily
Vyacheslav Akhmechet wrote: Yes. I've run into similar issues with hs-plugins (albeit not the same). What platform are you running on? How are you compiling your code? Try compiling it with the -threaded flag and see if it fixes your problem. My platform is amd64 (x86_64). I usually compile with '--make -O2'. I just tried adding the '-threaded' flag, but that does not seem to change anything. Thanks for the suggestion though! When I get around to it, I'll check whether a minimal program that accesses a file from dynamically loaded code shows this locking problem. Greetings, Arie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GADTs vs arrows/typeclasses
Dear all, S. Alexander Jacobson wrote: I don't think I'm the only one confused here. Henrik Nilson in his paper on adding GADTs to Yampa comments that: ... In particular, GADTs are just what is needed to address the problem discussed above since the key idea is to allow constructors that have more specific types than usual, and to take that extra type information into account in individual case branches. GADTs would no doubt also offer an interesting alternative to the methods described by Baars and Swierstra [1] and Hughes [19]. [1] and [19] are papers about Arrows. I categorically deny being confused! :-) The comment refers to the methods Baars, Swierstra, and Hughes employ to encode type equality in order to be able to perform optimizations along similar lines as outlined in my paper. I was not at all proposing to use GADTs in place of arrows, and I cannot really see how the quote can be read as suggesting that. As Neil has already said: GADTs and arrows are just different kinds of entities. Best, /Henrik -- Henrik Nilsson School of Computer Science and Information Technology The University of Nottingham [EMAIL PROTECTED] This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] WANTED: grey line layout boxes in vim and emacs
I'd like some more help from the editors in getting 2d layout right without trying. Here's a mockup of vim with vertical grey bars delimiting layout: http://www.cse.unsw.edu.au/~dons/tmp/haskell+boxes.png Does anyone know how to get this effect in vim (or emacs)? Bonus points if the grey bars are draggable, changing the indenting. More bonus points for box-based navigation. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] WANTED: grey line layout boxes in vim and emacs
dons: I'd like some more help from the editors in getting 2d layout right without trying. Here's a mockup of vim with vertical grey bars delimiting layout: http://www.cse.unsw.edu.au/~dons/tmp/haskell+boxes.png Does anyone know how to get this effect in vim (or emacs)? Bonus points if the grey bars are draggable, changing the indenting. More bonus points for box-based navigation. mbishop on #haskell pointed out that Kate can do this: http://img172.imageshack.us/my.php?image=indentbu9.png -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] WANTED: grey line layout boxes in vim and emacs
On Thu, Dec 07, 2006 at 11:34:42AM +1100, Donald Bruce Stewart wrote: I'd like some more help from the editors in getting 2d layout right without trying. Here's a mockup of vim with vertical grey bars delimiting layout: http://www.cse.unsw.edu.au/~dons/tmp/haskell+boxes.png Does anyone know how to get this effect in vim (or emacs)? Bonus points if the grey bars are draggable, changing the indenting. More bonus points for box-based navigation. Having played with haskell parsers for various reasons, the layout rule is quite tricky due to the rules involving 'parse-error'. if we could come up with a formulation that didn't have those. it would make things a whole lot nicer. something like an unexpected 'in', 'of', ')' '}' ']' might do it. the lexer would have to keep track of matching brackets.. hmmm.. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] WANTED: grey line layout boxes in vim and emacs
On Wed, 2006-12-06 at 16:56 -0800, John Meacham wrote: Having played with haskell parsers for various reasons, the layout rule is quite tricky due to the rules involving 'parse-error'. if we could come up with a formulation that didn't have those. it would make things a whole lot nicer. something like an unexpected 'in', 'of', ')' '}' ']' might do it. the lexer would have to keep track of matching brackets.. hmmm.. Yes, not having the parser-lexer feedback would be great! And this proposal seems like it should work quite well. Somebody with a lot more spare time than me should code it up and see how much real code it breaks. Carl Witty ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] WANTED: grey line layout boxes in vim and emacs
On Wed, Dec 06, 2006 at 05:37:01PM -0800, Carl Witty wrote: On Wed, 2006-12-06 at 16:56 -0800, John Meacham wrote: Having played with haskell parsers for various reasons, the layout rule is quite tricky due to the rules involving 'parse-error'. if we could come up with a formulation that didn't have those. it would make things a whole lot nicer. something like an unexpected 'in', 'of', ')' '}' ']' might do it. the lexer would have to keep track of matching brackets.. hmmm.. Yes, not having the parser-lexer feedback would be great! And this proposal seems like it should work quite well. Somebody with a lot more spare time than me should code it up and see how much real code it breaks. there is the helium layout rule: http://www.cs.uu.nl/helium/docs/LayoutRule.html which is similar to what I am thinking of but only has a special case for 'in'. my general thought is to take the layout rule algorithm from the haskell report, and add some more possibiliies to the 'layout stack'. so, right now it is layout :: [Token] - [Int] - [Token] where the first argument is the token stream, the next argument is a stack of layout contexts, and the result is the new token stream. now we change it to something like (in semi-psuedo haskell) data LContext = LExpects Token | LLevel Int expectableTokens = ['of','in',')','}',']'] and change the signature to layout :: [Token] - [LContext] - [Token] layout = ... now, LLevel nodes will be pushed just like the old algorihm, but whenever a 'case' for instance is encountered, a LExpects 'of' node will be pushed. now, whenever we get something in expectableTokens, an 'of' say, either the top of the stack is a LExpects 'of', in which case we pop it add the 'of' to the output stream and continue, or it is a 'LLevel' in which case we insert a '}' then pop the LLevel and continue (with the 'of' still in the input stream) I think something like this could work. the only odd bits I can think of are handling 'let's without 'in's as occur in 'do' blocks, and the comma, but I think we can integrate them too. does something like this seem like it will work? John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] Defining Cg, HLSL style vectors in Haskell
Slavomir Kaslev slavomir.kaslev at gmail.com writes: On 11/29/06, Krasimir Angelov kr.angelov at gmail.com wrote: It is possible of course but your definition doesn't correspond to any operation in the usual vector algebra. By the way how do you define (*)? Isn't it 3D vector multiplication? (*) is per component multiplication, as it is in Cg/HLSL. For vector to vector, vector to matrix, etc. multiplication there is mul. Cheers. Hello, I have defined a class for vectors that I think can be interesting for you, althougt I do NOT use the Num class. I really like infix operators for vectors but using + * ... and so gets things confusing for me and have bad interaction with scalars. So I define infix operators + - * ... with an or on the side when a vector is spected, so (*) is a scalar multiplication of a vector, (*) multiplication of two vectors, . dot product The class is named Vector, and I don't make distinction bewteen vectors and points. A minimalist instance of Vector class, can be defined by only two method functions, reduceComponent and combineComponent. reduceComponent is like a fold functions over the components of a vector, so for example the max component of a vector is defined as maxComponent vec = reduceComponent (max) vec. combineComponent apply a function to every pair of components of two vectors, so an addition of two vectors is defined as (+) a b = combineComponent (+) a b. Note that for Vector3 and Vector2 datatypes I define instances with reduceComponent and combineComponent, but for performance reasons I override default implementations of the most used operations. Here is the code, I hope that it makes clear what I have tried to explain. Please, feel free to criticize the code Fco. Javier Loma fjloma at andaluciajunta.es --begin code {-# OPTIONS_GHC -fglasgow-exts -fbang-patterns #-} module Data.Vectors where -- Use a Double for each component type VReal = Double --data Dimension = X | Y | Z | W deriving (Show, Read, Eq) data Vector3 = V3 !VReal !VReal !VReal deriving (Show, Read, Eq) class (Floating r, Ord r) = (Vector r) v | v - r where -- minimun definition by reduceComponent and combineComponent reduceComponent :: (r - r - r) - v - r combineComponent :: (r - r - r) - v - v - v (+) :: v - v - v (+) a b = combineComponent (+) a b (-) :: v - v - v (-) a b = combineComponent (-) a b (*) :: v - v - v (*) a b = combineComponent (*) a b (/) :: v - v - v (/) a b = combineComponent (/) a b (.) :: v - v - r a . b = reduceComponent (+) (combineComponent (*) a b) (*) :: v - r - v a * k = combineComponent (\x - \_ - x*k) a a (/) :: v - r - v a / k = combineComponent (\x - \_ - x/k) a a (*) :: r - v - v k * vec = vec * k normalize :: v - v normalize vec = vec / (vlength vec) vlength :: v - r vlength vec = sqrt(vec . vec) maxComponent :: v - r maxComponent vec = reduceComponent (max) vec minComponent :: v - r minComponent vec = reduceComponent (min) vec middle :: v - v - v middle a b = (a + b) / 2 distance :: v - v - r distance a b = sqrt (distance2 a b) distance2 :: v - v - r distance2 a b = r . r where r = b - a instance Vector VReal Vector3 where reduceComponent f (V3 a1 a2 a3) = (f a1 (f a2 a3)) combineComponent f (V3 a1 a2 a3) (V3 b1 b2 b3) = V3 (f a1 b1) (f a2 b2) (f a3 b3) (!V3 a1 a2 a3) + (!V3 b1 b2 b3) = V3 (a1 + b1) (a2 + b2) (a3 + b3) (!V3 a1 a2 a3) - (!V3 b1 b2 b3) = V3 (a1 - b1) (a2 - b2) (a3 - b3) (!V3 a1 a2 a3) * (!V3 b1 b2 b3) = V3 (a1 * b1) (a2 * b2) (a3 * b3) (!V3 a1 a2 a3) / (!V3 b1 b2 b3) = V3 (a1 / b1) (a2 / b2) (a3 / b3) (!V3 a1 a2 a3) . (!V3 b1 b2 b3) = a1 * b1 + a2 * b2 + a3 * b3 (!V3 a1 a2 a3) * k = V3 (a1 * k) (a2 * k) (a3 * k) (!V3 a1 a2 a3) / k = V3 (a1 / k) (a2 / k) (a3 / k) data Vector2 = V2 !VReal !VReal deriving (Show, Read, Eq) instance Vector VReal Vector2 where combineComponent f (V2 a1 a2) (V2 b1 b2) = V2 (f a1 b1) (f a2 b2) reduceComponent f (V2 a1 a2) = (f a1 a2) (V2 a1 a2 ) . (V2 b1 b2 ) = a1 * b1 + a2 * b2 (V2 a1 a2 ) * k = V2 (a1 * k) (a2 * k) (V2 a1 a2 ) / k = V2 (a1 / k) (a2 / k) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe