[Haskell-cafe] Iteratee stack-consumption
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 I have written iteratees on the JVM, which does not include tail-call in its instruction set. They incur a stack frame per iteratee input, which can be expensive and unable to scale beyond a few thousand. Is there some trick to permitting this? Some sort of chunking the enumeratee or something? I was unable to find any good general hints in any of the hackage libraries. Thanks for any pointers. - -- Tony Morris http://tmorris.net/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk3jNHEACgkQmnpgrYe6r63QcACfSeZvvy+iYVisZ3e/dhWQd3D6 790AnRZCjJT6eCY21XlsVqcpTuamfuXY =ADo5 -END PGP SIGNATURE- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient object identity (aka symbols as data)
On 30 May 2011 05:27, Anupam Jain ajn...@gmail.com wrote: Why doesn't Haskell have built in syntactic sugar for atoms? Because they don't have a functional interpretation? (i.e. they're really a hack) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Erlang's module discussion
On 28/05/2011, at 3:37 PM, Brandon Allbery wrote: On Fri, May 27, 2011 at 23:10, Tom Murphy amin...@gmail.com wrote: I sure love Hackage, but there's a very interesting discussion going on, on the Erlang mailing list, about completely restructuring the module-model. Sounds like one of those ideas that looks really neat on paper but in the real world runs up against the fact that we're absolutely *abysmal* at managing that much metadata, and our programs to do so mostly reflect our inabilities. It's fair to say that nobody on the Erlang mailing list was terribly keen on the idea. People have testing and documentation and deployment strategies based on modules that they'd rather not give up. It seems fairly clear that it's not something you can add incrementally to a language: you'd need a massive new 'ecosystem for code', and the difficulties people have expressed here with finding things in Hackage would be doubled and redoubled to say the least of it. On the other hand, modules as we now know them look like very small objects in the light of the giant systems they are part of. (I had to download a new copy of Eclipse today. Good grief; to think people used to whinge about the size of *emacs*!) So maybe it's less of a jump than people think. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Please help with double recursion
On 28/05/2011, at 11:47 PM, Dmitri O.Kondratiev wrote: Hello, I am trying to solve a simple task, but got stuck with double recursion - for some reason not all list elements get processed. Please advice on a simple solution, using plane old recursion :) *** Task: From a sequence of chars build all possible chains where each chain consists of chars that can be accessed from one to another. For example, given the sequence: abcde In table below chars in a left column can access a list of chars in the right column: a | b c d e b | c d e c | d e d | e You have a set S of characters and a binary relation R ⊆ S × S and a chain is a sequence [x0,x1,...] such that x[0] ∈ S and for all i 0, x[i-1] R x[i] Can a chain be empty? What constraints on R do you have that lead you to think that each chain is finite, or are you expecting infinite chains as well? (S = {a}, R = {(a,a)} admits chains of any length, including ones that do not terminate.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How unique is Unique
2011-05-28 11:35, Heinrich Apfelmus skrev: Emil Axelsson wrote: Hello! Lacking a proper blog, I've written some notes about Data.Unique here: http://community.haskell.org/~emax/darcs/MoreUnique/ This describes a real problem that makes Data.Unique unsuitable for implementing observable sharing. The document also proposes a solution that uses time stamps to generate symbols that are more unique. Does anyone have any comments on the proposed solution? Are there any alternatives available? I don't know how Data.Unique is implemented. For observable sharing, I usually implement my own variant of Data.Unique with a global variable/counter. This is how Data.Unique is implemented too. Would your implementation pass the test I posted at the link above? Since every module of my DSL depends on the same global variable, only two things should happen: * Reloading a module does not reload the global counter. Everything is fine. * Reloading a module does reload the global counter. This forces *all* modules to be reloaded, which removes all expressions that have used the old variable from scope. But Simon Marlow just said that CAFs are reset upon reload. So the first situation should never occur(?). And as my example shows, resetting the counter does not force all dependent modules to get reloaded. However, note that the problem is not so much with Data.Unique; the real problem is that you can't say I want this to be unique, you have to say I want this to be unique within this or that *context*. Imagine that I give you two expressions with some Uniques inside, some of them equal, some of them not. How do you know that two equal Uniques denote the same subexpressions? For that, you have to know that I created them in the same context, in the same *environment*. Using Data.Unique assumes that the environment is one program run. It is clear that reloading modules in GHCi leads to different environments. OK, so I guess you could say that my solution makes the context explicit by associating it with a time stamp. Of course, this is just an approximation, because it's not impossible for two different contexts to get the same time stamp, especially in a parallel setting. However, it seems that this somewhat ugly trick might actually be what makes this approach to observable sharing work in practice. Concerning observable sharing, I very much like the approach from Andy Gill. Type safe observable sharing. http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf which uses StablePointers . Unfortunately, it forces Typeable contraints on polymorphic combinators. As far as I've heard, the semantics of stable pointers is not always well-defined either (but I could be wrong). But I should look into whether this technique could be used with the syntactic library. It would be nice to be able to gather several techniques under a common interface. / Emil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell School of Expression (graphics)
Henk-Jan van Tuyl commenting Andrew Coppin ... (about HOpenGL and H.Platform) ... Uh... yes, you might be right about that. However, AFAIK you still need something with which to create a rendering surface in the first place. (Not sure if HP includes GLUT...) As you can see in the HP documentation at http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/index.html , both OpenGL and GLUT are present. Or simply download and execute the examples before raising doubts... (the Haskell translation of the NeHe tutorials, etc.) No need for speculation. Now, I have a personal pedagogical comment. A few months ago I gave to some 30 students an assignment (a family of, with freely chosen variants). A long one, to complete in 2 months or more, and the subject was - the implementation, coding and running some nice 3D scenes with HOpenGL. I teach Haskell for years, usually the projects, which should be applied are devoted to some exercices in AI / games, compilation, text processing, graph manipulation, lazy numerics, etc., you know the song. This time I decided to propose something more visual. The results? A true DISASTER! They did something, all of them, and all their realisations were the nec plus ultra of mediocrity... Since my students were as clever and laborious as always, and I didn't drink much vodka during this process, I asked them what happened? The short standard assignments went smoothly as always... The answers (concentrated) were as follows: The OpenGL bindings in Haskell are hardly functional. You make us sweat with generic functional patterns, laziness, exquisite typing, non-determinism monad, parsing tools, etc., and then you throw us into this ugly imperativism ! Nobody liked your assignment, it was no pleasure for us, and our results are the consequence thereof. Where is Haskell?? Of course, we had to execute the typical syntactic gymnastics, but without understanding the functioning of all those variables, and other stuff relevant to the stateful OpenGL engine. Perhaps, if we had before a semester of OpenGL, and at least two months of a true course/tutorial (not your pseudo-tutorial on the Web...) we could be more productive. That's it... I don't want to generalize, but there is a huge work to do in this context. All the best. Jerzy Karczmarczuk Caen, France ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: quickcheck-properties
On 30 May 2011 00:14, Alexey Khudyakov alexey.sklad...@gmail.com wrote: It always puzzled me why there are no packages for for testing general type classes laws. (Monoid laws, monad laws etc). It looks like ideal case for quickcheck and smallcheck. How about 'checkers' by Conal Elliott: http://hackage.haskell.org/package/checkers Nice work by the way! Bas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: quickcheck-properties
On 30.05.2011 12:26, Bas van Dijk wrote: On 30 May 2011 00:14, Alexey Khudyakovalexey.sklad...@gmail.com wrote: It always puzzled me why there are no packages for for testing general type classes laws. (Monoid laws, monad laws etc). It looks like ideal case for quickcheck and smallcheck. How about 'checkers' by Conal Elliott: http://hackage.haskell.org/package/checkers We really need better search on hackage than C-f in browser. I didn't find them. Thank you for pointers. Nice work by the way! Bas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANN: dtd-types 0.0.0.1
The dtd-types package provides types for processing XML DTDs in Haskell. These types are intended to be compatible with and extend the set of types provided by John Millikin's xml-types package. This is a very preliminary first version, pending discussion by the community on the web-devel list about integration with xml-types, and any other issues that might come up. Hackage: http://hackage.haskell.org/package/dtd-types/ Darcs: http://code.haskell.org/dtd/dtd-types Enjoy, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: quickcheck-properties
Alexey Khudyakov schrieb: On 30.05.2011 12:26, Bas van Dijk wrote: How about 'checkers' by Conal Elliott: http://hackage.haskell.org/package/checkers We really need better search on hackage than C-f in browser. I didn't find them. Thank you for pointers. google with site:hackage.haskell.org option might help ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Please help with double recursion
On Mon, May 30, 2011 at 11:26 AM, Richard O'Keefe o...@cs.otago.ac.nz wrote: On 28/05/2011, at 11:47 PM, Dmitri O.Kondratiev wrote: Hello, I am trying to solve a simple task, but got stuck with double recursion - for some reason not all list elements get processed. Please advice on a simple solution, using plane old recursion :) *** Task: From a sequence of chars build all possible chains where each chain consists of chars that can be accessed from one to another. For example, given the sequence: abcde In table below chars in a left column can access a list of chars in the right column: a | b c d e b | c d e c | d e d | e You have a set S of characters and a binary relation R ⊆ S × S and a chain is a sequence [x0,x1,...] such that x[0] ∈ S and for all i 0, x[i-1] R x[i] Can a chain be empty? What constraints on R do you have that lead you to think that each chain is finite, or are you expecting infinite chains as well? (S = {a}, R = {(a,a)} admits chains of any length, including ones that do not terminate.) Sorry, I missed to specify that char sequences and chains are finite. Every chain is built from chars that can be accessed from one to another. Chars are examined proceeding from the beginning of the sequence to its end, and never in the opposite direction. Going always in one direction and being bound with sequence end, makes chains finite. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell School of Expression (graphics)
From: michael rice nowg...@yahoo.com I think this is fixed in the gtk2hs source tree, have you tried building from the repo? cabal install gtk2hs-buildtools darcs get --lazy http://code.haskell.org/gtk2hs/ cd gtk2hs chmod +x bootstrap.sh ./bootstrap.sh John Lato Is this worth chasing down? I loaded the Haskell Platform, which I assume has some graphics capability (Cairo?). Maybe my time would be better spent getting familiar with that? Michael --- On Sun, 5/29/11, Andrew Coppin andrewcop...@btinternet.com wrote: From: Andrew Coppin andrewcop...@btinternet.com Subject: Re: [Haskell-cafe] Haskell School of Expression (graphics) To: haskell-cafe@haskell.org Date: Sunday, May 29, 2011, 9:45 AM On 28/05/2011 08:06 PM, michael rice wrote: /tmp/glib-0.11.22906/glib-0.11.2/Gtk2HsSetup.hs:190:70: Couldn't match expected type `[PackageDB]' with actual type `PackageDB' Expected type: PackageDBStack Actual type: PackageDB In the sixth argument of `registerPackage', namely `packageDb' In the expression: registerPackage verbosity installedPkgInfo pkg lbi inplace packageDb cabal: Error: some packages failed to install: cairo-0.11.1 failed during the configure step. The exception was: ExitFailure 1 There's some sort of glitch with Gtk2hs (on which SOE depends) that causes it to not build with GHC 7.x (?) unless you hand-edit some of the files (!) http://hackage.haskell.org/trac/gtk2hs/ticket/1203 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] What's the advantage of writing Haskell this way?
Hi all, I'm trying to learn about enumerators by reading this paperhttps://john-millikin.com/downloads/enumerator_0.4.10.pdfand came across some code on page 2 that I found hard to digest, but I think I finally got it: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return x = Chunks [x] Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks [] mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF Cheers, -John ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Detecting overlay-ed signal patterns
Hello, I am trying to detect signal patterns in a system with numerous signals overlaying each other in time. I am aware that there is a whole class of problem solving methods for this task, yet trying my own algorithm, that may be wrong of course :) Next I use a simple example to describe the problem and my algorithm. Maybe someone will find this problem interesting enough to comment. Thanks in advance! In the following example signals from varying sources are represented by chars - unique signal = unique char. Examples of signal patterns (Pk) to detect: P1 = abcd P2 = 12345 Examples of a mixture of signals (pattern signals are underscored): M1 = s s n a_b_c_d_ r t 6 1_ 2_ 3_ 4_ 5_ 8 7 k l t M2 = g h a_ r 1_ w e 2_ j k b_ c_ l m p 3_ d_ 4_ e r 5_ v x M3 = ... MN = ... In the above examples two patterns P1 and P2 are interleaved with each other and other patterns. All mixtures are recorded for 24 hours for 12 month. One mixture corresponds to one 24 period (day). To find signal patterns in all these mixtures (M1, M2) my algorithm goes through these steps: 1) For every day: For every signal 'Y' create a list of 'weight pairs' such as: (Y, X1, 1), (Y, X2, 1), .. (Y, XN, 1) where X1, X2, ... XN are signals 'accessible from' (or following) signal 'Y' during this day So, for example, given the sequence: abcde, chars in a left column of a table can access a list of chars in the right column: a | b c d e b | c d e c | d e d | e 2) For every signal sum all its 'weight pairs' for all days of the year: W(Y) = Sum((Y, Xk, 1), j=1... 364) For the above example, M1+ M2 will double the value of weight pairs in patterns: P1 = abcd P2 = 12345 such as: (a,b,2) (a,c,2) (a,d,2) (b,c,2) (b,d,2) (b,e,2) (c,d,2) (c,e,2) (d,e,2) and also: (1,2,2) (1,3,2) (1,4,2), (1,5,2) (2,3,2) (2,4,2) (2,5,2) etc... On the other hand, after summation M1+M2, weight pairs for other char sequences, that do not form patterns of often repeated signals, will not increase much. To demonstrate: M_1 and M_2 are sequences with repeating patterns being removed: M_1 = s s n r t 6 8 7 k l t M_2 = g h r w e j k l m p e r v x Here most pair weights will be small, same as before addition: (s,s,2) (g,h,1), (w,e, 1) ... 3) Compute weight of all possible chains in this year. Each chain consists of chars that can be accessed from one to another. Chars are examined, proceeding from the beginning of the sequence to its end, and never in the opposite direction. Going always in one direction and being bound with sequence end, makes chains finite. Chains for 'abcde' example will be: abcde, acde, ade, ae, bcde, bde, be, cde, cd, ce, de Weight of the chain is computed as a sum of its pairs: W(Ci) = Sum(Pj, j=1,..R) where R is a number of pairs that this chain is built from. For example for chain a 'acde' the weight will be: W('acde') = W(a,c)+ W(a,d) + W(a,e) 4) Split chains in groups by its length 5) For each group select chains with maximum weight. With pattern P1 = 'abcd' spread over some signal mixture, my algorithm will find (I hope) the following 4 classes of chains with maximum weight: 1) abcde, acde, ade, ae, 2) bcde, bde, be, 3) cde, cd, ce, 4) de In the same way, chains for pattern P2 = 12345 should be found. Thus, grounding on the idea of 'signal precedence' found in repeating pattern of several signals, and using pair 'weights' to mark signal chains - patterns are detected. Summation of pair weights allows to stress out, or highlight the repeating patterns. Inserting other signals inside a 'pattern pair' does not obscure it because in a long run (after many summations) its weight will make such pair stand out of the crowd. I have not yet fully developed this algorithm and have not tested it on big enough training sets. I hope it will work on training sets exhibiting some regularities - which in this case means repeating patterns. Of course it will not work on randomly generated data, where all pairs have approximately the same weight. Working with pairs and chains will allow for natural parallelism in processing huge sequences of events, I hope. It would be nice to use some analog of Hadoop map-reduce for this task. Any experience with Haskell analog of Apache Hadoop cluster (http://hadoop.apache.org/mapreduce/)? Does such thing exist in Haskell world at all? I would be happy to get criticism of my algorithm and comments on 'route-cause analysis' algorithms in general, thanks! Dmitri ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: quickcheck-properties
On 30.05.2011 14:45, Henning Thielemann wrote: Alexey Khudyakov schrieb: On 30.05.2011 12:26, Bas van Dijk wrote: How about 'checkers' by Conal Elliott: http://hackage.haskell.org/package/checkers We really need better search on hackage than C-f in browser. I didn't find them. Thank you for pointers. google with site:hackage.haskell.org option might help It's do not offer much help. It finds too many pages for module descriptions packages get lost here. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell School of Expression (graphics)
and then cabal install soegtk? Michael --- On Mon, 5/30/11, John Lato jwl...@gmail.com wrote: From: John Lato jwl...@gmail.com Subject: Re: [Haskell-cafe] Haskell School of Expression (graphics) To: michael rice nowg...@yahoo.com Cc: haskell-cafe@haskell.org, Andrew Coppin andrewcop...@btinternet.com Date: Monday, May 30, 2011, 8:48 AM From: michael rice nowg...@yahoo.com I think this is fixed in the gtk2hs source tree, have you tried building from the repo? cabal install gtk2hs-buildtools darcs get --lazy http://code.haskell.org/gtk2hs/ cd gtk2hs chmod +x bootstrap.sh ./bootstrap.sh John Lato Is this worth chasing down? I loaded the Haskell Platform, which I assume has some graphics capability (Cairo?). Maybe my time would be better spent getting familiar with that? Michael --- On Sun, 5/29/11, Andrew Coppin andrewcop...@btinternet.com wrote: From: Andrew Coppin andrewcop...@btinternet.com Subject: Re: [Haskell-cafe] Haskell School of Expression (graphics) To: haskell-cafe@haskell.org Date: Sunday, May 29, 2011, 9:45 AM On 28/05/2011 08:06 PM, michael rice wrote: /tmp/glib-0.11.22906/glib-0.11.2/Gtk2HsSetup.hs:190:70: Couldn't match expected type `[PackageDB]' with actual type `PackageDB' Expected type: PackageDBStack Actual type: PackageDB In the sixth argument of `registerPackage', namely `packageDb' In the expression: registerPackage verbosity installedPkgInfo pkg lbi inplace packageDb cabal: Error: some packages failed to install: cairo-0.11.1 failed during the configure step. The exception was: ExitFailure 1 There's some sort of glitch with Gtk2hs (on which SOE depends) that causes it to not build with GHC 7.x (?) unless you hand-edit some of the files (!) http://hackage.haskell.org/trac/gtk2hs/ticket/1203 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How unique is Unique
Emil Axelsson wrote: Heinrich Apfelmus wrote: Since every module of my DSL depends on the same global variable, only two things should happen: * Reloading a module does not reload the global counter. Everything is fine. * Reloading a module does reload the global counter. This forces *all* modules to be reloaded, which removes all expressions that have used the old variable from scope. But Simon Marlow just said that CAFs are reset upon reload. So the first situation should never occur(?). And as my example shows, resetting the counter does not force all dependent modules to get reloaded. Something is really weird here. In your example, reloading M2 should not reset the counter, but it does. However, it's not true that all CAFs are reset. After all, this would mean that a would have been reset as well! (Of course, if the two requirements above were met, then it would work.) However, note that the problem is not so much with Data.Unique; the real problem is that you can't say I want this to be unique, you have to say I want this to be unique within this or that *context*. Imagine that I give you two expressions with some Uniques inside, some of them equal, some of them not. How do you know that two equal Uniques denote the same subexpressions? For that, you have to know that I created them in the same context, in the same *environment*. Using Data.Unique assumes that the environment is one program run. It is clear that reloading modules in GHCi leads to different environments. OK, so I guess you could say that my solution makes the context explicit by associating it with a time stamp. Of course, this is just an approximation, because it's not impossible for two different contexts to get the same time stamp, especially in a parallel setting. However, it seems that this somewhat ugly trick might actually be what makes this approach to observable sharing work in practice. Well, what I actually wanted to say is that your values are free-floating, they contain a lot of dangling pointers. There is a fundamental problem here which I think you're trying to paste over with judicious use of side effects. Observable sharing is just a funny way of augmenting your DSL with let bindings, the funny thing being that you can use the host-language let instead of an separate Let constructor. I recommend to think it terms of an explicit Let constructor, this will clear up a lot of confusion. For instance, your example can be written as a = Let (1 := a) `In` Var 1 b = Let (2 := b) `In` Var 2 (Now, the purpose of Data.Unique is just to supply fresh variable names.) What happens if b is defined as b = Let (1 := b) `In` Var 1 ? The expressions a and b are both Var 1 , but the variables refer to different environments (1 := a) and (1 := b). If you want to make a large expression from a and b , you have to unify the two environments. For instance, you can use scoping rules (= associated each variable with the height in the expression tree) or you can rename variables. Or you can use unsafePerformIO , which provides one single global environment, eliminating the need to unify environments in the first place. Unfortunately, global environments are unsafe. Concerning observable sharing, I very much like the approach from Andy Gill. Type safe observable sharing. http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf which uses StablePointers . Unfortunately, it forces Typeable contraints on polymorphic combinators. As far as I've heard, the semantics of stable pointers is not always well-defined either (but I could be wrong). But I should look into whether this technique could be used with the syntactic library. It would be nice to be able to gather several techniques under a common interface. Err, I meant Stable *Names*, not Stable Pointers, sorry. The worst thing that can happen is that you lose some sharing, but you can never accidentally introduce sharing. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] State Machine and the Abstractions
Yves Parès wrote: For the purposes of a simple strategy game, I'd like to build an EDSL that expresses missions. A mission could be represented as a state machine. With basic bricks such as actions (MoveTo, ShootAt...) or tests (EnemiesAround, LowHealth...), I could (ideally dynamically) build some strategic behaviors for the units. I will take the example of a patrol. Applied to a unit (or a group of units), it dictates : go from point 1 to point 2 and then go back and repeat. But when you detect an enemy near, leave the patrol path, destroy it and then resume your patrol where you left it. So if I consider my mission as a monad: data Mission = MoveTo Point | ShootAt Unit patrol = do MoveTo point1 MoveTo point2 patrol [...] So I need a way to say: A is your action of patrolling. B is your action of surveillance. Do both in parallel, but B is preponderant, as if it successes (if enemies are there) it takes over A. So, it is as if I was running two state machines in parallel. There are several methods to specify state machines, sequential composition of actions is just one of them. Let me elaborate. First and foremost, you can express every state machine as an automaton. For instance, your example above could be written as state1 -- (MoveTo point1, state2) state2 -- (MoveTo point2, state3) state3 -- ((), state1) An automaton is a set of states and transitions between them, and you should imagine that all your state machines work like this. Of course, while all state machines *work* like this, this does not mean that you have to *specify* them like this. For instance, writing down the states for a long sequence of actions like do moveTo point1 moveTo point2 shoot moveTo point3 ...etc. would be very cumbersome, you'd have to invent one dummy state for each action in the sequence. And this is where do-notation comes in: it's a way to specify long sequences of actions and have the interpreter automatically generate the intermediate dummy states! As you note, however, not all state machines are sequences of actions, far from it, actually. Sometimes, you want to write Flee -- MoveTo point0 Attack -- shoot `during` MoveTo point1 Well, nobody forces you to use do-notation in that case, right? In other words, I propose that you invent a small set of *state machine combinators* that allow you to freely mix do-notation (or something less powerful) with state transitions. Parallel composition corresponds to pairing states. (Chances are that you can express everything with do-notation by introducing threads and combinators like during or fork , but I don't know whether that's the best way to go about it. It's worth trying, but keep in mind that the goal is to have an expressive set of combinators, not to shoehorn everything into monads.) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: Clipboard-2.2.0. System clipboard interface.
Hi all, I've just uploaded Clipboard-2.2.0 to Hackage [1]. Clipboard [2] is a library that provides an interface for the system clipboard. The API is very simple, so anyone can use it without knowing of low-level Win32 API. Currently, this library only works on a Windows OS, due to its dependency on the Win32 library. Features for 2.2.0 version: * Added compatibility with the unicode character set, while reading the content of the clipboard. * Unicode character set is the new standard for setting the clipboard content. * Fixed the function 'modifyClipboardString'. * Some changes in documentation. I want to give thanks to Artyom Kazak, who sent me the patch of Unicode compatibilty and the fix for 'modifyClipboardString' function. -- References [1] - Hackage site - http://hackage.haskell.org [2] - Clipboard site - http://sites.google.com/site/dheltadiaz/packages/clipboard ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's the advantage of writing Haskell this way?
Because they are more general functions that work on all monads rather than just lists. This allows Stream to be defined more flexibly. On Mon, May 30, 2011 at 9:01 PM, John Ky newho...@gmail.com wrote: Hi all, I'm trying to learn about enumerators by reading this paper and came across some code on page 2 that I found hard to digest, but I think I finally got it: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return x = Chunks [x] Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks [] mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF Cheers, -John ___ 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] What's the advantage of writing Haskell this way?
From: John Ky newho...@gmail.com Sent: Monday, May 30, 2011 8:01 AM Hi all, I'm trying to learn about enumerators by reading this paper and came across some code on page 2 that I found hard to digest, but I think I finally got it: Hi John. These programs should behave identically, and I think your version should be preferred. This first code uses some class methods like mconcat, but it seems to always be used on the list in Chunks, so it will only ever use the definition for list, which is equivalent to what you wrote directly in the second code. The result may not be useful, but to understand this more thoroughly you might try parametrizating the definition of Stream so the use of more general operators actually means something. Perhaps data Stream m a = Chunks (m a) | EOF I think you would want Monad and MonadPlus on m. import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return x = Chunks [x] Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks [] mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF Cheers, -John ___ 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] What's the advantage of writing Haskell this way?
On Mon, May 30, 2011 at 9:01 AM, John Ky newho...@gmail.com wrote: instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: I don't care for the inconsistency in this example, using both mempty and (++). Your version is at least consistent, but I'd actually prefer to use mappend instead of (++) here, because it makes it clear that this isn't actually defining a new Monoid instance, just translating an existing instance for the constructor parameter to work for the surrounding data type. - C. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] GHCJS/Firefox support for forkIO and MVars
Firstly a big thanks to Neil Mix for this threading library... http://www.neilmix.com/2007/02/07/threading-in-javascript-17/ It is just what GHCJS needs for threading support (at least in Firefox). Here is what I did to get it working in GHCJS... * Added Jump so that tail calls don't grow the stack * Implemented a really basic scheduler * Added some thread and MVar primitives * Added a YieldTrampoline calling convention to GHCJS The code is here https://github.com/hamishmack/ghcjs cabal install cd examples runhaskell BuildTestYield.hs ../../ghc-7.0.2 Then open test-yield.html in Firefox. I think you can build it with any GHC 7 (I used 7.0.3), but you need the 7.0.2 source. I get this error when I try to use the 7.0.3 source... ../../ghc-7.0.3/libraries/base/GHC/Unicode.hs:35:0: error: HsBaseConfig.h: No such file or directory ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell sometimes sees hidden constructors
A quick follow-up: 1) I had a typo: it should say N4 is like N1 with a phantom type variable. 2) In my larger code base, the constructor that is visible to TH when I think it shouldn't be is part of a type that is alpha-equivalent to N3. It's odd that N3 doesn't exhibit the leakiness here but an alpha-equivalent type does exhibit it in my larger program. On Fri, May 27, 2011 at 12:04 PM, Nicolas Frisby nicolas.fri...@gmail.com wrote: With the three modules at the end of this email, I get some interesting results. Note that none of the constructors are exported, yet Template Haskell can see (and splice in variable occurrences of!) T, C2, W1, and W4. If you load Dump into GHCi, you get to see the Info that TH provides when you reify each of the data types. For T, T2, N1, and N4, their construct is visible in the Info even though M doesn't export it. As a consequence, you can load Unhide with no errors. Thus c = C, c2 = C2, w1 = N1, and w4 = N4, even though those constructors were not supposed to be imported. I couldn't find any mention of this on the GHC Trac for Template Haskell or for a general search of reify. * http://j.mp/l9Ztjz (Description contains reify) * http://j.mp/mprUmq (Component = Template Haskell) * Disclaimer: I didn't take the time to inspect this one http://hackage.haskell.org/trac/ghc/ticket/4946 T is isomorphic to (), T2 is like T with a phantom type argument, N1 is a newtype wrapping an Int, and N4 is like N3 with a phantom type variable. This seems too inconsistent to be an intended behavior. Am I missing something? Thanks. == M.hs == module M (T(), T1(), T2(), T3(), T4(), N1(), N3(), N4()) where data T = C data T1 = C1 Int data T2 a = C2 data T3 a = C3 a data T4 a = C4 Int newtype N1 = W1 Int newtype N3 a = W3 a newtype N4 a = W4 Int == Dump.hs == {-# LANGUAGE TemplateHaskell #-} module Dump where import Language.Haskell.TH import M dumpT, dumpT1, dumpT2, dumpT3, dumpT4, dumpN1, dumpN3, dumpN4 :: () dumpT = $(reify ''T = fail . show) dumpT1 = $(reify ''T1 = fail . show) dumpT2 = $(reify ''T2 = fail . show) dumpT3 = $(reify ''T3 = fail . show) dumpT4 = $(reify ''T4 = fail . show) dumpN1 = $(reify ''N1 = fail . show) dumpN3 = $(reify ''N3 = fail . show) dumpN4 = $(reify ''N4 = fail . show) == Unhide.hs == {-# LANGUAGE TemplateHaskell #-} module Unhide where import Language.Haskell.TH import M c :: T c = $((\(TyConI (DataD _ _ _ [NormalC n _] _)) - ConE n) `fmap` reify ''T) c2 :: T2 a c2 = $((\(TyConI (DataD _ _ _ [NormalC n _] _)) - ConE n) `fmap` reify ''T2) w1 :: Int - N1 w1 = $((\(TyConI (NewtypeD _ _ _ (NormalC n _) _)) - ConE n) `fmap` reify ''N1) w4 :: Int - N4 a w4 = $((\(TyConI (NewtypeD _ _ _ (NormalC n _) _)) - ConE n) `fmap` reify ''N4) - for convenience, this is what I get when I load Dump in ghci Dump.hs:9:11: TyConI (DataD [] M.T [] [NormalC M.C []] []) In the expression: $(reify 'T = fail . show) In an equation for `dumpT': dumpT = $(reify 'T = fail . show) Dump.hs:10:12: TyConI (DataD [] M.T1 [] [] []) In the expression: $(reify 'T1 = fail . show) In an equation for `dumpT1': dumpT1 = $(reify 'T1 = fail . show) Dump.hs:11:12: TyConI (DataD [] M.T2 [PlainTV a_1627390697] [NormalC M.C2 []] []) In the expression: $(reify 'T2 = fail . show) In an equation for `dumpT2': dumpT2 = $(reify 'T2 = fail . show) Dump.hs:12:12: TyConI (DataD [] M.T3 [PlainTV a_1627390696] [] []) In the expression: $(reify 'T3 = fail . show) In an equation for `dumpT3': dumpT3 = $(reify 'T3 = fail . show) Dump.hs:13:12: TyConI (DataD [] M.T4 [PlainTV a_1627390695] [] []) In the expression: $(reify 'T4 = fail . show) In an equation for `dumpT4': dumpT4 = $(reify 'T4 = fail . show) Dump.hs:14:12: TyConI (NewtypeD [] M.N1 [] (NormalC M.W1 [(NotStrict,ConT GHC.Types.Int)]) []) In the expression: $(reify 'N1 = fail . show) In an equation for `dumpN1': dumpN1 = $(reify 'N1 = fail . show) Dump.hs:15:12: TyConI (DataD [] M.N3 [PlainTV a_1627390694] [] []) In the expression: $(reify 'N3 = fail . show) In an equation for `dumpN3': dumpN3 = $(reify 'N3 = fail . show) Dump.hs:16:12: TyConI (NewtypeD [] M.N4 [PlainTV a_1627390693] (NormalC M.W4 [(NotStrict,ConT GHC.Types.Int)]) []) In the expression: $(reify 'N4 = fail . show) In an equation for `dumpN4': dumpN4 = $(reify 'N4 = fail . show) Failed, modules loaded: M. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] something between a QQ and Q Exp?
This message motivates adding support to Template Haskell for code that can be spliced but can no longer be intensionally analyzed. I'm trying to use the well-known technique of a hidden constructor in order to represent values that satisfy a particular predicate. module Safe (Safe(), safe, mkSafe) where newtype Safe a = Hidden a -- the Hidden constructor is not exported safe :: Safe a - a-- the safe observer is exported In my case, the predicate is a restriction on the Haskell syntax used to define the value. In fact, in order to check my predicate, I need some of the information that TH embeds in the result of a [| ... |] quote. Thus I'm using TH to validate the construction of Safe values. isSafe :: Exp - Bool isSafe = ... -- uses TH metadata embedded in the Exp mkSafe :: Q Exp - Q Exp mkSafe m = do e - m if isSafe e then return (AppE (ConE 'Hidden) e) else fail (not safe:\n\t ++ pprint e) A user's construction of a Safe value then looks like $(mkSafe [| ... |]) in some other module. I'd like this to be the only way to build a Safe value. Unfortunately, TH is a double-edged sword. In particular, it can be used to expose the Hidden constructor, thereby invalidating the Safe type encapsulation of my invariant. abuse (AppE con _) = con uhoh :: a - Safe a uhoh = $(liftM abuse (safe [| ... |])) On the one hand, I need the user to use TH in order to construct Safe values. On the other, abuse of TH is capable of breaking my security kernel all together. If I could get by with a QuasiQuoter such as [mkSafe| ... |], the Hidden constructor would indeed be safe since the result of mkSafe is spliced in immediately and the user has no further access to it. Unfortunately, QuasiQuoters don't have access to the metadata that TH embeds in its quotations, which I need for validation. This inspires my idea for a solution: something between the two mechanisms. My first thought for a solution involved a new core type for Template Haskell. The Splice type would be completely abstract except for constructing it from a splicable type and the ability to splice a Splice into a program. So, TH could splice in either Q alpha like normal or Q (Splice alpha), for alpha an element of {Exp, Pat, Type, [Dec]}. mkSafe could be rewritten to generate a Splice instead of just an Exp, and hence an abusive user could no longer snoop the generated expression to extract the Hidden constructor. Unfortunately, if Splice is just another newtype with a hidden constructor, then it could be subverted in the same way that the abuse function exposes the Hidden constructor. Without further support from the Template Haskell system itself, it's turtles all the way down, I suspect. The popularity and convenience of creating a safety kernel by hiding constructors lends importance to plugging this hole, I think. Template Haskell is a useful system, but it currently subverts the most common lightweight approach to enforcing data invariants in the Haskell type system. It'd be nice if both could be used in the same system -- especially since the user can invoke Template Haskell regardless of the library author's intent. Is there already a way to write a security kernel that is robust against this sort of Template Haskell abuse? Or would we need further support from the Template Haskell system? Thanks for your time. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Code critique - Was [Maybe Int] sans Nothings
Hi Michael, You've used quite a few entirely redundant brackets. The tool HLint ( http://community.haskell.org/~ndm/hlint) will tell you which ones. Thanks, Neil On Wed, May 25, 2011 at 12:09 AM, michael rice nowg...@yahoo.com wrote: The input file: http://dl.dropbox.com/u/27842656/psalms The Markov chain exercise from The Practice of Programming, Kermighan/Pike. Sample runs at the end. Michael import System.Environment(getArgs) import System.Random import Control.Applicative import Control.Monad.Reader import Control.Monad.State import Data.Maybe import Data.Map type Prefix = (String,String) type GeneratorState1 = State ((Map Prefix [String]),Prefix,[String]) type GeneratorState2 = StateT (Prefix,StdGen) (Reader (Map Prefix [String])) non_word = \n f key new old = new ++ old buildMap :: GeneratorState1 (Map Prefix [String]) buildMap = do (mp,(pfx1,pfx2),words) - get if (Prelude.null words) then {- No more words. Return final map (adding non_word for final prefix). -} return (insertWithKey' f (pfx1,pfx2) [non_word] mp) else do {- Add word to map at prefix continue. -} put (insertWithKey' f (pfx1,pfx2) [head words] mp, (pfx2,(head words)), tail words) buildMap generate :: GeneratorState2 (Maybe String) generate = do ((pfx1,pfx2),gen) - get mp - ask let suffixList = mp ! (pfx1,pfx2) let (index,newGen) = randomR (0, (length suffixList)-1) gen let word = suffixList !! index if (word == non_word) then return Nothing else do put ((pfx2,word),newGen) return (Just word) rInt :: String - Int rInt = read main = do (seed:nwords:_) - (Prelude.map rInt) $ getArgs contents - getContents putStrLn $ unwords $ catMaybes $ runReader (evalStateT (sequence $ replicate nwords generate) ((non_word,non_word),mkStdGen seed)) (evalState buildMap (singleton (non_word,non_word) [], (non_word,non_word), words contents)) {- [michael@hostname ~]$ ghc --make markov.hs [1 of 1] Compiling Main ( markov.hs, markov.o ) Linking markov ... [michael@hostname ~]$ cat psalms | ./markov 111 100 Blessed is the LORD, in thine own cause: remember how the foolish people have blasphemed thy name. In the courts of the righteous: The LORD taketh pleasure in the desert. And he led them with the wicked, and with the whole earth, is mount Zion, on the sides of thine only. O God, and was troubled: I complained, and my God. My times are in thy praise. Blessed be God, which is full of the LORD is good: for his wondrous works. Now also when I am small and despised: yet do I put my trust: how say ye to [michael@hostname ~]$ cat psalms | ./markov 666 100 Blessed is the LORD, and cried unto thee, Thy face, LORD, will I remember thee from the beginning: and every one that is weaned of his heart to any wicked transgressors. Selah. They return at evening: they make ready their arrow upon the people; and thou hast destroyed all them that fight against them that trust in thee: and let my tongue cleave to the heavens by his power for ever; and thy lovingkindnesses; for they have laid a snare before them: and that my ways were directed to keep thy word. Mine eyes fail while I have said that [michael@hostname ~]$ --- On *Tue, 5/24/11, Alexander Solla alex.so...@gmail.com* wrote: From: Alexander Solla alex.so...@gmail.com Subject: Re: [Haskell-cafe] [Maybe Int] sans Nothings To: Haskell Cafe haskell-cafe@haskell.org Date: Tuesday, May 24, 2011, 5:01 PM Personally, I find non-functional values without Eq instances to be degenerate. So I really do not mind superfluous Eq constraints. I would not hesitate to use filter ((/=) Nothing) in a function whose type has no free type variables. It's just a bit of plumbing inside of a more complex function. Sometimes it seems to be better to not allow Eq on Float and Double. Since most algebraic laws do not hold for those types, it is more often an error than an intention to compare two Float values. And how to compare (IO a) values? Floats, Doubles, and IO are all degenerate types, for the reasons you outline. (Admittedly, Float and Double have Eq instances, but invalid Eq semantics) Notice how their value semantics each depend on the machine your runtime runs on, as opposed to merely the runtime. Bottom is another one of these degenerate types, since comparisons on arbitrary values are undecidable. Also, by thinking about function types, you often get interesting use cases. Thus I would not assume too quickly that a type will always be instantiated by types other than a function type. Thus I would stick to (filter isJust) and use this
Re: [Haskell-cafe] Code critique - Was [Maybe Int] sans Nothings
Nice tool. I'll be using it a lot from now on, I'm sure. Thanks, Neil. Michael --- On Mon, 5/30/11, Neil Mitchell ndmitch...@gmail.com wrote: From: Neil Mitchell ndmitch...@gmail.com Subject: Re: [Haskell-cafe] Code critique - Was [Maybe Int] sans Nothings To: michael rice nowg...@yahoo.com Cc: Haskell Cafe haskell-cafe@haskell.org, Alexander Solla alex.so...@gmail.com Date: Monday, May 30, 2011, 1:55 PM Hi Michael, You've used quite a few entirely redundant brackets. The tool HLint (http://community.haskell.org/~ndm/hlint) will tell you which ones. Thanks, Neil On Wed, May 25, 2011 at 12:09 AM, michael rice nowg...@yahoo.com wrote: The input file: http://dl.dropbox.com/u/27842656/psalms The Markov chain exercise from The Practice of Programming, Kermighan/Pike. Sample runs at the end. Michael import System.Environment(getArgs)import System.Randomimport Control.Applicativeimport Control.Monad.Reader import Control.Monad.Stateimport Data.Maybeimport Data.Map type Prefix = (String,String)type GeneratorState1 = State ((Map Prefix [String]),Prefix,[String]) type GeneratorState2 = StateT (Prefix,StdGen) (Reader (Map Prefix [String])) non_word = \n f key new old = new ++ old buildMap :: GeneratorState1 (Map Prefix [String]) buildMap = do (mp,(pfx1,pfx2),words) - get if (Prelude.null words) then {- No more words. Return final map (adding non_word for final prefix). -} return (insertWithKey' f (pfx1,pfx2) [non_word] mp) else do {- Add word to map at prefix continue. -} put (insertWithKey' f (pfx1,pfx2) [head words] mp, (pfx2,(head words)), tail words) buildMap generate :: GeneratorState2 (Maybe String) generate = do ((pfx1,pfx2),gen) - get mp - ask let suffixList = mp ! (pfx1,pfx2) let (index,newGen) = randomR (0, (length suffixList)-1) gen let word = suffixList !! index if (word == non_word) then return Nothing else do put ((pfx2,word),newGen) return (Just word) rInt :: String - IntrInt = read main = do (seed:nwords:_) - (Prelude.map rInt) $ getArgs contents - getContents putStrLn $ unwords $ catMaybes $ runReader (evalStateT (sequence $ replicate nwords generate) ((non_word,non_word),mkStdGen seed)) (evalState buildMap (singleton (non_word,non_word) [], (non_word,non_word), words contents)) {-[michael@hostname ~]$ ghc --make markov.hs[1 of 1] Compiling Main ( markov.hs, markov.o )Linking markov ...[michael@hostname ~]$ cat psalms | ./markov 111 100 Blessed is the LORD, in thine own cause: remember how the foolish people have blasphemed thy name. In the courts of the righteous: The LORD taketh pleasure in the desert. And he led them with the wicked, and with the whole earth, is mount Zion, on the sides of thine only. O God, and was troubled: I complained, and my God. My times are in thy praise. Blessed be God, which is full of the LORD is good: for his wondrous works. Now also when I am small and despised: yet do I put my trust: how say ye to[michael@hostname ~]$ cat psalms | ./markov 666 100 Blessed is the LORD, and cried unto thee, Thy face, LORD, will I remember thee from the beginning: and every one that is weaned of his heart to any wicked transgressors. Selah. They return at evening: they make ready their arrow upon the people; and thou hast destroyed all them that fight against them that trust in thee: and let my tongue cleave to the heavens by his power for ever; and thy lovingkindnesses; for they have laid a snare before them: and that my ways were directed to keep thy word. Mine eyes fail while I have said that [michael@hostname ~]$ --- On Tue, 5/24/11, Alexander Solla alex.so...@gmail.com wrote: From: Alexander Solla alex.so...@gmail.com Subject: Re: [Haskell-cafe] [Maybe Int] sans Nothings To: Haskell Cafe haskell-cafe@haskell.org Date: Tuesday, May 24, 2011, 5:01 PM Personally, I find non-functional values without Eq instances to be degenerate. So I really do not mind superfluous Eq constraints. I would not hesitate to use filter ((/=) Nothing) in a function whose type has no free type variables. It's just a bit of plumbing inside of a more complex function. Sometimes it seems to be better to not allow Eq on Float and Double. Since most algebraic laws do not hold for those types, it is more often an error than an intention to compare two Float values. And how to compare (IO a) values? Floats, Doubles, and IO are all degenerate types, for the reasons you outline. (Admittedly, Float and Double have Eq instances, but invalid Eq semantics) Notice how their value semantics each depend on the machine your runtime runs on, as opposed to merely the runtime. Bottom is another one
[Haskell-cafe] Can't figure out cmap in hmatrix
Hello, I'm playing around a bit with the hmatrix package (http://hackage.haskell.org/package/hmatrix) but can't quite figure out how to make the cmap function in Numeric.Container work. An example: ghci import Numeric.LinearAlgebra ghci let v = fromList [1.0,2.0,3.0] ghci v fromList [1.0,2.0,3.0] :: Data.Vector.Storable.Vector ghci :t v v :: Vector Double ghci cmap sqrt v interactive:1:1: No instance for (Container Vector e0) arising from a use of `cmap' Possible fix: add an instance declaration for (Container Vector e0) In the expression: cmap sqrt v In an equation for `it': it = cmap sqrt v ghci :t cmap cmap :: (Container c e, Element b, Element a) = (a - b) - c a - c b There is an instance for (Container Vector Double) but I assume that since the signature of cmap doesn't mention the type variable 'e' GHCi can't infer it. Googling hasn't helped me so far, except for digging up another post to this list with the same (?) problem, but no answer: http://www.haskell.org/pipermail/haskell-cafe/2011-April/091390.html Is there a way to tell GHC what instance to use, or how should cmap be used? Thanks! Mats ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] uniplate (was: code review?)
Hi John, While I'm on the topic, I recently wrote a tool that wanted to traverse deep data structures as produced by haskell-src-exts. ?I wound up with about 50 lines of case expressions and around the time my hands were literally beginning to hurt decided that enough was enough and I should try a generic approach. ?I heard uniplate was pretty easy to use, and was pretty pleased to turn the entire thing into a single line. ?It took me a little longer to figure out I needed to use universeBi since all the examples were monotyped, but once I did it Just Worked. ?Amazing. ?So thanks again! ?And maybe you could mention universeBi in the instant introduction? Yes, I probably should - I'll try and get to that. Of course, I'd also happily accept a patch against http://community.haskell.org/~ndm/darcs/uniplate I use Uniplate inside HLint, and it's invaluable - there are a lot of times when List Comp + universeBi really hits the spot. Does Uniplate include an instance for: instance Uniplate a = Biplate [a] a No, it only includes: instance Biplate [Char] Char where biplate (x:xs) = plate (:) |* x ||* xs biplate x = plate x I am slightly curious why I didn't include the more general a instead of Char version, but perhaps it doesn't quite work - polymorphic versions of the Direct instances can have problems if you pick weird types. I'll have a think, and if it does always work, I'll include it. Note that if you use the Typeable or Data versions this instance is automatically available. In practice I almost always end up using the Data versions of Uniplate, they require no instance definitions are are good to get started with - you can switch to Direct only if you need the additional performance. Thanks, Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Can't figure out cmap in hmatrix
this is actually a bug in the type of cmap, a fix is due in the next release (at least thats what Alberto indicated to me when I asked about this a monthish ago) (note how you have the container type c e, but we want c a and c b ). Instead use the vector map or matrix map ops directly cheers -Carter schonwald On Mon, May 30, 2011 at 3:27 PM, Mats Klingberg maklingb...@gmail.comwrote: Hello, I'm playing around a bit with the hmatrix package ( http://hackage.haskell.org/package/hmatrix) but can't quite figure out how to make the cmap function in Numeric.Container work. An example: ghci import Numeric.LinearAlgebra ghci let v = fromList [1.0,2.0,3.0] ghci v fromList [1.0,2.0,3.0] :: Data.Vector.Storable.Vector ghci :t v v :: Vector Double ghci cmap sqrt v interactive:1:1: No instance for (Container Vector e0) arising from a use of `cmap' Possible fix: add an instance declaration for (Container Vector e0) In the expression: cmap sqrt v In an equation for `it': it = cmap sqrt v ghci :t cmap cmap :: (Container c e, Element b, Element a) = (a - b) - c a - c b There is an instance for (Container Vector Double) but I assume that since the signature of cmap doesn't mention the type variable 'e' GHCi can't infer it. Googling hasn't helped me so far, except for digging up another post to this list with the same (?) problem, but no answer: http://www.haskell.org/pipermail/haskell-cafe/2011-April/091390.html Is there a way to tell GHC what instance to use, or how should cmap be used? Thanks! Mats ___ 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] uniplate (was: code review?)
Hi Neil, thanks for the response. On Mon, May 30, 2011 at 8:48 PM, Neil Mitchell ndmitch...@gmail.com wrote: Hi John, While I'm on the topic, I recently wrote a tool that wanted to traverse deep data structures as produced by haskell-src-exts. ?I wound up with about 50 lines of case expressions and around the time my hands were literally beginning to hurt decided that enough was enough and I should try a generic approach. ?I heard uniplate was pretty easy to use, and was pretty pleased to turn the entire thing into a single line. ?It took me a little longer to figure out I needed to use universeBi since all the examples were monotyped, but once I did it Just Worked. ?Amazing. ?So thanks again! ?And maybe you could mention universeBi in the instant introduction? Yes, I probably should - I'll try and get to that. Of course, I'd also happily accept a patch against http://community.haskell.org/~ndm/darcs/uniplate I use Uniplate inside HLint, and it's invaluable - there are a lot of times when List Comp + universeBi really hits the spot. Does Uniplate include an instance for: instance Uniplate a = Biplate [a] a No, it only includes: instance Biplate [Char] Char where biplate (x:xs) = plate (:) |* x ||* xs biplate x = plate x I am slightly curious why I didn't include the more general a instead of Char version, but perhaps it doesn't quite work - polymorphic versions of the Direct instances can have problems if you pick weird types. I'll have a think, and if it does always work, I'll include it. Note that if you use the Typeable or Data versions this instance is automatically available. In practice I almost always end up using the Data versions of Uniplate, they require no instance definitions are are good to get started with - you can switch to Direct only if you need the additional performance. I started with Data, but writing the Direct instance was so simple that I didn't see a reason not to do it. My type doesn't have many constructors yet though, and several of them aren't recursive, so maybe it was easier than normal. John ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's the advantage of writing Haskell this way?
Hi Brandon, Thanks for your suggestion. I'm a little stuck as adding Monad and MonadPlus in my instance declaration doesn't seem sufficient. I know mconcat comes from Monoid, but I don't know how to put that in. data Stream m a = Chunks (m a) | EOF deriving (Show, Eq) instance (Monad m, MonadPlus m) = Monoid (Stream m a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys) mappend _ _ = EOF instance (Monad m, MonadPlus m) = Monad (Stream m) where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF Iteratee.hs:28:25: No instance for (Monoid (m a)) arising from a use of `mempty' Possible fix: add an instance declaration for (Monoid (m a)) In the first argument of `Chunks', namely `mempty' In the expression: Chunks mempty In an equation for `mempty': mempty = Chunks mempty Iteratee.hs:29:54: No instance for (Monoid (m a)) arising from a use of `mappend' Possible fix: add an instance declaration for (Monoid (m a)) In the first argument of `Chunks', namely `(xs `mappend` ys)' In the expression: Chunks (xs `mappend` ys) In an equation for `mappend': mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys) Iteratee.hs:34:43: Could not deduce (m ~ []) from the context (Monad m, MonadPlus m) bound by the instance declaration at Iteratee.hs:32:10-51 `m' is a rigid type variable bound by the instance declaration at Iteratee.hs:32:17 Expected type: [a] Actual type: m a In the second argument of `fmap', namely `xs' In the first argument of `mconcat', namely `(fmap f xs)' In the expression: mconcat (fmap f xs) Failed, modules loaded: none. Cheers, -John On 31 May 2011 00:38, Brandon Moore brandon_m_mo...@yahoo.com wrote: From: John Ky newho...@gmail.com Sent: Monday, May 30, 2011 8:01 AM Hi all, I'm trying to learn about enumerators by reading this paper and came across some code on page 2 that I found hard to digest, but I think I finally got it: Hi John. These programs should behave identically, and I think your version should be preferred. This first code uses some class methods like mconcat, but it seems to always be used on the list in Chunks, so it will only ever use the definition for list, which is equivalent to what you wrote directly in the second code. The result may not be useful, but to understand this more thoroughly you might try parametrizating the definition of Stream so the use of more general operators actually means something. Perhaps data Stream m a = Chunks (m a) | EOF I think you would want Monad and MonadPlus on m. import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return x = Chunks [x] Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks [] mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF Cheers, -John ___ 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] Please add a method for optimized concat to the Semigroup class
I felt I should probably mention that ultimately what was done is I moved NonEmpty all the way down into semigroups and chose sconcat :: NonEmpty a - a at it was the closest analogue to the current mconcat behavior. So, request accomodated. ;) -Edward On Tue, May 3, 2011 at 7:23 PM, Edward Kmett ekm...@gmail.com wrote: Another option (upon reflection) would be to just transplant the NonEmpty type from http://hackage.haskell.org/packages/archive/streams/0.6.1.1/doc/html/Data-Stream-NonEmpty.html data NonEmpty a = a :| [a] http://hackage.haskell.org/packages/archive/streams/0.6.1.1/doc/html/Data-Stream-NonEmpty.htmlinto the semigroups package, which would give you the 'canonical non empty list' you seem to want. and then add the more pleasing and natural generalization sconcat:: NonEmpty a - a to the Semigroup class All I would need is to strip out the use of PatternGuards in a couple of locations. I would have to sprinkle a lot of instances through other packages on the way up the package tree NonEmpty isn't the most natural inductive version (Data.Stream.Future has that distinction), but it does implement efficiently and it can cheaply interconvert to [a]. -Edward On Tue, May 3, 2011 at 6:49 PM, Edward Kmett ekm...@gmail.com wrote: On Tue, May 3, 2011 at 3:43 PM, Yitzchak Gale g...@sefer.org wrote: Edward Kmett wrote: sconcat :: [a] - a - a with either the semantics you supplied or something like sconcat = appEndo . mconcat . map diff The sconcat we have been discussing is sconcat = flip $ appEndo . getDual . mconcat . map (Dual . Endo . flip ()) Holger's basically had this form, but I think Tetley's version is more useful, because it provides for the scenario you describe below where there is no value of the semigroup's type that you can merge with. But it was somewhat unsatisfying, in part because of the need for a seed element. Only because, as you said, there is no standard non-empty list type. I have a streams package which provides a number of non-empty list types, but it is fairly high up my module hierarchy, as it requires a number of compiler extensions, and other classes, and so isn't available to the class down here in the semigroups package. Another unsatisfying detail is no definition is in any way shape or form canonical when folding over a list. While our definition doesn't look any better than the others when expressed in terms of those combinators, it certainly seems to be the most natural when defined directly as Holger did. It's also the direct analogue of mconcat when viewed as the same type with lists replaced by non-empty lists. I'm sure that's the definition most users will expect. But I would be happy with whichever you supply. ...I'm more than happy to add it if only for symmetry with Data.Monoid, but I'd be much happier doing so with a compelling example where it actually sped things up I'm currently doing some recognition algorithms on heterogeneous collections of graphical elements on a 2D canvas. Many types of elements have a location and a rectangular extent. You can often combine them, but there is no unit element because even an empty element needs to have a specific location. It would be very slow to combine a list of them incrementally; instead, you find the minimum and maximum X and Y coordinates, and combine the content using a fast algorithm. This is a pretty good example. Even if in this case it is mostly saving you the boxing and unboxing of the intermediate rectangles You still probably want something closer to Stephen Tetley's version, otherwise you're going to have to magic up just that kind of empty rectangle that you don't want to give though! In fact you probably want something even stronger, that way you can signal the empty list result 'out of band' of the values you can fit in the Semigroup. This would avoid specifying an alternative directly, and his case can be derived with sconcat :: Semigroup a = [a] - Maybe a sconcat [] = Nothing sconcat (a:as) = Just (go a as) where go a (b:bs) = gs (ab) bs go a [] = a and effectively avoids fiddling with the empty case throughout the list. Then Stephen's version would look like tetley :: Semigroup a = a - [a] - a tetley alt = maybe alt id . sconcat Alternately Option could be used instead of Maybe to keep the package's API more self-contained, but I don't particularly care one way or the other. (I originally used Monoid instances by augmenting types with locationless empty elements. But that made a mess of my code and introduced a myriad of bugs and potential crashes. These are definitely semigroups, not monoids.) I'm sure there are countless other natural examples of semigroups in the wild, and that the typical non-trivial ones will benefit from an optimized sconcat. Sold! (modulo the semantic considerations above) -Edward
Re: [Haskell-cafe] What's the advantage of writing Haskell this way?
sorry, `m a` as an instance of Monoid, not `m' On Tue, May 31, 2011 at 9:30 AM, Canhua dreamerat...@gmail.com wrote: I think you should declare `m' as an instance of Monoid, rather than as instnaces of Monad and MonadPlus On Tue, May 31, 2011 at 8:33 AM, John Ky newho...@gmail.com wrote: Hi Brandon, Thanks for your suggestion. I'm a little stuck as adding Monad and MonadPlus in my instance declaration doesn't seem sufficient. I know mconcat comes from Monoid, but I don't know how to put that in. data Stream m a = Chunks (m a) | EOF deriving (Show, Eq) instance (Monad m, MonadPlus m) = Monoid (Stream m a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys) mappend _ _ = EOF instance (Monad m, MonadPlus m) = Monad (Stream m) where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF Iteratee.hs:28:25: No instance for (Monoid (m a)) arising from a use of `mempty' Possible fix: add an instance declaration for (Monoid (m a)) In the first argument of `Chunks', namely `mempty' In the expression: Chunks mempty In an equation for `mempty': mempty = Chunks mempty Iteratee.hs:29:54: No instance for (Monoid (m a)) arising from a use of `mappend' Possible fix: add an instance declaration for (Monoid (m a)) In the first argument of `Chunks', namely `(xs `mappend` ys)' In the expression: Chunks (xs `mappend` ys) In an equation for `mappend': mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys) Iteratee.hs:34:43: Could not deduce (m ~ []) from the context (Monad m, MonadPlus m) bound by the instance declaration at Iteratee.hs:32:10-51 `m' is a rigid type variable bound by the instance declaration at Iteratee.hs:32:17 Expected type: [a] Actual type: m a In the second argument of `fmap', namely `xs' In the first argument of `mconcat', namely `(fmap f xs)' In the expression: mconcat (fmap f xs) Failed, modules loaded: none. Cheers, -John On 31 May 2011 00:38, Brandon Moore brandon_m_mo...@yahoo.com wrote: From: John Ky newho...@gmail.com Sent: Monday, May 30, 2011 8:01 AM Hi all, I'm trying to learn about enumerators by reading this paper and came across some code on page 2 that I found hard to digest, but I think I finally got it: Hi John. These programs should behave identically, and I think your version should be preferred. This first code uses some class methods like mconcat, but it seems to always be used on the list in Chunks, so it will only ever use the definition for list, which is equivalent to what you wrote directly in the second code. The result may not be useful, but to understand this more thoroughly you might try parametrizating the definition of Stream so the use of more general operators actually means something. Perhaps data Stream m a = Chunks (m a) | EOF I think you would want Monad and MonadPlus on m. import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return = Chunks . return Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF I guess, it shows my lack of experience in Haskell, but my question is, why is writing the code this way preferred over say writing it like this: import Data.Monoid data Stream a = Chunks [a] | EOF deriving (Show, Eq) instance Monad Stream where return x = Chunks [x] Chunks xs = f = mconcat (fmap f xs) EOF = _ = EOF instance Monoid (Stream a) where mempty = Chunks [] mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys) mappend _ _ = EOF Cheers, -John ___ 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
[Haskell-cafe] ANNOUNCE: time-recurrence-0.4.2
I've been busy making major changes to my time library: http://hackage.haskell.org/package/time-recurrence Things are still under heavy development. This release is to show the direction the library is heading in. A major shift in the design has been made, and the current work is an attempt at simplifying the recurring time manipulations into the smallest number of function possible, then providing some useful convenience methods on top of that. Version 0.4.2 definitely feels more Haskell-y. Here is a simple example of how things are done: date = parse822Time Tue, 02 Sep 1997 09:00:00 -0500 take 5 $ repeatSchedule' dailyUTC{interval = toInterval 10, moment = date} [1997-09-02 14:00:00 UTC ,1997-09-12 14:00:00 UTC ,1997-09-22 14:00:00 UTC ,1997-10-02 14:00:00 UTC ,1997-10-12 14:00:00 UTC] In addition a test suite has been added to the package, it currently is using HUnit test-framework, and the Cabal 1.10 stdio test suite facility. Feedback, suggestions and pull requests are always welcome. -Chris ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] maybe a GHC bug but not sure
When building the Haskell Objective C bindings tool from http://code.google.com/p/hoc Using GHC 7.0.3 for Haskell Platform 2011.2.0.1, OS X 64 bit HOC compiles HOC_cbits.o before trying to build it into the rest of the program (I don't say link because this came up while trying to compile: [18 of 31] Compiling HOC.StdArgumentTypes ( HOC/HOC/StdArgumentTypes.hs, dist/build/HOC/StdArgumentTypes.o ) [loading packages, like you'd see from ghci...] Loading object (static) dist/build/HOC_cbits.o ... ghc: dist/build/HOC_cbits.o: Bad magic. Expected: feedfacf, got: feedface. GHC says the impossible happened and tells me to report it as a GHC bug, but based on the odd behavior I think the HOC build script might be doing something odd. I just don't have any idea where to start looking. For instance, why the heck is it looking at the magic bits for an object file while compiling a source file? Any insight appreciated. -- Edward Amsden Student Computer Science Rochester Institute of Technology www.edwardamsden.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Looking for n-body example with repa.
Hello! I'm studying repa package and trying to implement O(N^2) n-body code. I'm using Array DIM2 Double to represent the collection of particles. I've managed to write a function which calculates the energy of one particle in the field of others but I'm struggling to write a code to calculate the energy of the whole system. Maybe someone here has already written such code? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Student Internships for Parallel Haskell Programming at NII, Tokyo
As part of my research fellowship at the National Institute of Informatics in Tokyo, I announce the availability of student internships for up to three months between July and September 2011. Qualified applicants are enrolled in a Masters or Phd program, have a firm grasp of the Haskell programming language, and, ideally, know the different approaches to parallel and concurrent programming available in the Glorious Glasgow Haskell Compilation System (GHC). Their task is to support research on combinators for parallel programming by developing and comparing efficient implementations. The available fund covers sojourn costs but no travel expenses. It is meant to foster collaboration between Germany and Japan but qualified students from other countries may also be funded. If you want to spend the summer hacking Haskell in Tokyo please do not hesitate to contact me off list. Feel free to write even if you are unsure whether you are qualified or have any other questions regarding the internship. Best regards, Sebastian http://research.nii.ac.jp/members/fischer/ P.S. Information about the status after the earthquake is available on the Local Information page of ICFP'11: http://www.biglab.org/icfp11local/index.html Additionally, you may want to follow recent news in English by Mainichi Daily News and NHK World: http://mdn.mainichi.jp/ http://www3.nhk.or.jp/daily/english/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Erlang's module discussion
On 5/28/11 10:11 AM, Alex Rozenshteyn wrote: Since no-one has yet mentioned it, and I think it might be relevant, http://types.bu.edu/seminar-modularity/first-class-modules-for-haskell.pdf I haven't read it with any degree of understanding, but I don't think it's tractable to remove modules from haskell, nor desirable. Aww... I read that paper and got really excited thinking, Wow! I didn't realize that people were working on that; I wonder when I'll get to play with it!, and then I saw the paper was written for a seminar that took place in 2002, so I guess the idea just didn't pan out... Would anyone involved in the matter want be so kind as to fill me in on how that particular story ended (i.e., why everyone gave up it)? Thanks! Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's the advantage of writing Haskell this way?
instance (Monad m, MonadPlus m) = Monoid (Stream m a) where mempty = Chunks mempty mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys) mappend _ _ = EOF Iteratee.hs:28:25: No instance for (Monoid (m a)) arising from a use of `mempty' There is a clue in the first part of the error message. Add the required instance as part of the predicate: instance (Monad m, MonadPlus m, Monoid (m a)) = Monoid (Stream m a) where ... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe