Re: [Haskell-cafe] What is Haskell unsuitable for?
I would expand your definition of monadic to: able to syntactically transformed so as to be put in a sequence where an operation can be altered by the results of the operations preceeding it. IMO your definition matches more applicative. 2010/6/18 Alexander Solla a...@2piix.com On Jun 17, 2010, at 9:44 PM, Michael Snoyman wrote: While we're on the topic, does anyone else get funny looks when they say monads? Yes, almost every time. They seem to catch on if I say monadic when I mean able to syntactically transformed so as to be put in a sequence. ___ 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] Mapping a list of functions
??? What does exactly swing do ? 2010/6/18 Bulat Ziganshin bulat.zigans...@gmail.com Hello Martin, Thursday, June 17, 2010, 11:02:31 PM, you wrote: But what if I want to apply a list of functions to a single argument. I can one more answer is swing map: http://www.haskell.org/haskellwiki/Pointfree#Swing -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ 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] [reactive] A pong and integrate
The GHC bugs are now fixed, so it might be stable enough for another adventure like that, but I don't think I would bet on it again. GHC bugs are corrected, but Reactive still have some. (See my previous posts) IMO Haskell is great for writing small clean prototypes, doing interesting research, and maybe making some fun little games, but I wouldn't use it for production reactive game coding, not yet at least. Tim Sweeney (from Epic Games) has another perspective about that [1]. Besides, FRP is not mandatory. You can always make games in Haskell by using a more regular style (more imperative, would some say). For now, the main problem is the small number of Haskell libraries for games when compared to the huge numbers of those which exist in C++, which prevents, for now, Haskell to be used as the main language for big commercial games. But for smaller scale games (like indie), which have less needs, I think it's worth it. [1] http://www.scribd.com/doc/5687/The-Next-Mainstream-Programming-Language-A-Game-Developers-Perspective-by-Tim-Sweeney 2010/5/25 Peter Verswyvelen bugf...@gmail.com Well, first of all, I did not make these PS3 visualization, my former colleagues and I just made the editor, language and runtime that allowed video game artists to do the job for us in a couple of weeks time :-) I wouldn't use Yampa, for performance reasons, and difficulty to get it running on alien platforms (it is well known it performs relatively badly, although the work done by Paul Liu and co on Causal Commutative Arrows looks very promising, but does not support dynamic switching yet). After all, Yampa models a synchronous dataflow language, and compilers for these languages are relatively easy to make IMO. My previous - now defunct - company Anygma spent a lot of money on trying to use Haskell and Reactive for game programming, which unfortunately ended in some nasty GHC bugs popping up (see http://www.haskell.org/haskellwiki/Unamb), and not all problems with Reactive got fixed; it is amazing how difficult this all turned out to be. The GHC bugs are now fixed, so it might be stable enough for another adventure like that, but I don't think I would bet on it again. IMO Haskell is great for writing small clean prototypes, doing interesting research, and maybe making some fun little games, but I wouldn't use it for production reactive game coding, not yet at least. On Tue, May 25, 2010 at 10:49 AM, Limestraël limestr...@gmail.com wrote: Wow... impressive... And now, with your experience, if you'd have to do this again, would you use Yampa or stick up with C#/C++ ? 2010/5/24 Peter Verswyvelen bugf...@gmail.com Yeah. Funny that we're still writing games in C++, while mission critical and hard real time systems are written in much nicer languages :) I made something similar to Lucid Synchrone for a game company I used to work, but with the purpose of making reactive programming accessible to computer artists. The integrated development environment provided the typical boxes-and-links user interface, where the boxes were signal functions. Signals itself were not exposed, like Yampa. The system did type inference so artists never really had to deal with types. Special nodes like feedback and delay where provided to allow transferring values to the next frame. This actually was a great success, digital artists could literally create little interactive applications with it, without much help from programmers. This resulted in a Playstation 3 visual experience Mesmerize (http://www.youtube.com/watch?v=rW7qGhBjwhY). This was before I knew Haskell or functional programming, so it was hacked together in C# and C++... I still believe that the reason why computers artists could work with this environment and were not able to learn imperative programming is functional programming itself: the system had all the goodies of FP: type inference, referential transparancy, etc... But is also provided the possibility to edit literals while the simulation was running, providing zero turnaround times, which was equally important for quick adoption of the software. So IMO Haskell and FRP systems have a huge potential for education of a much broader audience than just computer scientists... On Mon, May 24, 2010 at 6:13 PM, Limestraël limestr...@gmail.com wrote: I assumed also that it was a field which was still under research, however, Lustre, again, is used for critical control software in aircraft, helicopters, and nuclear power plants, according to wikipedia. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [reactive] A pong and integrate
Wow... impressive... And now, with your experience, if you'd have to do this again, would you use Yampa or stick up with C#/C++ ? 2010/5/24 Peter Verswyvelen bugf...@gmail.com Yeah. Funny that we're still writing games in C++, while mission critical and hard real time systems are written in much nicer languages :) I made something similar to Lucid Synchrone for a game company I used to work, but with the purpose of making reactive programming accessible to computer artists. The integrated development environment provided the typical boxes-and-links user interface, where the boxes were signal functions. Signals itself were not exposed, like Yampa. The system did type inference so artists never really had to deal with types. Special nodes like feedback and delay where provided to allow transferring values to the next frame. This actually was a great success, digital artists could literally create little interactive applications with it, without much help from programmers. This resulted in a Playstation 3 visual experience Mesmerize (http://www.youtube.com/watch?v=rW7qGhBjwhY). This was before I knew Haskell or functional programming, so it was hacked together in C# and C++... I still believe that the reason why computers artists could work with this environment and were not able to learn imperative programming is functional programming itself: the system had all the goodies of FP: type inference, referential transparancy, etc... But is also provided the possibility to edit literals while the simulation was running, providing zero turnaround times, which was equally important for quick adoption of the software. So IMO Haskell and FRP systems have a huge potential for education of a much broader audience than just computer scientists... On Mon, May 24, 2010 at 6:13 PM, Limestraël limestr...@gmail.com wrote: I assumed also that it was a field which was still under research, however, Lustre, again, is used for critical control software in aircraft, helicopters, and nuclear power plants, according to wikipedia. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [reactive] A pong and integrate
One problem with Elerea experimental branch besides the update time control: the memo function. I can't understand when I have to call it and when I don't. Just to know, have you been told of a language dedicated to reactive programming (even experimental)? I mean, not an embedded language just like Yampa is. 2010/5/24 Patai Gergely patai_gerg...@fastmail.fm IMO: For AAA game programming? Definitely not. For exploring new ways of doing game programming and having a lot of fun and frustration? Sure! For making casual games? I don't know. Why not casual games? I don't see any immediate difficulty. Do you have any particular bad experience? Limestraël: I find Elerea fine so far, but it is still experimental and more limited than Yampa. Well, it's more expressive in one way and more limited in another. Elerea lifts some limitations of Yampa by extending it with the ArrowApply/Monad interface, and you can certainly reimplement all the crazy switching combinators using the basic building blocks provided by the library. However, you cannot stop a signal in Elerea, while that's trivial in Yampa. I believe Elerea needs two more basic combinators: a simple 'untilB'-like switcher (mainly to be able to tell when a signal ends) and a freezing modifier that allows you to control the updates of a signal (or more like a whole subnetwork). The semantics of the latter is not clear to me yet (I don't intend to introduce a full-fledged clock calculus #224; la Lucid Synchrone if it's possible to avoid), and I want to work it out properly before implementing anything. Gergely -- http://www.fastmail.fm - Choose from over 50 domains or use your own ___ 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] [reactive] A pong and integrate
But you have to be aware that Elerea, Yampa, Lucid Synchrone and Lustre are all very similar in their foundations. Okay. I just thought that reactive programming was a quite new field of research, but I saw that Lustre and Esterel date back to 1980... I assumed also that it was a field which was still under research, however, Lustre, again, is used for critical control software in aircraft, helicopters, and nuclear power plants, according to wikipedia. 2010/5/24 Patai Gergely patai_gerg...@fastmail.fm One problem with Elerea experimental branch besides the update time control: the memo function. I can't understand when I have to call it and when I don't. Technically, you never have to. However, if you have a signal derived from others by pure application (i.e. fmap or *), keep in mind that its output will be recalculated as many times as you request it. The memo element can be used as a proxy to prevent that. E.g. if you have z = liftA2 f x y, and you request z n times, f will also be called n times. But if you have z - memo (liftA2 f x y) instead, then the calculation will only happen once. If Elerea wasn't an EDSL, these memo elements could be inserted automatically, but now I have no means to tell how many times a certain signal is referred to, so the burden is on the programmer. The old version doesn't have this inconvenience, because it memoises all the applicative nodes too. Since most of them are only referred to once, this is adds a lot of unnecessary overhead. Just to know, have you been told of a language dedicated to reactive programming (even experimental)? I mean, not an embedded language just like Yampa is. Those that Peter mentioned are good examples, and there is also Lustre. But you have to be aware that Elerea, Yampa, Lucid Synchrone and Lustre are all very similar in their foundations. Gergely -- http://www.fastmail.fm - The professional email service ___ 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] Re: Haskell and scripting
As some people were advising me to peek in Lua, I did so. Well, I find it far too laxist and bug prone : weak-typing, variables which are global by default, non-existing variables which contain nil when we access them instead of failing... I mean, I like Haskell especially because it is rigorous and because the type-system continually saves the day: Lua is the total opposite. I don't hope to enjoy Haskell's tightness with a scripting language, but being interpreted and dynamically typed doesn't prevent to be somewhat painstaking (Python is, for instance)**. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [reactive] A pong and integrate
Elerea finds middle ground between the two, and unlike Yampa, it's examples would still work I guess. Yes that's the big problem of Yampa: all of the examples are very old, and some even don't work anymore. It's the same for the papers/tutorials (they're all 6 years old or more), and it would be less of a problem if the functions were documented! (Check hackage, you'll see...) I find Elerea fine so far, but it is still experimental and more limited than Yampa. 2010/5/24 Peter Verswyvelen bugf...@gmail.com What papers did you read? When I read most of the Yampa papers, most of the design patterns became obvious for AFRP (arrow-based FRP) style of programming. That doesn't mean I could apply the design patterns immediately; I understood them but writing a game in it was difficult since I also was too used to the imperative approach. Note that in AFRP the design patterns are actually functions and combinators itself (dpSwitch and the like), and no fuzzy descriptions like in imperative programming. Regarding user interfaces, FRUIT (also AFRP based) is also nice IMO. But above systems suffer from scalability and performance (and the annoying fact that a random number generator is not embedded in the framework) , although for simple games, I don't think this would be an issue. Newer work like Reactive is much more faithful to functional programming (no arrow syntax needed), but since no pong game was never made with it yet, I would classify this as ongoing research. Elerea finds middle ground between the two, and unlike Yampa, it's examples would still work I guess. On Mon, May 24, 2010 at 12:51 AM, Ben Christy ben.chri...@gmail.com wrote: Assuming Haskell is ready has any work gone into creating design patterns or the like. One of the biggest problems is ALL of the literature regarding game programming is written in an imperative style. My goal for learning Haskell is to make a hobby game written in a Functional language but I am at a loss how to go about it. I an imperative language I would set up a central entity management system and then have subsystems register with it and either transform the entities such as AI or user interface or do something with them IE graphics. This paradigm just will not work as far as I can imagine in Haskell. On Sun, May 23, 2010 at 6:30 PM, Jake McArthur jake.mcart...@gmail.com wrote: On 05/23/2010 02:17 PM, Peter Verswyvelen wrote: IMO: For AAA game programming? Definitely not. Why not? I suppose it may depend on your definition of AAA, since there doesn't seem to be any consensus on it. I have seen it mean various combinations of the following, but rarely, if ever, all of them: * Big development budget * Big marketing budget * High quality * Large number of sales and/or high revenue * High hardware requirements * Released by one of a small group of accepted AAA publishers While I think it's very unlikely that the last one will happen any time soon, I don't see any reason that Haskell and/or FRP (or as I now prefer to call my research in the area, Denotative Continuous-Time Programming, or DCTP) inherently can't be a major part of the development of a game that fits any of the definitions in the list. I suppose DCTP is not itself *ready* for somebody to risk a business investment on it, although it may be in the future, but Haskell as a whole would not be all that risky, in my opinion. - Jake ___ 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 mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Retrospective type-class extension
Then it would be: class Functor f where fmap :: (a - b) - f a - f b class (Functor f) = Pointed f where pure :: a - f a class (Pointed f) = Applicative f where (*) :: f (a - b) - f a - f b class (Applicative f) = Monad f where join :: f (f a) - f a This would be a great idea, for the sake of logic, first (a monad which is not a functor doesn't make sense), and also to eliminate redudancy (fmap = liftM, ap = (*), etc.) 2010/5/20 Tony Morris tonymor...@gmail.com Ivan Miljenovic wrote: On 20 May 2010 14:42, Tony Morris tonymor...@gmail.com wrote: We all know that class (Functor f) = Monad f is preferable but its absence is a historical mistake. We've all probably tried once: instance (Functor f) = Monad f where Do you mean the reverse of this (instance (Monad m) = Functor m where) ? Yes. -- Tony Morris http://tmorris.net/ ___ 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] [reactive] A pong and integrate
I heard complaints about this two-layered solution with SignalMonad/SignalGen, so I'm glad you like it. :) Doesn't SignalGen replace SignalMonad in the experimental branch ? They aren't meant to be used together, are they? By the way, I strongly recommend using the Experimental branch instead of the current one Yes, I just looked at FRP.Elerea.Experimental.Simple. I have one question: in the stable branch, 'superstep' takes an amount of time. In the experimental branch, it and 'createSignal' are replaced by 'start', if I'm right. So you do: main = do updater - start gen forever (join $ updater) But there is no notion of time, here. So how do I make sure the network is updated with the right amount of time? 2010/5/17 Patai Gergely patai_gerg...@fastmail.fm I looked at elerea. I found it simple and nice! I heard complaints about this two-layered solution with SignalMonad/SignalGen, so I'm glad you like it. :) I just regret the fact that the SignalMonad can only be run inside IO. That's life. ;) However, there is only a single point where you have to do the conversion, and you can think of everything as a pure abstraction within that top-level SignalGen. By the way, I strongly recommend using the Experimental branch instead of the current one, because sampler (the 'almost join') breaks referential transparency and generally behaves badly if you have more than two Signal layers to break down, which can easily happen in practice. Also, the new stuff is much more efficient. With reactive, you can transform signals in pure code. Sure, but you'll need IO anyway if you want to hook up the signals to peripherals. Both libraries allow you to describe the combinations of reactive values in a pure way, but they inevitably have to face the RealWorld at some point... Yes, as no optimization is done? But as long as you compile the code, you don't have such a problem? No, it's not a matter of optimisation, it's an intrinsic problem. Optimisation just makes it less obvious. I don't know how bad it is in practice though, because the more entities are created, the more often garbage collection should kick in, so it might not hinder scaling as much as one would think. You can also look at the bounce example in the elerea-examples package if you want a minimal test case for dynamic collections. Does reactive work elsewise? Yes. If you don't need a reactive value in Reactive, it is not evaluated. This means that unreferenced values just sit in memory until they are swept up by the garbage collector, as you would expect. This policy has a different unpleasant consequence though: if a stateful reactive value (e.g. our favourite integral) is only requested long after its start time -- which is always the start time of the whole program in the case of Reactive --, all its past has to be kept in memory, and the first evaluation will potentially take a lot of time while the computation is catching up. So it will cause a different kind of space-time leak than Elerea. Grapefruit has an interesting solution to this problem that uses phantom types to keep track of the observers of a signal. Elerea just forces every live signal to be updated to prevent big thunks from building up. I know that every FRP framework will have its own hiccups, as it is a domain which is still in development, but still, I found the time-leak bug (if it is a bug) in reactive very weird. I still haven't managed to find out whether it's just an implementation issue or somehow the consequence of the basic design of the library. Hopefully the former. The run-time behaviour of Reactive is quite complex, so it's difficult to pinpoint the source of the problem. Gergely -- http://www.fastmail.fm - Choose from over 50 domains or use your own ___ 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] [reactive] A pong and integrate
Time has to be an external signal? I saw dow uses the Simple experimental branch, and I don't see how you synchronize elerea with GLFW (what is done by driveNetwork in the Chase and Breakout examples which use the main branch). 2010/5/18 Patai Gergely patai_gerg...@fastmail.fm Doesn't SignalGen replace SignalMonad in the experimental branch ? They aren't meant to be used together, are they? Absolutely, they are incompatible, and play the same role in the respective versions. But there is no notion of time, here. So how do I make sure the network is updated with the right amount of time? Time is just an external parameter. You can use the Param version if you don't want to supply it as an external signal but pass it to the superstep. Since the system doesn't rely on this type in any way (it's basically a globally accessible value for the whole network), you are free to choose whatever structure you want, not just a single Double value like in the old version. Gergely -- http://www.fastmail.fm - mmm... Fastmail... ___ 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] [reactive] A pong and integrate
The game speed is determined by the amount of sleep per frame. I that the saw sleep time at each loop is fixed (0.02). So game speed will depend on processor speed, since with a more powerful CPU frames will be computed quicklier? So we don't have (with the Simple branch) some way to say I want my sprite to move 100 pixels *per second* on the left, except if we provide ourselves a time signal? 2010/5/18 Patai Gergely patai_gerg...@fastmail.fm Time has to be an external signal? With the Simple version, yes. With the Param (and Delayed) versions it's pretty much like the old one, where you have to pass something (delta time being one possibility) as an additional parameter, and all stateful and transfer nodes will see it. I saw dow uses the Simple experimental branch, and I don't see how you synchronize elerea with GLFW (what is done by driveNetwork in the Chase and Breakout examples which use the main branch). DoW doesn't use any notion of time for the game logic, so there's no need to synchronise. The game speed is determined by the amount of sleep per frame. Gergely -- http://www.fastmail.fm - Access all of your messages and folders wherever you are ___ 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] [reactive] A pong and integrate
I looked at elerea. I found it simple and nice! I just regret the fact that the SignalMonad can only be run inside IO. With reactive, you can transform signals in pure code. I suggest unpacking the source of dow and executing it in ghci, the problem will be obvious as you play at length. Yes, as no optimization is done? But as long as you compile the code, you don't have such a problem? Unfortunately, Elerea doesn't really work well as an EDSL, however much I'd like it to. Its main issue is that unreferenced entities keep using CPU time until they are garbage collected -- this comes from the necessity to keep them referentially transparent Does reactive work elsewise? I know that every FRP framework will have its own hiccups, as it is a domain which is still in development, but still, I found the time-leak bug (if it is a bug) in reactive very weird. 2010/5/17 Patai Gergely patai_gerg...@fastmail.fm I did not look thoroughly at elerea, but at least, when I tried its sample dungeons of wor it worked properly ;) Elerea has its own 'beauty' though. I suggest unpacking the source of dow and executing it in ghci, the problem will be obvious as you play at length. Unfortunately, Elerea doesn't really work well as an EDSL, however much I'd like it to. Its main issue is that unreferenced entities keep using CPU time until they are garbage collected -- this comes from the necessity to keep them referentially transparent, i.e. behaving the same way regardless of how they are observed --, and currently I don't see any way to solve that without implementing a dedicated runtime for dynamic stream processing. So there, no FRP library without a catch for you. ;) Gergely -- http://www.fastmail.fm - A fast, anti-spam email service. ___ 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] [reactive] A pong and integrate
Eventually, I don't think it is a profiling issue. Maybe a problem with integral. According to a quite recent post on the reactive mailing list, the following minimal code produces the same problem : import FRP.Reactive import FRP.Reactive.LegacyAdapters import Control.Applicative type Velocity = Double type Position = Double data Car = Car { vel :: Velocity, pos :: Position } deriving Show velocity :: Behavior Velocity velocity = 1 position :: Behavior Position position = integral (atTimes [0, 0.5 ..]) velocity car :: Behavior Car car = Car $ velocity * position main :: IO () main = adaptE $ print $ car `snapshot_` atTimes [0, 0.5..] 1) why is the leak happen? 2) how can I fix this problem? Some more detailed informations: * reactive 0.11.4 * GHC 6.12.1 * Gentoo Linux (2.6.32-tuxonice, x86_64) or Ubuntu 9.10 64bits * compiled with or without -O2 flag 2010/5/16 David Leimbach leim...@gmail.com On Sat, May 15, 2010 at 8:42 AM, Limestraël limestr...@gmail.com wrote: Okay, guess I'll have to bring out the chapter 25 of my Real World Haskell... I find it's often the most practical chapter that I hit a lot during writes and changes to my server process I have in Haskell in our control system code :-) That plus the information that I had missed that Control.Monad.State defaulted to the Lazy version (which is consistent, but for some reason it got by me) helped me to realize why I was leaking so much space in a garbage collected environment. I wouldn't have gotten very far with Haskell as this piece of our code without that chapter. I'd love to see more writing of that sort around Haskell in book form. One can become fluent in tuning Haskell by trial and error, but the sharp corners one must bump into are often sharper than in other languages I've found. Dave 2010/5/15 Bulat Ziganshin bulat.zigans...@gmail.com Hello Limestraėl, Saturday, May 15, 2010, 7:02:38 PM, you wrote: But when I set my beat to tick every 60 times per second, the position is well updated, but I clearly see that the display dramatically slows down after a few seconds of execution. Too heavy rate for integrate? it may be due to lot of uncollected garbage that is result of lazy evaluation. profile program to check its GC times -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ 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] [reactive] A pong and integrate
Why isn't it possible to make a Pong with Reactive? Where is the problem? Conceptually, I don't see where it is. IMO, it's a time-leak issue due to a Reactive bug, but it is not a limitation of Reactive. I mean, it's not that it *can't* work, it's that it *should* work, shouldn't it? And why would it be more possible with Yampa? I've already checked Yampa, but I find it much less simple and easy to use than Reactive. Moreover, I tried the space invaders sample (the sample that the paper Yampa Arcade is about), and it lauches but it is completely unusable (I do have a decent PC, and I get like 5fps and a gun which absolutely doesn't move correctly). Not very appealing ^^, but maybe the problem is with the code of the game itself or with my PC, not with Yampa... I did not look thoroughly at elerea, but at least, when I tried its sample dungeons of wor it worked properly ;) I will have a look... 2010/5/16 Peter Verswyvelen bugf...@gmail.com As far as I know, it was never possible to make a pong game in Reactive, at least not with the versions I tried, but I admit a lot of never versions got released since then. It would be great to see one though :) You might want to try Yampa, that works for sure (although you should mark all your output data strict, as is done in the examples, otherwise you might also get space leaks or shaky frame rates). Or Elerea, which comes with a breakout game. On Sun, May 16, 2010 at 9:30 PM, Limestraël limestr...@gmail.com wrote: Eventually, I don't think it is a profiling issue. Maybe a problem with integral. According to a quite recent post on the reactive mailing list, the following minimal code produces the same problem : import FRP.Reactive import FRP.Reactive.LegacyAdapters import Control.Applicative type Velocity = Double type Position = Double data Car = Car { vel :: Velocity, pos :: Position } deriving Show velocity :: Behavior Velocity velocity = 1 position :: Behavior Position position = integral (atTimes [0, 0.5 ..]) velocity car :: Behavior Car car = Car $ velocity * position main :: IO () main = adaptE $ print $ car `snapshot_` atTimes [0, 0.5..] 1) why is the leak happen? 2) how can I fix this problem? Some more detailed informations: * reactive 0.11.4 * GHC 6.12.1 * Gentoo Linux (2.6.32-tuxonice, x86_64) or Ubuntu 9.10 64bits * compiled with or without -O2 flag 2010/5/16 David Leimbach leim...@gmail.com On Sat, May 15, 2010 at 8:42 AM, Limestraël limestr...@gmail.com wrote: Okay, guess I'll have to bring out the chapter 25 of my Real World Haskell... I find it's often the most practical chapter that I hit a lot during writes and changes to my server process I have in Haskell in our control system code :-) That plus the information that I had missed that Control.Monad.State defaulted to the Lazy version (which is consistent, but for some reason it got by me) helped me to realize why I was leaking so much space in a garbage collected environment. I wouldn't have gotten very far with Haskell as this piece of our code without that chapter. I'd love to see more writing of that sort around Haskell in book form. One can become fluent in tuning Haskell by trial and error, but the sharp corners one must bump into are often sharper than in other languages I've found. Dave 2010/5/15 Bulat Ziganshin bulat.zigans...@gmail.com Hello Limestraėl, Saturday, May 15, 2010, 7:02:38 PM, you wrote: But when I set my beat to tick every 60 times per second, the position is well updated, but I clearly see that the display dramatically slows down after a few seconds of execution. Too heavy rate for integrate? it may be due to lot of uncollected garbage that is result of lazy evaluation. profile program to check its GC times -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ 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] [reactive] A pong and integrate
Hello, I know there is a special mailing list for reactive, but I got no answers when sending to it. Also, maybe my problem is not totally reactive-centered, it concerns integration of an object speed to obtain its position with FRP. As a newbie with reactive, I'm trying to make a simple example, namely a pong. But I'm stuck with the paddle animation. Here is a how I proceed : A paddle: data Paddle = Paddle { paddleCol :: Double, paddleCenter :: Behavior Double } The paddle moves along a column, so only it's Y coordinate changes. paddleCenter is the Y coordinate of its center. This is how I create a paddle: data Direction = PaddleUp | PaddleDown | PaddleStill deriving (Eq, Show) newPaddle :: Behavior Direction - Double - Paddle newPaddle direction column = let position = fmap ((initY ^+^)) $ integral *beat* $ fmap ((speed *) . factor) direction factor PaddleUp = -1 factor PaddleDown = 1 factor _ = 0 speed = 50 -- pixels per second initY = 400-- suppose we have a 800x600 window: paddle is right at the middle *beat = atTimes [0, 0.01..]* in Paddle column position Basically, a paddle is driven by a behavior which tells him to go up, down or to stand still. My problem is with the tuning of the beat, a ticker event which is used for the integration. How do I have to think ? - My speed is in pixels/second, so it has to tick every second? (atTime [0, 1..]) - My app will run at 60fps, so it has to tick 60 times per second? (atTime [0, 1/60..]) The main program (I'm not using any graphics library, just getting keys ('u' for up, 'd' for down) and displaying the current paddle pos) makeKeyboardEvent = do hSetBuffering stdin NoBuffering hSetBuffering stdout NoBuffering (buttonPressedSink, event) - makeEvent = makeClock forkIO . forever $ getChar = buttonPressedSink return event main = do keyEvt - makeKeyboardEvent let dirEvt = fmap key2dir keyEvt paddle = newPaddle (stepper PaddleStill dirEvt) 50 adaptE $ fmap print $ snapshot_ (paddleCenter paddle) $ atTimes [0, 0.01..] key2dir k = maybe PaddleStill snd $ find (($ k) . fst) [((== 'u'), PaddleUp), ((== 'd'), PaddleDown)] When I launch the program, I hit 'u' or 'd' and I see the position increase/decrease. If the beat ticks every second, I see the position being increased by 50 every second, which is normal, but it's a too low refresh rate for an app that is to run at 60fps. But when I set my beat to tick every 60 times per second, the position is well updated, but I clearly see that the display dramatically slows down after a few seconds of execution. Too heavy rate for integrate? That's why I'm asking: how should I use integrate? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [reactive] A pong and integrate
Okay, guess I'll have to bring out the chapter 25 of my Real World Haskell... 2010/5/15 Bulat Ziganshin bulat.zigans...@gmail.com Hello Limestraėl, Saturday, May 15, 2010, 7:02:38 PM, you wrote: But when I set my beat to tick every 60 times per second, the position is well updated, but I clearly see that the display dramatically slows down after a few seconds of execution. Too heavy rate for integrate? it may be due to lot of uncollected garbage that is result of lazy evaluation. profile program to check its GC times -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [reactive] A pong and integrate
I'm definitely not good at profiling... But I have something: 4,971,190,736 bytes allocated in the heap 4,392,735,248 bytes copied during GC 13,998,328 bytes maximum residency (573 sample(s)) 3,281,000 bytes maximum slop 38 MB total memory in use (0 MB lost due to fragmentation) Generation 0: 6987 collections, 0 parallel, 3.18s, 3.01s elapsed Generation 1: 573 collections, 0 parallel, 1.74s, 1.90s elapsed INIT time0.00s ( 0.00s elapsed) MUT time6.60s ( 9.54s elapsed) GCtime4.92s ( 4.91s elapsed) RPtime0.00s ( 0.00s elapsed) PROF time0.02s ( 0.03s elapsed) EXIT time0.01s ( 0.01s elapsed) Total time 11.55s ( 14.49s elapsed) *%GC time 42.6%* (33.9% elapsed) Alloc rate752,071,215 bytes per MUT second Productivity 57.2% of total user, 45.6% of total elapsed COST CENTREMODULE %time %alloc MAIN MAIN 92.2 89.9 newPaddle Pong.Types 7.89.9 Apparently, the integral (which is in newPaddle) does not consumes lots of memory and time. It's the main. I don't see where I should add strict evaluation. 2010/5/15 Limestraël limestr...@gmail.com Okay, guess I'll have to bring out the chapter 25 of my Real World Haskell... 2010/5/15 Bulat Ziganshin bulat.zigans...@gmail.com Hello Limestraėl, Saturday, May 15, 2010, 7:02:38 PM, you wrote: But when I set my beat to tick every 60 times per second, the position is well updated, but I clearly see that the display dramatically slows down after a few seconds of execution. Too heavy rate for integrate? it may be due to lot of uncollected garbage that is result of lazy evaluation. profile program to check its GC times -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FRP demos and tutorials page
Really? There are only 4 fundamental functions in Reactive? Seems simpler than I thought... Thanks, btw, I've been looking quite a long time to simple reactive tutos. 2010/5/10 Tom Poliquin poliq...@softcomp.com On Monday 10 May 2010 00:08, Jean-Marie Gaillourdet wrote: We have created are a set of demos and tutorials for FRP (Conal reactive). It consists of four demos: the simple furnace, the human controlled furnace, the hybrid robot sim, and the FRP robot sim. since I never took the time to understand frp properly I thought it would be helpful to look at some examples. I was able to compile and run the first to programs after I managed to find out the dependencies. But I failed to compile third one. I just got the a compiler error with ghc-6.12.1 on Mac OS X 10.6, see below. No instance for (MatrixComponent Double) .. and various other complaints about Doubles. Thanks Jean for trying the examples out! We'll look into this tomorrow. I think we are down rev a bit in our OpenGL. Our Doubles should be GLdoubles to make everybody happy. We'll upload new code when fixed and let you know. Tom On Monday 10 May 2010 00:08, Jean-Marie Gaillourdet wrote: Hi, since I never took the time to understand frp properly I thought it would be helpful to look at some examples. I was able to compile and run the first to programs after I managed to find out the dependencies. But I failed to compile third one. I just got the a compiler error with ghc-6.12.1 on Mac OS X 10.6, see below. Best regards, Jean leibniz:robot_sim jmg$ ./go Compiling Generator [1 of 2] Compiling Model( Model.hs, Model.o ) [2 of 2] Compiling Main ( Main.hs, Main.o ) Linking main ... Compiling Player [1 of 5] Compiling ReadImage( ReadImage.hs, ReadImage.o ) [2 of 5] Compiling Sprites ( Sprites.hs, Sprites.o ) [3 of 5] Compiling ViewSupport ( ViewSupport.hs, ViewSupport.o ) ViewSupport.hs:32:7: No instance for (MatrixComponent Double) arising from a use of `scale' at ViewSupport.hs:32:7-11 Possible fix: add an instance declaration for (MatrixComponent Double) In the expression: scale In the definition of `scal': scal = scale ViewSupport.hs:100:9: No instance for (NormalComponent Double) arising from a use of `normal' at ViewSupport.hs:100:9-33 Possible fix: add an instance declaration for (NormalComponent Double) In a stmt of a 'do' expression: normal (Normal3 nx ny nz) In the second argument of `($)', namely `do { normal (Normal3 nx ny nz); mapM_ (\ ((vx, vy, vz), tcoord) - do { texCoord tcoord; }) (zip ([q0] ++ [q1] ++ [q2] ++ [q3]) ts) }' In the expression: renderPrimitive Quads $ do { normal (Normal3 nx ny nz); mapM_ (\ ((vx, vy, vz), tcoord) - do { texCoord tcoord; }) (zip ([q0] ++ [q1] ++ [q2] ++ [q3]) ts) } ViewSupport.hs:102:18: No instance for (TexCoordComponent Double) arising from a use of `texCoord' at ViewSupport.hs:102:18-32 Possible fix: add an instance declaration for (TexCoordComponent Double) In a stmt of a 'do' expression: texCoord tcoord In the expression: do { texCoord tcoord; vertex $ Vertex3 vx vy vz } In the first argument of `mapM_', namely `(\ ((vx, vy, vz), tcoord) - do { texCoord tcoord; vertex $ Vertex3 vx vy vz })' ViewSupport.hs:103:18: No instance for (VertexComponent Double) arising from a use of `vertex' at ViewSupport.hs:103:18-23 Possible fix: add an instance declaration for (VertexComponent Double) In the first argument of `($)', namely `vertex' In the expression: vertex $ Vertex3 vx vy vz In the expression: do { texCoord tcoord; vertex $ Vertex3 vx vy vz } ___ 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] IO (Either a Error) question
Yes, I wonder why mtl is not updated so as to remove this restriction. 2010/5/1 John Millikin jmilli...@gmail.com You might want to make a local version of ErrorT in your library, to avoid the silly 'Error' class restriction. This is pretty easy; just copy it from the 'transformers' or 'mtl' package. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
There is the package hint, which embeds the calls to GHC API. Quite easy to use: Let's say your configuration file (cfg/Script.hs) contains a function script that you want to get: type ScriptFun = IO () loadScript :: IO ScriptFun loadScript = do liftM (either (error . show) id) $ runInterpreter $ do path - get searchPath set [searchPath := (./cfg:path)] loadModules [Script] setTopLevelModules [Script] exports - getModuleExports Script if Fun script `elem` exports then *interpret script (as :: ScriptFun)* else error script function not found There is just the line I put in bold that bothers me. Can't we get the action script more easily than by re-interpreting some code? 2010/5/8 Brandon S. Allbery KF8NH allb...@ece.cmu.edu On May 4, 2010, at 01:52 , Maciej Piechotka wrote: After change of file you have to wait a long time as it compiles and links with yi. On my system (1 GB of RAM taken by system + 1 GB 'free' + 2 GB swaps, x86-64) it could in some situations it caused OOM. I'd prefer if the code was interpreted by ghci instead of compiled by GHC in this case (it should be as fast as most of the code was compiled anyway). On the one hand, this is doable with the GHC API. On the other, that more or less means your program contains what amounts to a full copy of GHC. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH ___ 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] IO (Either a Error) question
Personally I think fail is a terrible wart, and should be shunned. So do I. I can't understand its purpose since monads which can fail can be implemented through MonadPlus. 2010/5/8 Ross Paterson r...@soi.city.ac.uk On Sat, May 08, 2010 at 07:49:57AM +1000, Ivan Lazar Miljenovic wrote: Limestraėl limestr...@gmail.com writes: 2010/5/1 John Millikin jmilli...@gmail.com You might want to make a local version of ErrorT in your library, to avoid the silly 'Error' class restriction. This is pretty easy; just copy it from the 'transformers' or 'mtl' package. Yes, I wonder why mtl is not updated so as to remove this restriction. Presumably because its in maintenance mode (i.e. it only gets changed/updated to reflect changes in GHC that might affect it and the API is frozen). The API isn't frozen -- it can be changed with a library proposal, if you can get people to agree to it. As Ryan said, the Error constraint is there to support a definition of the fail method in the Monad instance for ErrorT. (Personally I think fail is a terrible wart, and should be shunned.) ___ 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] Re: Haskell and scripting
You might have misunderstood me. When using hint, one wants the script to be interpreted. It is interpreted when called loadModules [Script] , but if we call later interpret *something* (as :: Something) , the *something *can be any Haskell code, not just a function name, which means hint has also to interpret the *something*. So, IMO, a double interpretation is done when a function such as getSymbol *functionName *(as :: FuncType), which would simply get the function, would be sufficient. I don't know if hint/GHC API allows to do such a thing... 2010/5/8 Brandon S. Allbery KF8NH allb...@ece.cmu.edu On May 7, 2010, at 19:51 , Limestraël wrote: then *interpret script (as :: ScriptFun)* There is just the line I put in bold that bothers me. Can't we get the action script more easily than by re-interpreting some code? Make up your mind: you don't want to have to compile the script, but you don't want to have to interpret the script. What exactly is supposed to be left? -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
^^ That's an interesting debate: How do you imagine the future programming languages? But not today's topic. It's strange that, since Lisp is still used now, especially for teaching purposes, and since everybody complains about parenthesises, nobody developed a Lisp-like just based on indentation... To my mind, I think that as long as you lay out well your code, Lisp is quite readable. I don't see why the parenthesises would make it harder to learn. Daniel, prior to learn Haskell, did you know other functional languages? Cause I didn't, and let me tell you that the functional way of coding wasn't obvious while beginning (now I can't do without), especially the whole monad thing. Problem: Haskell without monads (or structures even more unusual, like Arrows) is no longer Haskell (can be subject to debate, too), so you have to get the point if you want to use properly the language. Or else you stuck to quicksort-like algorithms which show the beauty of the language, but not its power. 2010/5/6 Pierre-Etienne Meunier pierreetienne.meun...@gmail.com Fifty years ago someone came up with this idea of lisp and parentheses. By now in year 2010, I have never heard of any programmer who never made jokes about it. Now imagine the discussions in 2060 : - ahah, you're still programming with monads. lol - no but theyre ok for dirty scripting. - all these =, significative indentation, You're from the past dude. - Wtf !!? haskell's easy to compile. - So what ? ... good luck limestraël ;-) El 05/05/2010, a las 18:25, Gregory Crosswhite escribió: On May 5, 2010, at 3:09 PM, Daniel Fischer wrote: Learning Lisp dialects is much harder (to a large part because of the parentheses, which makes them near impossible to parse). On the contrary, the whole point of parentheses is that it makes Lisp *easier* to parse... for computers. :-) Cheers, Greg ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
Don Cave said: We've been through the generalities of this discussion before - is map hard, are for loops easy? what if you never learned an imperative language, does that make a difference, aren't functional languages the most natural because everyone knows about equations, ... etc. Oh yes. The problem comes from the sole fact that -- generally -- we sadly start by the imperative paradigm. I now there are a few universities, in France, which teaches to the beginners Lisp or Ocaml, but they are not countless. Moreover, call me an integrist but beginning students are usually dumb (I was, so no offense): either they are stubborn and reject programmation whatever the language is, or they are geeks who swear by regular languages (*), mostly because gamemakers or software companies use them. They follow the crowd. Time to change some minds. But, hey, by swearing by functional programming I'm kind of a nonconformist geek, too. (*) Been there. I'm digressing. 2010/5/6 Daniel Fischer daniel.is.fisc...@web.de Haskell just matched the natural way of thinking pretty closely. I agree. Especially with datatypes. I personnaly don't think naturally in objects, with notions of inheritance and such. IMO, it is much more human to express in terms of alternatives. A door is either unlocked or locked with a key: data Door = Unlocked | Locked Key (maybe not the best example but it's just the one that went through my mind) 2010/5/6 Daniel Fischer daniel.is.fisc...@web.de ... good luck limestraël ;-) Seconded. I chose the Dyre method. The easy path. ^^ If I was trying to make a game, I should be trying hslua. Just sad I didn't find an easy way to script in functional (*). (*) Nonconformist geek hit again. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
How do you embed Lua in Haskell? 2010/5/5 Niclas W nicl...@gmail.com Limestraël limestrael at gmail.com writes: (*) functional language, because I want to keep the benefit of functional programming for scripting. So no Lua, no Python... You might want to take another look at lua. It is pretty darn functional. Also fast, small, and seems to be even easier to embed in haskell than in c. ___ 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] Re: Haskell and scripting
Thanks! However, I don't forget that my goal is to get a system monitor configuration language. Lua may have some functional components, it remains imperative, I think a more declarative language like Scheme would be more appropriate (and there is also a scheme interpreter, haskeem). What do you think about it? 2010/5/5 Ivan Lazar Miljenovic ivan.miljeno...@gmail.com Limestraël limestr...@gmail.com writes: How do you embed Lua in Haskell? http://hackage.haskell.org/package/hslua -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
Yes, the xmonad approach is very neat, but I see 2 major (IMO) drawbacks to it: 1) The end-user has to have GHC, and all the necessary libraries to compile the configuration 2) A scripting language should be simple and QUICK to learn : Haskell is clean, powerful but its learning takes time Uwe, I noticed kind of recently the haskeem package, I have not tried it yet and I didn't know its usability. If you say it's not made for that, then I believe you. 2010/5/5 Yitzchak Gale g...@sefer.org Maciej Piechotka wrote: After change of file you have to wait a long time as it compiles and links with yi. But Yi is a far bigger application than what Limestraël is talking about. One of my computers is very old and much less powerful than yours (let's just say that it has far less than 1 Gb memory in total). On that machine, xmonad, still much larger than Limestraël's app, recompiles its configuration file almost instantaneously. And of course, even that fast recompile only happens when I change the configuration, which is almost never. I would try the xmonad approach to scripting in Haskell. It is much simpler to implement than any of the others, and much neater if you find that it works well. Regards, Yitz ___ 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] Re: Haskell and scripting
I do agree, but you will not object if I say that scheme is quicker to learn than Haskell. Most of all, I think Haskell is far too rigorous to serve scripting purposes for my app. Quick and dirty is clearly not the Haskell way. And is think its the very intrinsic nature of scripting to be done fast. Nevertheless, I'm not a bigot ^^, if you people think Lua is an appropriate language for what I'm trying to do, and if it is convenient to use with Haskell, then I'm willing to give it a go. 2010/5/5 Kyle Murphy orc...@gmail.com Concerning your second point, I think just about any functional language isn't going to be simple or quick to learn. It's simply not a way of approaching problems that your average person (even your average programmer) is used to dealing with. Things like fold and map, the work horses of functional programming, are simply too foreign to most peoples imperative way of approaching problems. -R. Kyle Murphy -- Curiosity was framed, Ignorance killed the cat. On Wed, May 5, 2010 at 16:29, Limestraël limestr...@gmail.com wrote: Yes, the xmonad approach is very neat, but I see 2 major (IMO) drawbacks to it: 1) The end-user has to have GHC, and all the necessary libraries to compile the configuration 2) A scripting language should be simple and QUICK to learn : Haskell is clean, powerful but its learning takes time Uwe, I noticed kind of recently the haskeem package, I have not tried it yet and I didn't know its usability. If you say it's not made for that, then I believe you. 2010/5/5 Yitzchak Gale g...@sefer.org Maciej Piechotka wrote: After change of file you have to wait a long time as it compiles and links with yi. But Yi is a far bigger application than what Limestraël is talking about. One of my computers is very old and much less powerful than yours (let's just say that it has far less than 1 Gb memory in total). On that machine, xmonad, still much larger than Limestraël's app, recompiles its configuration file almost instantaneously. And of course, even that fast recompile only happens when I change the configuration, which is almost never. I would try the xmonad approach to scripting in Haskell. It is much simpler to implement than any of the others, and much neater if you find that it works well. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and scripting
Well, it is clear that, for me, the dyre approach is clearly the simplest to implement, since everything is in Haskell. Maybe I could start with it, and see if it suits me... (Sorry, I know, ^^ I keep changing my mind...) 2010/5/5 Gwern Branwen gwe...@gmail.com On Wed, May 5, 2010 at 4:29 PM, Limestraël limestr...@gmail.com wrote: Yes, the xmonad approach is very neat, but I see 2 major (IMO) drawbacks to it: 1) The end-user has to have GHC, and all the necessary libraries to compile the configuration 2) A scripting language should be simple and QUICK to learn : Haskell is clean, powerful but its learning takes time For basic customization, many XMonad users (judging by questions on #xmonad) have little to no Haskell experience and get by. Further, it's easier to step down the power than to increase it; because we use Haskell, it's possible to have simpler configuration options like xmonad-light* * http://braincrater.wordpress.com/2008/08/28/announcing-xmonad-light/ isn't a very good explanation of xmonad-light, but I don't know of any others -- gwern ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell and scripting
A complete language needs a complete implementation. No, Minh, I was not talking about re-implementing a whole Lisp/Scheme language interpreter in Haskell. (I know there is BTW a Scheme interpreter made in Haskell : http://jonathan.tang.name/files/scheme_in_48/tutorial/overview.html). But what I really wanted to know is how usually haskellers do to script their applications. For instance (as you say), many games made in C/C++ use Lua (for AI or for configuration). That is the kind of scripting I'm talking about : a compiled program (in Haskell) reading an interpreting a script (in some already existing interpreted language (*) or some DSL especially made for this purpose). (*) functional language, because I want to keep the benefit of functional programming for scripting. So no Lua, no Python... I may have misunderstood your goals and what you mean by scripting. Our DSEL is intended to be used for expressing all kinds of scripting tasks. Martin, I did not understand your meaning of scripting. IMO, a program can be scripted if it provides a way to alter (a part of) its configuration without having to recompile it entirely. If need be it recompiles the configuration files, but I think it's better if those files are interpreted (speeds up the program lauching, since it doesn't have to compile and link again (*)) (*) Yi, for instance, takes a little time to recompile its configuration, and when it re-links its executable, it weighs 38Mo! (and dynamic linking is still not perfect in Haskell) Plus, end-users have to install the compiler (GHC, which is not lightweight), even if they have the statically-linked executable of the application. 2010/5/4 minh thu not...@gmail.com 2010/5/4 Limestraël limestr...@gmail.com: ... Minh, Kyle, Gwern, the dyre approach seems to be very interesting too. But if I understood well, we also have to recompile at run-time the configuration haskell script? So the final application (Yi, for instance) will need GHC to be installed to run? Or did I miss something? By the way, I had never heard of Yi, but can I deduce from its name its a Vi(m)-like (which I am a big fan of)? Moreover, the idea of scripting my editor in Haskell appeals me. Yes GHC is needed. But if your goal is to produce something with the benefits of a complete language for configuration, I think it's fine. Numerous games include for instance a complete Lua interpreter, SketchUp includes a ruby interpreter (or maybe it is python), Blender uses python, Common Lisp programs can use Common Lisp, and so on. A complete language needs a complete implementation. If you want to make your own (non-embedded) DSL, you will either provide less than a complete language or have to implement a lot of stuff. Cheers, Thu ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell and scripting
Hello Café, I don't know if you know conkyhttp://en.wikipedia.org/wiki/Conky_%28software%29. It's a well-known open-source system monitor (a software that displays information on the desktop, like CPU frequency, disk usage, network rate, etc.). It is quite good, but it's very descriptive, and even if you can call shell commands it's clearly not made for being scripted. What I would do is to make a similar system monitor, which base would be compiled Haskell code, but that would be scriptable with some DSL, or already existing interpreted language. I've thought about a Lisp/Scheme language, since those languages are functional, dynamically typed and simple (so enable a quick scripting) and I'm not very keen on making my own DSL What I would like to know is: 1) If you have other solutions 2) How do haskellers usually script their applications ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell and scripting
Thank you all, that's very interesting. Martin, I've started reading the paper, I like the way you think about what a scripting language should provide (traceability, error handling and a type system). But, hold me if I'm wrong, but at no moment in the paper you made you own language? It's a EDSL, not a DSL, so I don't see where is the scripting, since the program will always have to be recompiled, won't it? Minh, Kyle, Gwern, the dyre approach seems to be very interesting too. But if I understood well, we also have to recompile at run-time the configuration haskell script? So the final application (Yi, for instance) will need GHC to be installed to run? Or did I miss something? By the way, I had never heard of Yi, but can I deduce from its name its a Vi(m)-like (which I am a big fan of)? Moreover, the idea of scripting my editor in Haskell appeals me. 2010/5/3 Gwern Branwen gwe...@gmail.com On Mon, May 3, 2010 at 5:47 PM, Kyle Murphy orc...@gmail.com wrote: That's also the approach Yi uses. I'm fairly certain there's a library on hackage that makes writing up programs in that style fairly trivial, http://hackage.haskell.org/package/dyre -- gwern ___ 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] Happy: PATH issue
Yes, it's weird, but it works! Thanks. 2010/5/1 Daniel Fischer daniel.is.fisc...@web.de Am Samstag 01 Mai 2010 13:16:55 schrieb Limestraël: Hello Café, When I was trying to cabal-install haskell-src, I came up with: cabal: The program happy is required but it could not be found However, the happy package was actually installed and the 'happy' executable was in ~/.cabal/bin (which was in my PATH) Just a couple of days ago, we had an issue where ~/.cabal/bin was in the path, but (due to some differences between tilde-expansion and $-variable expansion), it didn't work, however $HOME/.cabal/bin in the path worked. Could that be another instance of the same issue? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Happy: PATH issue
Hello Café, When I was trying to cabal-install haskell-src, I came up with: cabal: The program happy is required but it could not be found However, the happy package was actually installed and the 'happy' executable was in ~/.cabal/bin (which was in my PATH) I had to link ~/.cabal/bin/happy to /usr/bin/happy so that cabal-install may finally find it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: forkable-monad 0.1
Nice initiative! By the way, since this is a monad, I think a better place than Control.Concurrent.Forkable would be Control.Monad.Forkable. It's just a suggestion. 2010/4/21 David Anderson d...@natulte.net Dear Haskellers, I'm happy, and only slightly intimidated, to announce the initial release of forkable-monad. The short version is that forkable-monad exports a replacement forkIO that lets you do this: type MyMonad = ReaderT Config (StateT Ctx IO) startThread :: MyMonad ThreadId startThread = forkIO threadMain threadMain :: MyMonad () threadMain = forever $ liftIO $ putStrLn Painless monad stack forking! Note the lack of monad stack deconstruction and reconstruction to transport it over to the new thread. You'll find the details in the Haddock documentation for the module. forkable-monad is available: * On hackage: http://hackage.haskell.org/package/forkable-monad * Via cabal: cabal install forkable-monad * Source and issue tracker: http://code.google.com/p/forkable-monad/ Feedback is of course welcome. As this is my first published Haskell code and Hackage upload, I expect there will be quite a bit! - Dave ___ 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] Functional Dependencies conflicts
It seems like a reasonable and not-too-painful solution, thanks! Concerning Haskell typesystem, I know it to be beautiful, but also kind of complex. One of the great Haskell assets is genericity, but this complexity sometimes encumbers this genericity. But still, Haskell is -- in terms of flexibility -- way before other languages which pretend to be generic. 2010/4/18 Sebastian Fischer s...@informatik.uni-kiel.de On Apr 18, 2010, at 11:01 AM, Limestraël wrote: It's strange I can't declare a generic instance for Binary types... I thought I was trying to do something quite common in Haskell. A common workaround is to define a newtype like this newtype GenericBinary a = GB { fromGB :: a } and an instance like this instance Binary a = Binarizable (GenericBinary a) a where toBinary = fromGB which only needs FlexibleInstances enabled. You can then 'tag' Binary types for which you want to use the generic default instance above with the GB newtype constructor. Whether this is less of a pain than implementing a Binarizable instance for each Binary type is a different question.. Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional Dependencies conflicts
There must be some kind of a private joke I don't get... BTW, all you've said is pretty scaring... It's strange I can't declare a generic instance for Binary types... I thought I was trying to do something quite common in Haskell. Apparently I'm still a young padawan with many things to learn. Anyway, it's not the first time I get worked up with multi-param typeclasses and functionnal dependencies 2010/4/18 Ivan Lazar Miljenovic ivan.miljeno...@gmail.com Daniel Fischer daniel.is.fisc...@web.de writes: Wow. Makes me wonder what quicksilver says about IncoherentInstances. Not quicksilver, but according to lambdabot: ivanm @quote incoherent lambdabot sproingie says: * enables IncoherentInstances and ends up with Sarah Palin in his living room -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com ___ 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] Functional Dependencies conflicts
Hello, I'm trying to make two simple classe which would help me to transform unserializable datatypes to serializable ones. The classes are: class (Binary b) = Binarizable a b | a - b where toBinary :: a - b class (Binarizable a b, Monad m) = Unbinarizable a b m | a - b where fromBinary :: b - m a The idea is simple: if we have a type 'a' which cannot be serialized (for instance because it contains functions), we may turn it into a 'b' type which is instance of Binary, with of course a loss of information. And then, Unbinarizable enables us to get the original 'a' type back. fromBinary has to run inside a monad so that it can somehow recover the lost information. Now, for instance, in a simple role playing game, we would have the datatype : data GameObject = GameObject { objIdentifier :: String, objEffect :: Character - Character } It can't obviously be declared instance of Binary, since the field objEffect is a function. So -- since an objIdentifier must be unique -- we can declare it instance of Binarizable/Unbinarizable: instance Binarizable GameObject String where toBinary = objIdentifier instance (MonadReader [GameObject] m) = Unbinarizable GameObject String m where fromBinary name = liftM getIt ask where getIt = maybe err id . find ((== name) . objIdentifier) err = error $ Unbinarize: The object ' ++ name ++ ' doesn't exist! To be unbinarized, we need to have a ReaderMonad which grants us access to the list of all the objects, so that we may find the object from its identifier. Well, here comes the trouble: GameStructs.hs:16:9: Functional dependencies conflict between instance declarations: instance (Binary a) = Binarizable a a -- Defined at MagBots/GameStructs.hs:16:9-37 instance Binarizable GameObject String -- Defined at MagBots/GameStructs.hs:38:9-37 GameStructs.hs:19:9: Functional dependencies conflict between instance declarations: instance (Binary a, Monad m) = Unbinarizable a a m -- Defined at MagBots/GameStructs.hs:19:9-50 instance (MonadReader [GameObject] m) = Unbinarizable GameObject String m -- Defined at MagBots/GameStructs.hs:41:9-73 I don't see why the functional dependencies conflict, since GameObject is not an instance of Binary... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional Dependencies conflicts
Yes! Sorry, I forgot a bit: Binary types are automatically made instances of Binarizable/Unbinarizable (that's my line 16): instance (Binary a) = Binarizable a a where toBinary = id instance (Binary a, Monad m) = Unbinarizable a a m where fromBinary = return To me, the functional dependency in: class (Binary b) = Binarizable a b | a - b meant that for each a, there only one type b that can match. That's what I want: for every Binary type 'a', the matching Binary is also 'a' And for GameObject, the sole matching type is String. In other words, GameObject implies String. I would have undestood the error if GameObject was also an instance of Binary (then the two instances would match), but it's not the case... Is my FunDep wrong? I done this especially because I didn't wanted to declare each type one by one instance of Binarizable, Haskell type system normally enables me to automatically define a Binary as an instance of Binarizable. 2010/4/17 Daniel Fischer daniel.is.fisc...@web.de Am Samstag 17 April 2010 19:14:02 schrieb Limestraël: Hello, Well, here comes the trouble: GameStructs.hs:16:9: Functional dependencies conflict between instance declarations: instance (Binary a) = Binarizable a a -- Defined at MagBots/GameStructs.hs:16:9-37 instance Binarizable GameObject String -- Defined at MagBots/GameStructs.hs:38:9-37 GameStructs.hs:19:9: Functional dependencies conflict between instance declarations: instance (Binary a, Monad m) = Unbinarizable a a m -- Defined at MagBots/GameStructs.hs:19:9-50 instance (MonadReader [GameObject] m) = Unbinarizable GameObject String m -- Defined at MagBots/GameStructs.hs:41:9-73 I don't see why the functional dependencies conflict, since GameObject is not an instance of Binary... Somebody somewhere might write such an instance. But more fundamentally: GHC doesn't look at the constraints for instance selection, so your instance in line 16 looks like instance Binarizable a a where ..., oh, and by the way, a must be an instance of Binary, otherwise please refuse to compile to the compiler. The FunDep then says in each instance (and you'd need at least OverlappingInstances to declare more) a and b are the same type. instance Binarizable GameObject String violates that FunDep. (Analogous for Unbinarizable.) I think removing the instance Binary a = ... and declaring an instance for the types you need manually is the easiest solution. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functional Dependencies conflicts
Ok, so I am heading to a headache... Daniel Fischer mentioned a solution using Type Families. As I read, those are meant to replace the FunDeps, I will try this solution... 2010/4/17 Casey McCann syntaxgli...@gmail.com On Sat, Apr 17, 2010 at 4:01 PM, Limestraël limestr...@gmail.com wrote: I would have undestood the error if GameObject was also an instance of Binary (then the two instances would match), but it's not the case... As Daniel Fischer has mentioned, presumably a Binary instance could later be written for GameObject; even if you have no intention of doing so, GHC considers the possibility. In other words, it's sufficient that such an instance could exist, not that it actually does. In general: Instance selection and context checking are separate and occur in that order, thus contexts generally can't influence instance selection (except by using OverlappingInstances and strategically confusing instance heads, ensuring that GHC can't make any sense of your code until considering the contexts). Unfortunately, anything involving extremely generic instances with some constraint tend to be very difficult to construct, because of how this works. This tends to include things like default instances for types not covered by specific ones, making all instances of X also instances of Y, fundep type predicates based on class membership, and so on. Type hackery can often get you most of what you want, but it gets awkward fast. - C. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple binary-protocol through network test
By the way, I happen to have a little problem when I try to add data compression/decompression. Since its impossible to add binary treatments (I call binary treatment a function which type is: ByteString - ByteString, e.g. compression), I made my own package binary-communicator. (can be found on hackage) It's very simple. It's a mere IORef containing a lazy bytestring, and updated when we try to read from it. Same example, client sends a computation, the server does it and sends the result back. When I use id a treatment function (no compression whatsoever), everything works But when I use compress/decompress (from Codec.Compression.GZip), I have the following weird issue: The server treats well the first computation, and sends back the answer, and then immediately fails with a Server: too few bytes. Failed reading at byte position 1, and closes the connection. GZip compression is supposed to work on lazy bytestrings, and it does since the first computation is well done. Does someone see the problem? I enclosed an archive containing all the files. (working version of binary-communicator and the sample) 2010/4/8 Gregory Crosswhite gcr...@phys.washington.edu That sounds like a reasonable modification; if you want, free to fork it at http://github.com/gcross/binary-protocol and push me your proposed changes. Cheers, Greg On Apr 8, 2010, at 9:12 AM, Yves Parès wrote: By the way, Gregory, concerning the package binary-protocol, I was wondering if it was possible to turn the BinaryProtocol monad from type BinaryProtocol = StateT (Handle, Handle, ByteString) IO to: type BinaryProtocol = StateT (Handle, Handle, ByteString) And then the functions, like runProtocol, would become: runProtocol :: (MonadIO m) = BinaryProtocol m a - Handle - Handle - m a I mean that BinaryProtocol could run within any MonadIO, not only IO. This would turn the BinaryProtocol into a monad trans, which would be more generic (we could for instance stack two BinaryProtocols). Yves Parès wrote: Problem tracked! It comes from the last version of bytestring package. I tried with bytestring-0.9.1.5, and it works perfectly. Do you know where I should submit this bug? - Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Simple-binary-protocol-through-network-test-tp28157883p28180773.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe binary-communicator.tar.gz Description: GNU Zip compressed data ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Fwd: Re: Simple game: a monad for each player
Ok, but there is no function such as mapMonad in the operational package? By the way, I noticed that ProgramT is not automatically made instance of MonadIO when possible. It could be: instance (MonadIO m) = MonadIO (ProgramT r m) where liftIO = lift . liftIO Is that intentional? ( In fact, I think it's a slip in the mtl package itself, since every instance of MonadTrans can be declared instance of MonadIO: instance (MonadTrans t, MonadIO m) = MonadIO (t m) where liftIO = lift . liftIO ) By the way, I finally managed to use operational to modify my TicTacToe game. (One shot, by the way, I had no bugs ^^. Very nice when it happens...) Human player and AI are working. I'm currently fixing the Network player. If you are interested, I could upload my code (it can be another example of how to use the operational package). In the end, I used a mix of your solution and my former one. I have a Request datatype: data Request a where GetGrid :: Request Grid TurnDone :: (Grid, Maybe GridResult) - Request () GetResult :: Request (Maybe GridResult) (Grid is what you called Board, GridResult is a type which indicates if someone wins or if there is a draw) The game monad is PlayerMonadT, and is a newtype: newtype PlayerMonadT m a = PMT (ProgramT Request m a) deriving (Functor, Monad, MonadTrans) I still have a datatype Player, which contains functions: (I tried to use classes, but it was more complicated) data Player m m' = Player { -- | Gets the mark (Cross or Circle) of the player plMark :: Mark, -- | Called when the player must play plTurn :: Grid - m Pos, -- | Called when player tries to play at a forbidden position plForbidden :: Pos - m (), -- | Called when game has ended. plGameOver :: GridResult - m (), -- | Used to reach PlayerMonad in the monad stack plLift :: forall a. PlayerMonadT m' a - m a, -- | Used to run the monad stack the player runs in plRun :: forall a. m a - PlayerMonadT m' a } *m* is the monad stack the player runs in. It must be able to run it, by providing a plRun function. *m'* is the top monad, which can't be run (IO for human, any monad for AI, etc.) The alteration done to this type is the addition of the plLift and plRun functions. Those are the functions you, Heinrich, and Bertram told me about. Then, *all* the players play according to this logic: playerLogic :: (Monad m) = Player m m' - m () playerLogic pl = do let toProg = plLift pl . PMT . singleton grid - toProg GetGrid pos - plTurn pl grid case checkCell grid (plMark pl) pos of Nothing - do-- The cell was already filled in plForbidden pl pos -- We signal the error playerLogic pl -- We start the turn again Just newGridAndResult - do -- The cell has been successfully marked, so we got a new grid toProg $ TurnDone newGridAndResult -- At this point, the interpreter will switch to the other player mbResult - toProg $ GetResult -- This player is back, and wants to know what's new case mbResult of Nothing - playerLogic pl Just res - plGameOver pl res We can then run this function with the player custom stack thanks to the runPlayer function: runPlayer :: (Monad m) = Player m m' - PlayerMonadT m' () runPlayer pl = plRun pl $ playerLogic pl And finally, the interpreter: doGame :: (Monad m) = Grid - [PlayerMonadT m ()] - m Grid doGame initGrid players = mapM unwrap players = flip evalStateT (initGrid, Nothing) . eval where unwrap (PMT pl) = viewT pl eval :: (Monad m) = [PromptT Request m ()] - StateT (Grid, Maybe GridResult) m Grid eval [] = liftM fst get eval ((Return _) : pls) = eval pls eval ((GetGrid := pl) : pls) = do (grid, _) - get p - lift . viewT $ pl grid eval $ p : pls eval ((TurnDone (newGrid, mbResult) := pl) : pls) = do put (newGrid, mbResult) p - lift . viewT $ pl () eval $ pls ++ [p] eval ((GetResult := pl) : pls) = do (_, mbResult) - get p - lift . viewT $ pl mbResult eval $ p : pls The game can be launched by doing for example: let pl1 = humanPlayer Cross let pl2 = artificialPlayer Circle levelOfDifficulty doGame blankGrid [runPlayer pl1, runPlayer pl2] I did it! 2010/4/15 Heinrich Apfelmus apfel...@quantentunnel.de Limestraël wrote: Okay, I start to understand better... Just, Heinrich, how would implement the mapMonad function in terms of the operational package? You just shown the signature. Ah, that has to be implemented by the library, the user cannot implement this. Internally, the code would be as Bertram suggests: mapMonad :: (Monad m1, Monad m2) = (forall a . m1 a - m2 a) - ProgramT instr m1 a - ProgramT instr m2 a mapMonad f (Lift m1) = Lift (f m1) mapMonad f (Bind m k) = Bind (mapMonad f m) (mapMonad f . k) mapMonad f (Instr i) = Instr i I
Re: [Haskell-cafe] Re: Fwd: Re: Simple game: a monad for each player
There is the project. I changed some little things with the player datatype. For flexibility sake, it's stack has no longer to contain PlayerMonadT (I needed it for the net player client) The most interesting part (the one that deals with operational) is in TicTacToe/Game.hs This is not very, very clean (incomplete doc, for instance), but it'll do the work. By the way, the game.hs and client.hs are to be modified (it's the only way to change the type of the players in the game) 2010/4/15 Limestraël limestr...@gmail.com Ok, but there is no function such as mapMonad in the operational package? By the way, I noticed that ProgramT is not automatically made instance of MonadIO when possible. It could be: instance (MonadIO m) = MonadIO (ProgramT r m) where liftIO = lift . liftIO Is that intentional? ( In fact, I think it's a slip in the mtl package itself, since every instance of MonadTrans can be declared instance of MonadIO: instance (MonadTrans t, MonadIO m) = MonadIO (t m) where liftIO = lift . liftIO ) By the way, I finally managed to use operational to modify my TicTacToe game. (One shot, by the way, I had no bugs ^^. Very nice when it happens...) Human player and AI are working. I'm currently fixing the Network player. If you are interested, I could upload my code (it can be another example of how to use the operational package). In the end, I used a mix of your solution and my former one. I have a Request datatype: data Request a where GetGrid :: Request Grid TurnDone :: (Grid, Maybe GridResult) - Request () GetResult :: Request (Maybe GridResult) (Grid is what you called Board, GridResult is a type which indicates if someone wins or if there is a draw) The game monad is PlayerMonadT, and is a newtype: newtype PlayerMonadT m a = PMT (ProgramT Request m a) deriving (Functor, Monad, MonadTrans) I still have a datatype Player, which contains functions: (I tried to use classes, but it was more complicated) data Player m m' = Player { -- | Gets the mark (Cross or Circle) of the player plMark :: Mark, -- | Called when the player must play plTurn :: Grid - m Pos, -- | Called when player tries to play at a forbidden position plForbidden :: Pos - m (), -- | Called when game has ended. plGameOver :: GridResult - m (), -- | Used to reach PlayerMonad in the monad stack plLift :: forall a. PlayerMonadT m' a - m a, -- | Used to run the monad stack the player runs in plRun :: forall a. m a - PlayerMonadT m' a } *m* is the monad stack the player runs in. It must be able to run it, by providing a plRun function. *m'* is the top monad, which can't be run (IO for human, any monad for AI, etc.) The alteration done to this type is the addition of the plLift and plRun functions. Those are the functions you, Heinrich, and Bertram told me about. Then, *all* the players play according to this logic: playerLogic :: (Monad m) = Player m m' - m () playerLogic pl = do let toProg = plLift pl . PMT . singleton grid - toProg GetGrid pos - plTurn pl grid case checkCell grid (plMark pl) pos of Nothing - do-- The cell was already filled in plForbidden pl pos -- We signal the error playerLogic pl -- We start the turn again Just newGridAndResult - do -- The cell has been successfully marked, so we got a new grid toProg $ TurnDone newGridAndResult -- At this point, the interpreter will switch to the other player mbResult - toProg $ GetResult -- This player is back, and wants to know what's new case mbResult of Nothing - playerLogic pl Just res - plGameOver pl res We can then run this function with the player custom stack thanks to the runPlayer function: runPlayer :: (Monad m) = Player m m' - PlayerMonadT m' () runPlayer pl = plRun pl $ playerLogic pl And finally, the interpreter: doGame :: (Monad m) = Grid - [PlayerMonadT m ()] - m Grid doGame initGrid players = mapM unwrap players = flip evalStateT (initGrid, Nothing) . eval where unwrap (PMT pl) = viewT pl eval :: (Monad m) = [PromptT Request m ()] - StateT (Grid, Maybe GridResult) m Grid eval [] = liftM fst get eval ((Return _) : pls) = eval pls eval ((GetGrid := pl) : pls) = do (grid, _) - get p - lift . viewT $ pl grid eval $ p : pls eval ((TurnDone (newGrid, mbResult) := pl) : pls) = do put (newGrid, mbResult) p - lift . viewT $ pl () eval $ pls ++ [p] eval ((GetResult := pl) : pls) = do (_, mbResult) - get p - lift . viewT $ pl mbResult eval $ p : pls The game can be launched by doing for example: let pl1 = humanPlayer Cross let pl2 = artificialPlayer Circle levelOfDifficulty doGame blankGrid [runPlayer pl1, runPlayer pl2] I did it! 2010/4/15 Heinrich
Re: [Haskell-cafe] Simple game: a monad for each player
Yves, that is exactly how I designed my program so far. Human player needs a monad IO, AI needs just a monad, whatever it is, and I make both run in IO. And, as you said, the type of the ai (bot :: Monad m = Player m) contains no IO, so I know that, even if I make it run in IO, it won't make any side-effect. My problem was, for example, if I want a player to run in its OWN monad. Human uses IO, which is unique and shared by all the human players in the program. But what if I want an AI that remember every former opponent's move, so that it could adapt its reflexion all along the game? Then this AI would have to run in its own State monad, for instance. 2010/4/13 Tillmann Rendel ren...@informatik.uni-marburg.de Yves Parès wrote: data Player m = Player { plName :: String, -- unique for each player plTurn :: GameGrid - m Move -- called whenever the player must play } What I try to avoid is having every player running in IO monad. One could define the following players. human :: MonadIO m = Player m human = ... bot :: Monad m = Player m bot = ... Note that these players are polymorphic in m, only assuming some minimal interface. Now you can run both players in a single monad which is good enough for both, because it supports the union of the interfaces assumed by the various players. In this case, this monad could be IO, since it supports both MonadIO and Monad. changeBoard :: Board - Move - board changeBoard = ... play :: Player IO - Player IO - GameGrid - IO GameResult play p1 p2 board do move - plTurn p1 board play p2 p1 (changeBoard board move) While this is probably not as expressive as what you want, it is reasonably simple, and it has the property that bot is not in the IO monad. I have first seen this pattern in monadic interpreters, where you could have types like the following. eval :: (MonadReader Env m) = Expression - m Value exec :: (MonadReader Env m, MonadIO m) = Statement - m () These types reflect that the interpreted language permits side-effects only in statements, but not in expressions. This is similar to your situation: You want your types to reflect that your game permits side-effects only in human players, not in artifical intelligences. Tillmann ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Simple game: a monad for each player
I have some difficulties to see the use of PromptT, because in the tutorial, this type is never mentioned, and its operations (Return and :=) are instead constructors of ProgramT... Would you have some concrete examples? Because there I'm a bit lost (since the tutorial doesn't match the operational package as it is, because of the type PromptT)... 2010/4/14 Heinrich Apfelmus apfel...@quantentunnel.de Bertram Felgenhauer wrote: Yves Parès wrote: I answered my own question by reading this monad-prompt example: http://paste.lisp.org/display/53766 But one issue remains: those examples show how to make play EITHER a human or an AI. I don't see how to make a human player and an AI play SEQUENTIALLY (to a TicTacToe, for instance). A useful idea is to turn the construction upside-down - rather than implementing the game logic using MonadPrompt (or operational), implement the players in such a monad. A sketch: {-# LANGUAGE GADTs, EmptyDataDecls #-} import Control.Monad.Prompt hiding (Lift) data Game -- game state data Move -- move data Request m a where Board:: Request m Game MakeMove :: Move - Request m () Lift :: m a - Request m a type Player m a = Prompt (Request m) a Just a small simplification: it is not necessary to implement the Lift constructor by hand, the operational library implements a generic monad transformer. The following will do: import Control.Monad.Operational data Request a where Board:: Request Game MakeMove :: Move - Request () type Player m a = ProgramT Request m a game :: Monad m = Player m () - Player m () - m () game p1 p2 = do g - initGame eval' g p1 p2 where eval' g p1 p2 = viewT p1 = \p1' - eval g p1' p2 eval :: Monad m = Game - - Prompt Request m () - Player m () - m () eval g (Return _)_ = return () eval g (Board := p1) p2 = eval' g (p1 g) p2 eval g (MakeMove mv := p1) p2 = makeMove mv g = \g - eval' g p2 (p1 ()) This way, you are guaranteed not to break the lifting laws, too. What have we achieved? Both players still can only access functions from whatever monad m turns out to be. But now each strategy can pile its own custom monad stack on the Player m monad! And of course, the use of the m Monad is completely optional. Of course, the custom monad stack has to provide a projection back to the Player m a type runMyStackT :: MyStackT (Player m) a - Player m a Fortunately, you can't expect anything better anyway! After all, if the game function were to accept say LogicT (Player m) as well, this would mean that the player or AI could interleave the game arbitrarily, clearly not a good idea. Mapping between various 'm' monads may also be useful: mapPlayerM :: forall m1 m2 a . (forall a . m1 a - m2 a) - Player m1 a - Player m2 a mapPlayerM m1m2 pl = runPromptC return handle pl where handle :: Request m1 x - (x - Player m2 a) - Player m2 a handle (Lift a) x = prompt (Lift (m1m2 a)) = x handle (MakeMove mv) x = prompt (MakeMove mv) = x handle (Board) x = prompt (Board) = x This could be used to lock out the AI player from using IO, say. Shouldn't this actually be a member of the MonadTrans class? mapMonad :: (Monad m1, Monad m2, MonadTrans t) = (forall a . m1 a - m2 a) - t m1 a - t m2 a ? 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 mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Fwd: [Haskell-cafe] Re: Simple game: a monad for each player
Okay, I just understood that 'Prompt' was just a sort of view for 'Program'. I'd like to make it very accessible, so please don't hesitate to report any difficulties with finding and understanding documentation and examples! Then I think the name 'Prompt' may be misleading for those who doesn't know the MonadPrompt package. Maybe something like 'ProgramView' ? What have we achieved? Both players still can only access functions from whatever monad m turns out to be. But now each strategy can pile its own custom monad stack on the Player m monad! And of course, the use of the m Monad is completely optional. Of course, the custom monad stack has to provide a projection back to the Player m a type runMyStackT :: MyStackT (Player m) a - Player m a According to what Bertram said, each strategy can pile its own custom monad stack ON the (Player m) monad. Here, you are stacking the (Player m) monad ON the custom monad stack. What is then the use of the 'm', in (Player *m*)? Is it not supposed to be a custom monad? (MonadIO for human, Identity for AI, etc.) But then, I don't see how the game function could work: game :: Monad m = Player m () - Player m () - m () As it is written, it requires both players to run in the SAME monad. And if have a network player ( e.g.* Player (StateT Handle IO)* ) and an AI storing former opponent's moves ( e.g. *(Monad m) = Player (StateT [Move] m)* ), then they can't be in the same monad... * * 2010/4/14 Heinrich Apfelmus apfel...@quantentunnel.de Limestraël wrote: I have some difficulties to see the use of PromptT, because in the tutorial, this type is never mentioned, and its operations (Return and :=) are instead constructors of ProgramT... Would you have some concrete examples? Because there I'm a bit lost (since the tutorial doesn't match the operational package as it is, because of the type PromptT)... The project page http://projects.haskell.org/operational/ links to documentation that describes the differences to The Operational Monad Tutorial, in particular the new Prompt and PromptT types. It also links to several examples. Two small examples are also included in the Haddock documentation. I'd like to make it very accessible, so please don't hesitate to report any difficulties with finding and understanding documentation and examples! 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 mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Fwd: [Haskell-cafe] Re: Simple game: a monad for each player
Okay, I start to understand better... Just, Heinrich, how would implement the mapMonad function in terms of the operational package? You just shown the signature. 2010/4/14 Bertram Felgenhauer bertram.felgenha...@googlemail.com Limestraėl wrote: Okay, I just understood that 'Prompt' was just a sort of view for 'Program'. Right. runMyStackT :: MyStackT (Player m) a - Player m a According to what Bertram said, each strategy can pile its own custom monad stack ON the (Player m) monad. Yes, and I meant what Heinrich wrote, you wrap some transformer around the common Player m monad. game :: Monad m = Player m () - Player m () - m () As it is written, it requires both players to run in the SAME monad. And if have a network player ( e.g.* Player (StateT Handle IO)* ) and an AI storing former opponent's moves ( e.g. *(Monad m) = Player (StateT [Move] m)* ), then they can't be in the same monad... The idea is to pick m = IO, and then use type NetPlayer a = StateT Handle (Player IO) a and type AIPlayer a = StateT [Move] (Player IO) a or possibly type AIPlayer a = StateT [Move] (Player Identity) a using the mapPlayerM (or mapMonad as suggested by Heinrich) function. You'd then provide functions like runAIPlayer :: AIPlayer a - Player IO a runAIPlayer player = {- mapMonad (return . runIdentity) $ -} evalStateT player [] This gives you most of what you want: You can add custom state and the like to each player. You can not hope to exchange the base monad m, because then the 'game' function would have to know how to run both of those base monads simultaneously. A function like mapMonad is the best device you can hope for, I think. regards, Bertram ___ 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] ANN: Dungeons of Wor - a largish FRP example and a fun game, all in one!
Seems like today FRP is the last word in game programming with Haskell. Do you know something that could be a good tutorial, or at least introduction to FRP ? Something that could somewhat help me learn the ropes, 'cause I'm afraid if I dive directly into your code I'm gonna be lost. Good job, by the way. Yves Parès Felipe Lessa wrote: On Sat, Feb 13, 2010 at 09:49:53PM +0100, Henk-Jan van Tuyl wrote: I tried it, but after briefly displaying a window, the program terminates with the message: dow: user error (unknown OpenGL extension entry glTexParameteri, check for OpenGL 3.1) I suppose the program needs a newer version than is supplied with Windows (opengl.org states that Microsoft always includes an old version of OpenGL [1]) Does anybody know how to deal with this? Just a thought: maybe it is something else. That function appears to exist since Windows 95 according msdn[1] and OpenGL 1.1[2]. [1] http://msdn.microsoft.com/en-us/library/dd368641(VS.85).aspx [2] http://www.talisman.org/opengl-1.1/Reference/glTexParameter.html HTH, -- Felipe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- View this message in context: http://old.nabble.com/ANN%3A-Dungeons-of-Wor---a-largish-FRP-example-and-a-fun-game%2C-all-in-one%21-tp27543827p27579234.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Eventually, I think using cabal during development may be convenient. The only drawback is that you have to specify each dependency and -- above all -- every module each time you add one. Nevertheless, I'm not convinced regarding the use of Makefiles with Cabal. I happen to think it's a bit outsize. A shell script is enough. By the way, I've found another way to develop simultaneously a (or many) library(ies) and an executable. It would be to use a local ghc package database. In my project directory, I do: ghc-pky init pkg.conf.d It create a directory pkg.conf.d which will contain my local database. Then all the libs must be configured with: cabal configure --package-db pkg.conf.d (or 'runhaskell Setup.hs configure --package-db pkg.conf.d' if you don't use cabal-install) Then build normally ('cabal build') Then, the little trouble is that you have to register you newly-built manually with a: cabal register --inplace (Anyone knows how to tell cabal to register automatically to the local pkg database?) Then, to compile you executable with ghc (because Cabal is definitely not convient when you have a lib and an executable in the same package): ghc --make --package-conf pkg.conf.d main.hs Again, should you have better/simpler ways to achieve this, I would be glad to know them. Simon Michael wrote: Another great thread. I'm another who uses both make and cabal. I try to automate a lot of things and find a makefile easier for quick scripting. Perhaps at some point I'll get by with just cabal. Here's an example: http://joyful.com/repos/hledger/Makefile An unusual feature, I think, is the use of the little-known sp tool for auto-recompiling (see ci rule). Typically I leave make ci running in an emacs shell window, where I can watch the errors as I edit and save source. I don't have clickable errors currently, I get by with linum-mode. When I need to explore I'll run ghci in another shell window. After reading this thread, I'm going to try using C-c C-l more. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27544307.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Neil Brown-7 wrote: Don't you simply need to do what the error message says, and add (*in the Executable section*, at the end of the file): Nope, just check my previous message (my issue (2)): Limestrael wrote: (2) well, then, when building, if I don't specify that my executable depends on my lib, I got: SFML/Direct/Graphics.hs:51:7: Could not find module `SFML.Direct.Types.Enums': It is a member of the hidden package `HSFML-1.5'. Perhaps you need to add `HSFML' to the build-depends in your .cabal file. it is a hidden module in the package `HSFML-1.5' Use -v to see a list of the files searched for. and if I do what it asks me to do (to add the line 'Build-Depends: HSFML' in the 'Executable' section of my .cabal file), I'm told when 'cabal build'ing: cabal: internal error: could not construct a valid install plan. The proposed (invalid) plan contained the following problems: The following packages are involved in a dependency cycle HSFML-1.5 -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27534455.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Using Cabal during development
Cabal/cabal-install are good tools for distribution and installation, but I was wondering -- as I was starting to learn how to use Cabal -- how do usually Haskell developpers build their softwares (and especially medium or big libraries) while they are still developping them ? With cabal-install, by doing one 'cabal configure' once and 'cabal build' each time they have altered their code ? With only Cabal, through some 'runhaskell Setup.hs build's ? The point is that I am currently writing a binding for an SDL-like library called SFML. My project is now 55-file wide (and I will have to add some more), uses hsc2hs and has a little executable (for testing purposes) in which I add some code each time I add functionnalities to my binding. What I mean is that it would be a pain to have to compile it by hand whenever I add something to my code. Currently, I compile it by using a simple shell script, but it's a little bit lousy, I think. -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27515446.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
(This is a same message, but with newlines. Sorry for the double post) Cabal/cabal-install are good tools for distribution and installation, but I was wondering -- as I was starting to learn how to use Cabal -- how do usually Haskell developpers build their softwares (and especially medium or big libraries) while they are still developping them ? With cabal-install, by doing one 'cabal configure' once and 'cabal build' each time they have altered their code ? With only Cabal, through some 'runhaskell Setup.hs build's ? The point is that I am currently writing a binding for an SDL-like library called SFML. My project is now 55-file wide (and I will have to add some more), uses hsc2hs and has a little executable (for testing purposes) in which I add some code each time I add functionnalities to my binding. What I mean is that it would be a pain to have to compile it by hand whenever I add something to my code. Currently, I compile it by using a simple shell script, but it's a little bit lousy, I think. -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27515487.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Okay, so then I have so troubles regarding the compilation of my executable: First, what do you think is the simpler : (1) build only the library through cabal-install and then the executable with ghc (it isn't to be distributed with the lib), or (2) add both to my http://old.nabble.com/file/p27515830/HSFML.cabal .cabal file and build them in the same time with a 'cabal build' ? Because I've tried both methods, and have had issues with both : (1) after a 'cabal build', ghc doesn't know where to find my library -- whereas cabal-install displays 'Registering HSFL-1.5...' at the end of the build -- when I do 'ghc --make main.hs'. I'm not gonna do a 'cabal install' whenever I alter my code, am I? (2) well, then, when building, if I don't specify that my executable depends on my lib, I got: SFML/Direct/Graphics.hs:51:7: Could not find module `SFML.Direct.Types.Enums': It is a member of the hidden package `HSFML-1.5'. Perhaps you need to add `HSFML' to the build-depends in your .cabal file. it is a hidden module in the package `HSFML-1.5' Use -v to see a list of the files searched for. and if I do what I asks me to add (I add the line 'Build-Depends: HSFML' in the 'Executable' section of my .cabal file), I'm told when 'cabal build'ing: cabal: internal error: could not construct a valid install plan. The proposed (invalid) plan contained the following problems: The following packages are involved in a dependency cycle HSFML-1.5 Miguel Mitrofanov wrote: With cabal-install, usually. -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27515830.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Okay, I juste solved issue (1) : The package compiled through Cabal has its information stored in the dist/package.conf.inplace file. I can then compile my main by doing : ghc --make -package-conf dist/package.conf.inplace main.hs I just don't know if it's really the way I'm supposed to do this. Nevertheless, issue (2) remains... Limestraël wrote: Okay, so then I have some troubles regarding the compilation of my executable: First, what do you think is the simpler : (1) build only the library through cabal-install and then the executable with ghc (it isn't to be distributed with the lib), or (2) add both to my http://old.nabble.com/file/p27515830/HSFML.cabal .cabal file and build them in the same time with a 'cabal build' ? Because I've tried both methods, and have had issues with both : (1) after a 'cabal build', ghc doesn't know where to find my library -- whereas cabal-install displays 'Registering HSFL-1.5...' at the end of the build -- when I do 'ghc --make main.hs'. I'm not gonna do a 'cabal install' whenever I alter my code, am I? (2) well, then, when building, if I don't specify that my executable depends on my lib, I got: SFML/Direct/Graphics.hs:51:7: Could not find module `SFML.Direct.Types.Enums': It is a member of the hidden package `HSFML-1.5'. Perhaps you need to add `HSFML' to the build-depends in your .cabal file. it is a hidden module in the package `HSFML-1.5' Use -v to see a list of the files searched for. and if I do what it asks me to do (to add the line 'Build-Depends: HSFML' in the 'Executable' section of my .cabal file), I'm told when 'cabal build'ing: cabal: internal error: could not construct a valid install plan. The proposed (invalid) plan contained the following problems: The following packages are involved in a dependency cycle HSFML-1.5 Miguel Mitrofanov wrote: With cabal-install, usually. -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27516610.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Okay, but have you ever felt the need to make in the same project a library and an executable which depends on this library (even just like me, for testing purpose)? How would you do it? Jason Dusek wrote: My development environment is a Screen with Bash, Vim and GHCi running. If I can just load the files in GHCi or compile them with GHC without specifying many options or extensions, then I just do it that way. As soon as I feel a need to write a Makefile or a little build script, I write a Cabal file instead and switch to using `cabal-install'. When I say many options or extensions, I nearly mean any. Most projects of mine get a Cabal file at the point where I feel the need for the first `LANGUAGE' pragma. (I usually omit `LANGUAGE' pragmas, delegating to Cabal for that. I'm not sure whether this is good or bad practice.) -- Jason Dusek ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27518960.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
Then how does the 'Executable' section of your .cabal look like? That's what I can't get working. Jonathan Daugherty-4 wrote: The first thing I always do is create a skeletal cabal file for my project and add Library and Executable sections to it. The executable might be a test/demo program, or it might be a real app. I usually try to put whatever I can into a library to keep my executable source lightweight. -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27520110.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Using Cabal during development
I think I must be dumb or something. I did my SFML.cabal exactly the way the packager of vty-ui did vty-ui.cabal, and I still have got the error when building: hs_src/SFML/Direct/Graphics.hs:51:7: Could not find module `SFML.Direct.Types.Enums': It is a member of the hidden package `SFML-1.5'. Perhaps you need to add `SFML' to the build-depends in your .cabal file. it is a hidden module in the package `SFML-1.5' Use -v to see a list of the files searched for. My cabal file is http://old.nabble.com/file/p27522604/SFML.cabal here . Il you get to know why it doesn't work, please tell me, because I'm lost... I have a hs_src directory, which contains an SFML directory (the lib) and a demo.hs file. (the simple main) It's the way vty-ui package is done. Jonathan Daugherty-4 wrote: Then how does the 'Executable' section of your .cabal look like? That's what I can't get working. Executable vty-ui-demo Hs-Source-Dirs: src Main-is: Demo.hs Build-Depends: mtl = 1.1 1.2 The Main-is refers to src/Demo.hs. This example is from: http://hackage.haskell.org/packages/archive/vty-ui/0.2/vty-ui.cabal The package description link on any Hackage package page will link to the release's cabal file, so you can see how other folks have written their Executable sections. Hope that helps, -- Jonathan Daugherty ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- View this message in context: http://old.nabble.com/Using-Cabal-during-development-tp27515446p27522604.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe