[Haskell-cafe] indentation with let and do
Hi the list, why do this function doesn't compile (parse error): test :: Bool - IO () test foo = do let bar = case foo of True - Foo; False - Bar return () while this one does (just adding one space in front of True and False): test :: Bool - IO () test foo = do let bar = case foo of True - Foo; False - Bar return () Thanks!! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] indentation with let and do
Thanks to all for your replies! I asked the question because I often make this kind of transformations (please don't mind the non-sensical example): test :: Bool - IO () test foo = do bar - case foo of True - return Foo False - return Bar return () into test :: Bool - IO () test foo = do let bar = case foo of True - Foo False - Bar return () And was wondering why can't I maintain the initial (and nicer) indentation. But since let allows for several bindings, it make sense... Best, Corentin On Thu, Oct 3, 2013 at 8:31 PM, Corentin Dupont corentin.dup...@gmail.comwrote: test :: Bool - IO () test foo = do let bar = case foo of True - Foo; False - Bar return () ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.3 beta, the game where you can change the rules
There is not so much people in the game right now (only 3) and a little more watching (20). Don't be shy and join! On Thu, Oct 3, 2013 at 1:14 AM, Corentin Dupont corentin.dup...@gmail.comwrote: Hello everybody! I released the third beta of Nomyx http://www.nomyx.net, the only game where You can change the rules! The second beta was a success. Great players (byorgey, nomeata, Toxaris...) proposed amazing rules, effectively building a nice universe. For example, a banking system in ecu was proposed, with cash monies and even a way to buy pies! Other rules like different democratic systems were proposed. You can check those rules in this thread: http://www.nomyx.net/forum/viewtopic.php?f=4t=1520 Let's start a new game! I propose to set it in the medieval era. Dear rulers, I'll let your imagination speak! Please login to the game here: www.nomyx.net:8000/Nomyx. The corresponding forum thread is here: http://www.nomyx.net/forum/viewtopic.php?f=4t=1523 Some background: this is an implementation of a Nomic [2] game in Haskell(I believe the first complete implementation of a Nomic game on a computer). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language http://hackage.haskell.org/package/Nomyx-Language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The example file gives a lot of examples of rules that you can submit: www.nomyx.net:8000/src/Language/Nomyx/Examples.hs changes in V0.3: - creation of admin role - inputs made by the rules now include checkboxes, buttons, textarea - outputs made by the rules are now managed (create, update, delete) - refactored the GUI - bumped to GHC 7.6 - compilation errors are displayed in context - bug fixes Cheers, Corentin [1] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANN: Nomyx 0.3 beta, the game where you can change the rules
Hello everybody! I released the third beta of Nomyx http://www.nomyx.net, the only game where You can change the rules! The second beta was a success. Great players (byorgey, nomeata, Toxaris...) proposed amazing rules, effectively building a nice universe. For example, a banking system in ecu was proposed, with cash monies and even a way to buy pies! Other rules like different democratic systems were proposed. You can check those rules in this thread: http://www.nomyx.net/forum/viewtopic.php?f=4t=1520 Let's start a new game! I propose to set it in the medieval era. Dear rulers, I'll let your imagination speak! Please login to the game here: www. nomyx.net:8000/Nomyx. The corresponding forum thread is here: http://www.nomyx.net/forum/viewtopic.php?f=4t=1523 Some background: this is an implementation of a Nomic [2] game in Haskell(I believe the first complete implementation of a Nomic game on a computer). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language http://hackage.haskell.org/package/Nomyx-Language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The example file gives a lot of examples of rules that you can submit: www. nomyx.net:8000/src/Language/Nomyx/Examples.hs changes in V0.3: - creation of admin role - inputs made by the rules now include checkboxes, buttons, textarea - outputs made by the rules are now managed (create, update, delete) - refactored the GUI - bumped to GHC 7.6 - compilation errors are displayed in context - bug fixes Cheers, Corentin [1] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: MVar problem in acid-state?
OK, my mistake: it's working now. It was because I'm using an haskell interpreter in my program, and the version of GHC was different on my PC (where I compile) and on the server (where I run)... On Tue, Sep 3, 2013 at 11:13 AM, Dag Odenhall dag.odenh...@gmail.comwrote: It's conceivable. It might help if you list what version of acid-stateyou're using and what parts of it. And maybe file a bug https://github.com/acid-state/acid-state/issues upstream even if you're not sure it is acid-state. On Mon, Sep 2, 2013 at 7:35 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi the list, I have compiled my application on my PC, it works fine, but when I copy it on my server (same architecture), I get: Nomyx: thread blocked indefinitely in an MVar operation I don't use MVars in my application, is it possible that it's coming from acid-state? Thanks, Corentin ___ 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] Fwd: MVar problem in acid-state?
Hi the list, I have compiled my application on my PC, it works fine, but when I copy it on my server (same architecture), I get: Nomyx: thread blocked indefinitely in an MVar operation I don't use MVars in my application, is it possible that it's coming from acid-state? Thanks, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.2 beta, the game where you can change the rules
Thanks Brent! I'm glad you like it. You will win a lot of money if new players come :) Indeed Brent proposed a rule that allows sponsorship: if you invite a player in, you win 50 ECU... The game is still in beta-phase, so expect bugs... There is some learning material in the links in my mail under (see the forum). Best, Corentin** On Wed, Jun 19, 2013 at 1:01 PM, Brent Yorgey byor...@seas.upenn.eduwrote: This is great fun, more people should come and join us! =) http://www.nomyx.net:8000/Nomyx we are playing game demo3. -Brent On Fri, Jun 14, 2013 at 05:57:57PM +0200, Corentin Dupont wrote: Hello everybody! Here it comes, the second beta release [1] of Nomyx, the only game where You can change the rules!! This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation of a Nomic game on a computer). In a Nomyxgame you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum The example file gives a lot of examples of rules that you can submit: www.nomyx.net:8000/src/Language/Nomyx/Examples.hs Changes from V0.1: - new login system: you can now login with your Google, Yahoo, Live Journal, Myspace, OpenId or Facebook accounts (thanks to happstack-authenticate)! - new DSL for voting (see below) - styling: rule code colorized, better settings and help - use cookies to store the user ID (as suggested on this mailing list) - new error system to handle exceptions in rules (with ErrorT) - use lenses I set up a little DSL to create elections (elect one of the players for a special role) or referendums (a yes/no question). You create in one line within Nomyx an vote with unanimity or majority, a quorum and different ballot systems. See here: http://www.nomyx.net/forum/viewtopic.php?f=3t=1518 Let's test it! If you are interested, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?f=4t=1517 The demo game is running here: www.nomyx.net:8000/Nomyx then select game demo2. As the first player of the game, I changed the initial unanimity vote to a simple majority, with a minimum of 2 players voting. Having your new rules accepted will be easy! Let's see who will win :) Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] hand over maintenance of a package
Hi Cafe, How to hand over the maintenance of a hackage package? Thanks Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.2 beta, the game where you can change the rules
Thanks Tobias, I'm looking forward to see you in the game! I'll try to fix the text/plain part of the mails. I had quite some problems with the haskell command *simpleMail* some time ago. Best, Corentin On Wed, Jun 19, 2013 at 3:48 PM, Tobias Dammers tdamm...@gmail.com wrote: On Wed, Jun 19, 2013 at 01:18:54PM +0200, Corentin Dupont wrote: Thanks Brent! I'm glad you like it. You will win a lot of money if new players come :) Indeed Brent proposed a rule that allows sponsorship: if you invite a player in, you win 50 ECU... Joined a game, though I don't really have time to look into it right now. One thing though: It appears that the game sends multipart/alternative e-mail messages, where the text/plain part is completely empty (0 bytes). Since I've configured my mail client to prefer text/plain over text/html, this is kind of inconvenient. Otherwise, good job. I'm curious where this is going. ___ 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] ANN: Nomyx 0.2 beta, the game where you can change the rules
Hello everybody! Here it comes, the second beta release [1] of Nomyx, the only game where You can change the rules!! This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation of a Nomic game on a computer). In a Nomyxgame you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum The example file gives a lot of examples of rules that you can submit: www.nomyx.net:8000/src/Language/Nomyx/Examples.hs Changes from V0.1: - new login system: you can now login with your Google, Yahoo, Live Journal, Myspace, OpenId or Facebook accounts (thanks to happstack-authenticate)! - new DSL for voting (see below) - styling: rule code colorized, better settings and help - use cookies to store the user ID (as suggested on this mailing list) - new error system to handle exceptions in rules (with ErrorT) - use lenses I set up a little DSL to create elections (elect one of the players for a special role) or referendums (a yes/no question). You create in one line within Nomyx an vote with unanimity or majority, a quorum and different ballot systems. See here: http://www.nomyx.net/forum/viewtopic.php?f=3t=1518 Let's test it! If you are interested, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?f=4t=1517 The demo game is running here: www.nomyx.net:8000/Nomyx then select game demo2. As the first player of the game, I changed the initial unanimity vote to a simple majority, with a minimum of 2 players voting. Having your new rules accepted will be easy! Let's see who will win :) Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] voting sytem DSL
Hi haskellers! I am trying to make a DSL able to describe a voting system. That DSL should be able to describe many different voting procedures: unanimity or majority, open or secret ballot, one or two turns... It should also work for referendums (yes/no question) or elections (electing one or several people)... Are you aware of any such DSL? In Haskell I haven't see it, maybe in another language? Cheers, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] code to HTML
Hello everybody, I'd like to transform a .hs file into a .html file. The objective is that the .html file, when rendered, looks exactly the same that the .hs, with the exeption that every function in the code is a link to its haddock documentation. Is that possible? The result would look like that: f xs = maphttp://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:map headhttp://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:headxs Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Display an inferred type during compilation
Thanks all for your solutions! Here is a summary: - floating a value to the top level; then with -Wall GHC will give the type since we didn't give a value, - adding :: () to the value to check, GHC will complain equally, - using TemplateHaskell (hereunder), - waiting for the release of the next GHC with TypeHoles. Corentin On Sat, Apr 27, 2013 at 8:46 PM, Ilya Portnov port...@iportnov.ru wrote: ** В письме от 27 апреля 2013 18:55:16 пользователь Corentin Dupont написал: Hi Cafe, can I ask the compiler to display the type of an inferred value during compile time? It would be great if I can output a string during compilation with the type. A little bit like running :type in GHCi, but without GHCi... Because running GHCi is sometime painful (I have to clean my code first). I'm thinking of something like: main :: IO () main = do a - someCode displayTypeAtCompileTime a return () $ ghc -c test.hs test.hs:4:3: your type is: Foo Thanks, Corentin Hi. What about TemplateHaskell? Smth like: {-# LANGUAGE TemplateHaskell #-} module DisplayType where import Language.TH displayTypeAtCompileTime :: Name - Q Exp displayTypeAtComileTime name = do reified - reify name -- inspect reified structure, see TH haddock documentation runIO $ putStrLn $ show theType [| undefined |] -- you need to return some expression; since you are not to use it's value, it may be even undefined, it seems. ### {-# LANGUAGE TemplateHaskell #-} module Main where import DisplayType main = do ... $displayTypeAtCompileTime 'a ... WBR, Ilya Portnov. ___ 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] Display an inferred type during compilation
Hi Cafe, can I ask the compiler to display the type of an inferred value during compile time? It would be great if I can output a string during compilation with the type. A little bit like running :type in GHCi, but without GHCi... Because running GHCi is sometime painful (I have to clean my code first). I'm thinking of something like: main :: IO () main = do a - someCode displayTypeAtCompileTime a return () $ ghc -c test.hs test.hs:4:3: your type is: Foo Thanks, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Remove redundancy with Template Haskell
Thanks Daniel, that's very simple! Realizing this in TH seems be impossible, is it right? On Wed, Mar 27, 2013 at 10:33 PM, Daniel Trstenjak daniel.trsten...@gmail.com wrote: Hi Corentin, On Wed, Mar 27, 2013 at 09:13:41PM +0100, Corentin Dupont wrote: I have a function that looks like this: call :: SomeFunction - String - SomeState The string is actually the representation of the function passed in parameter. It is stored in the state for documentation. So a call looks like that: call (\a - putStrLn a) \a - putStrLn a There is a clear redundancy here, how could I remove it with Template Haskell? I cannot figure out... You can even use cpp to get something like: #define CALL(func) call (func) #func CALL(\a - a + 1) = call (\a - a + 1) \a - a + 1 Greetings, Daniel ___ 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] Remove redundancy with Template Haskell
Hi Café, I have a function that looks like this: call :: SomeFunction - String - SomeState The string is actually the representation of the function passed in parameter. It is stored in the state for documentation. So a call looks like that: call (\a - putStrLn a) \a - putStrLn a There is a clear redundancy here, how could I remove it with Template Haskell? I cannot figure out... Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Make a DSL serializable
What do you mean by monoid? It's not clear to me how a state (essentially a structure with many fields) can be a monoid... I figured out that the Writer monad may be good for that purpose. On Mon, Mar 25, 2013 at 1:50 AM, Alberto G. Corona agocor...@gmail.comwrote: That is the advantage of recording the sequence of events instead of the final state: that the state don´t need to be seriallizable. And this indeed the way to serlize something that can be decomposed in events. I think that this is elegant.. Specially if the events and the state are elements of a Monoid instance. 2013/3/24 Corentin Dupont corentin.dup...@gmail.com Hi Brandon, in fact, that's what I'm doing. I record the list of actions performed by the players, including the submission of the code. I serialize this list of actions instead of the state of the game. When deserializing, I replay all the players actions from scratch to get back to the same state than before. This is the only way to do it (replaying from scratch), since the pieces of code submitted can interact with other pieces of code submitted earlier: they are not independant. But I always bothered me that this state is not serializable... On Sun, Mar 24, 2013 at 10:02 PM, Brandon Allbery allber...@gmail.comwrote: On Sun, Mar 24, 2013 at 4:16 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi Daniel, in my game the handlers are supplied by the players as part of little programs that they submit. An haskell interpreter is reading the program code submitted and inserts it in the game. So there is an infinite number of handlers... You might store both the compiled code and the originally submitted code, and serialize the latter in a form that restart can recompile. I don't think that can be any less safe than the original submission/compilation/insertion. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Alberto. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Make a DSL serializable
Workflow is impressive! I didn't know you could serialize IO states/computations. On Mon, Mar 25, 2013 at 2:06 AM, Alberto G. Corona agocor...@gmail.comwrote: the package Workflow serialize also the state of a computation, so it can be re-started and continued. It uses also the above mentioned event trick to serialize the state. By the way you can use the workflow monad transformer to recover the state of the game. You don´t need to serialize anything explicitly, the transformer will do it, but your step results must be serializable. If you have this code: loop= do eventhandlercode - receive handler - compile eventhandlercode execute handler loop then the lifted process in the workflow monad would be: loop=do eventhandlercode - step receive handler - liftIO $ compile eventhandlercode liftIO $ execute handler loop step will store the result and will recover the execution state. Only the step result should be serializable. 2013/3/24 Corentin Dupont corentin.dup...@gmail.com I also came across Scala's Swarm, making use serializable delimited continuations. Looks good! http://www.scala-lang.org/node/3485 On Sun, Mar 24, 2013 at 11:13 PM, Michael Better mbet...@gmail.comwrote: Isn't this similar to the problem Cloud Haskell had to solve to send code to another process to run? Mike On Mar 24, 2013 5:06 PM, Brandon Allbery allber...@gmail.com wrote: On Sun, Mar 24, 2013 at 5:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: But I always bothered me that this state is not serializable... I am not quite sure how to respond to that. You seem to be asking for magic. That kind of state has never been sanely serializeable. Not in Haskell, not anywhere else. The usual hack is to dump an entire memory image to disk, either as an executable (see gcore and undump; also see how the GNU emacs build dumps a preloaded emacs executable) or by dumping the data segment as raw bytes and reloading it as such (which doesn't work so well in modern demand paged executables; it can work better with a virtual machine environment, and various Lisp and Smalltalk implementations dump and reload their raw VM images this way). I would not be surprised if what you seem to be asking for turns out to be yet another guise of the halting problem. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.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 -- Alberto. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Make a DSL serializable
Hi Café, I have a DSL like this: data Exp where OnEvent :: EventName - (Int - Exp) - Exp (...) The OnEvent element carries a function (the handler to be called when the event happens), and that makes my DSL non showable/serializable. How could I fix that? This is a real handicap not to be able to serialize the state of my whole application because of that :) Thanks, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Make a DSL serializable
Hi Daniel, in my game the handlers are supplied by the players as part of little programs that they submit. An haskell interpreter is reading the program code submitted and inserts it in the game. So there is an infinite number of handlers... I was thinking of hiding the parameters of the handlers like this: data Exp a where OnEvent :: EventName - Exp () - Exp () getArg :: Exp Int setArg :: Exp () deriving (Show) Now it should be possible to write the Show instance: instance Show a - Show (Exp a) where ... You could write a program like this: myProgram :: Exp () myProgram = do OnEvent NewPlayer (getArg = (\name - output $ Hello to player ++ name)) But I don't find it elegant at all: there is no compile time guaranty that the caller will set the argument correctly as you can have with normal function signatures... Best, Corentin On Sun, Mar 24, 2013 at 6:25 PM, Daniel Trstenjak daniel.trsten...@gmail.com wrote: Hi Corentin, I have a DSL like this: data Exp where OnEvent :: EventName - (Int - Exp) - Exp (...) The OnEvent element carries a function (the handler to be called when the event happens), and that makes my DSL non showable/serializable. How could I fix that? This is a real handicap not to be able to serialize the state of my whole application because of that :) You could have a unique id for your handlers, which might be an Int or a String and have some kind of registration for the handlers. data Exp where OnEvent :: EventName - HandlerId - Exp type HandlerId = String type Handler = (Int - Exp) type Handlers = HashMap HandlerId Handler registerHandler :: Handlers - (HandlerId, Handler) - Handlers getHandler :: Handlers - HandlerId - Maybe Handler But you have to ensure, that for each application run the same HandlerId also gets the same Handler. Less flexible but more secure is an ADT for you Handler. data Handler = DoThat | DoSometingElse You can than just pattern match on your handler and don't need any kind of registration. But you can go further and define your own little Handler DSL. Greetings, Daniel ___ 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] Make a DSL serializable
Hi Brandon, in fact, that's what I'm doing. I record the list of actions performed by the players, including the submission of the code. I serialize this list of actions instead of the state of the game. When deserializing, I replay all the players actions from scratch to get back to the same state than before. This is the only way to do it (replaying from scratch), since the pieces of code submitted can interact with other pieces of code submitted earlier: they are not independant. But I always bothered me that this state is not serializable... On Sun, Mar 24, 2013 at 10:02 PM, Brandon Allbery allber...@gmail.comwrote: On Sun, Mar 24, 2013 at 4:16 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi Daniel, in my game the handlers are supplied by the players as part of little programs that they submit. An haskell interpreter is reading the program code submitted and inserts it in the game. So there is an infinite number of handlers... You might store both the compiled code and the originally submitted code, and serialize the latter in a form that restart can recompile. I don't think that can be any less safe than the original submission/compilation/insertion. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Make a DSL serializable
I also came across Scala's Swarm, making use serializable delimited continuations. Looks good! http://www.scala-lang.org/node/3485 On Sun, Mar 24, 2013 at 11:13 PM, Michael Better mbet...@gmail.com wrote: Isn't this similar to the problem Cloud Haskell had to solve to send code to another process to run? Mike On Mar 24, 2013 5:06 PM, Brandon Allbery allber...@gmail.com wrote: On Sun, Mar 24, 2013 at 5:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: But I always bothered me that this state is not serializable... I am not quite sure how to respond to that. You seem to be asking for magic. That kind of state has never been sanely serializeable. Not in Haskell, not anywhere else. The usual hack is to dump an entire memory image to disk, either as an executable (see gcore and undump; also see how the GNU emacs build dumps a preloaded emacs executable) or by dumping the data segment as raw bytes and reloading it as such (which doesn't work so well in modern demand paged executables; it can work better with a virtual machine environment, and various Lisp and Smalltalk implementations dump and reload their raw VM images this way). I would not be surprised if what you seem to be asking for turns out to be yet another guise of the halting problem. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.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] Make a DSL serializable
On Sun, Mar 24, 2013 at 11:05 PM, Brandon Allbery allber...@gmail.comwrote: On Sun, Mar 24, 2013 at 5:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: But I always bothered me that this state is not serializable... I am not quite sure how to respond to that. You seem to be asking for magic. haha as always :) But Haskell is a bit about magic... That kind of state has never been sanely serializeable. Not in Haskell, not anywhere else. The usual hack is to dump an entire memory image to disk, either as an executable (see gcore and undump; also see how the GNU emacs build dumps a preloaded emacs executable) or by dumping the data segment as raw bytes and reloading it as such (which doesn't work so well in modern demand paged executables; it can work better with a virtual machine environment, and various Lisp and Smalltalk implementations dump and reload their raw VM images this way). I would not be surprised if what you seem to be asking for turns out to be yet another guise of the halting problem. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Extracting exposed modules from an installed library
Hi Joachim, that's right thanks, but I was looking for a way to do that from a program. ghc-pkg does not seems to expose any library... On Wed, Mar 20, 2013 at 11:23 PM, Joachim Breitner m...@joachim-breitner.de wrote: Hi, Am Mittwoch, den 20.03.2013, 00:34 +0100 schrieb Corentin Dupont: Hi Cafe! I'm looking for how to extract the exposed modules (as a list of strings) from an installed library, giving the library name. I can see some structures in Cabal (InstalledPackageInfo) and some functions in ghc-pkg.hs in GHC, but nothing readily useable... $ ghc-pkg field base exposed-modules exposed-modules: Foreign.Concurrent GHC.Arr GHC.Base GHC.Char GHC.Conc GHC.Conc.IO GHC.Conc.Signal GHC.Conc.Sync GHC.ConsoleHandler GHC.Constants GHC.Desugar GHC.Enum GHC.Environment GHC.Err GHC.Exception GHC.Exts GHC.Fingerprint GHC.Fingerprint.Type GHC.Float GHC.Float.ConversionUtils GHC.Float.RealFracMethods GHC.Foreign GHC.ForeignPtr GHC.Generics GHC.GHCi GHC.Handle GHC.IO GHC.IO.Buffer GHC.IO.BufferedIO GHC.IO.Device GHC.IO.Encoding GHC.IO.Encoding.CodePage GHC.IO.Encoding.Failure GHC.IO.Encoding.Iconv GHC.IO.Encoding.Latin1 GHC.IO.Encoding.Types GHC.IO.Encoding.UTF16 GHC.IO.Encoding.UTF32 GHC.IO.Encoding.UTF8 GHC.IO.Exception GHC.IO.FD GHC.IO.Handle GHC.IO.Handle.FD GHC.IO.Handle.Internals GHC.IO.Handle.Text GHC.IO.Handle.Types GHC.IO.IOMode GHC.IOArray GHC.IOBase GHC.IORef GHC.IP GHC.Int GHC.List GHC.MVar GHC.Num GHC.PArr GHC.Pack GHC.Ptr GHC.Read GHC.Real GHC.STGHC.Stack GHC.Stats GHC.Show GHC.Stable GHC.Storable GHC.STRef GHC.TypeLits GHC.TopHandler GHC.Unicode GHC.Weak GHC.Word System.Timeout GHC.Event Control.Applicative Control.Arrow Control.Category Control.Concurrent Control.Concurrent.Chan Control.Concurrent.MVar Control.Concurrent.QSem Control.Concurrent.QSemN Control.Concurrent.SampleVar Control.Exception Control.Exception.Base Control.Monad Control.Monad.Fix Control.Monad.Instances Control.Monad.STControl.Monad.ST.Safe Control.Monad.ST.Unsafe Control.Monad.ST.Lazy Control.Monad.ST.Lazy.Safe Control.Monad.ST.Lazy.Unsafe Control.Monad.ST.Strict Control.Monad.Zip Data.Bits Data.Bool Data.Char Data.Complex Data.Dynamic Data.Either Data.Eq Data.Data Data.Fixed Data.Foldable Data.Function Data.Functor Data.HashTable Data.IORef Data.Int Data.Ix Data.List Data.Maybe Data.Monoid Data.Ord Data.Ratio Data.STRef Data.STRef.Lazy Data.STRef.Strict Data.String Data.Traversable Data.Tuple Data.Typeable Data.Typeable.Internal Data.Unique Data.Version Data.Word Debug.Trace Foreign Foreign.C Foreign.C.Error Foreign.C.String Foreign.C.Types Foreign.ForeignPtr Foreign.ForeignPtr.Safe Foreign.ForeignPtr.Unsafe Foreign.Marshal Foreign.Marshal.Alloc Foreign.Marshal.Array Foreign.Marshal.Error Foreign.Marshal.Pool Foreign.Marshal.Safe Foreign.Marshal.Utils Foreign.Marshal.Unsafe Foreign.Ptr Foreign.Safe Foreign.StablePtr Foreign.Storable Numeric Prelude System.Console.GetOpt System.CPUTime System.Environment System.Exit System.IO System.IO.Error System.IO.Unsafe System.Info System.Mem System.Mem.StableName System.Mem.Weak System.Posix.Internals System.Posix.Types Text.ParserCombinators.ReadP Text.ParserCombinators.ReadPrec Text.Printf Text.Read Text.Read.Lex Text.Show Text.Show.Functions Unsafe.Coerce Greetings, Joachim -- Joachim nomeata Breitner Debian Developer nome...@debian.org | ICQ# 74513189 | GPG-Keyid: 4743206C JID: nome...@joachim-breitner.de | http://people.debian.org/~nomeata ___ 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] Extracting exposed modules from an installed library
Hi Cafe! I'm looking for how to extract the exposed modules (as a list of strings) from an installed library, giving the library name. I can see some structures in Cabal (InstalledPackageInfo) and some functions in ghc-pkg.hs in GHC, but nothing readily useable... Thanks, Corenti ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
happstack-authenticate looks impressive, they seem to support for Google , Yahoo, Live Journal, Myspace, and OpenId logins! I'll try it. On Fri, Mar 1, 2013 at 5:17 AM, Chris Wong chrisyco+haskell-c...@gmail.comwrote: On Thu, Feb 28, 2013 at 1:26 PM, Brandon Allbery allber...@gmail.com wrote: On Wed, Feb 27, 2013 at 8:37 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi Chris, Thanks! That's true for the user number. What should I do? Encrypt it? It's not that you have a user number, or even that it's accessible: it's that it's the entirety of access control, meaning that if the user changes it they can masquerade as another user. The correct solution is that a user should authenticate, which creates a session hash that you stash away and also send back to the user as a cookie so the browser will present it on accesses. Then you check that the presented hash is there and matches the session hash. These should expire periodically, requiring the user to log back in again. Brandon pretty much pulled the words out of my mouth, but I have one last thing to add: no matter how well you encrypt the information, as long as it's in the URL it's insecure. Hypothetical situation #1: if there's someone looking over your shoulder, they can just note down the address -- it is in plain view, after all. Even more likely: your friend wants to watch the game, so you send her the link. Unfortunately, you forget to delete your session information from the URL. Now your friend (conveniently named Eve) has hijacked your account and is voting on your behalf. The Ruby on Rails website has an excellent explanation of common security holes [1]. The article is Rails-centric, but most of it applies to Haskell as well. [1] http://guides.rubyonrails.org/security.html As for libraries, Happstack has happstack-authenticate [2]. I haven't used it myself, but it looks good. [2] http://hackage.haskell.org/package/happstack-authenticate Chris -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
Hi all, with the mutiplayer server, the game was occasionally crashing with: CPU time limit exceeded (core dumped) I think it was due to some ulimit set too low, it should work better now. BR, C On Wed, Feb 27, 2013 at 12:28 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum As this is the first beta release of the game, I'm looking for beta testers :) Although I tested it quite a lot, I'm sure a lot of bugs remains, especially in multiplayer. So if you are interested in testing Nomyx, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?p=5 Comments/contributions are very highly welcome! There is still a lot to do. As for now, the game is not completely securised. It is easy to break it by submitting rules containing malicious code. I'm working on it. If you'd like to do security testing, please do it locally on your own machine and send me a bug report :). Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
I think it would be harder to implement a computer version of 1KBWC and Calvin ball!! Have to think of it ;) On Wed, Feb 27, 2013 at 9:48 AM, Tom Murphy amin...@gmail.com wrote: There's another one... http://3.bp.blogspot.com/-0-NT1rzFpik/Tpe4sb18gOI/AuM/j2BHO_TgLi4/s1600/calvinball.jpg Tom On Tue, Feb 26, 2013 at 7:07 PM, Ben Lippmeier b...@ouroborus.net wrote: On 27/02/2013, at 10:28 , Corentin Dupont corentin.dup...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. Don't forget 1KBWC: http://www.corngolem.com/1kbwc/ Ben. ___ 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: Nomyx 0.1 beta, the game where you can change the rules
Thank you very much, that's very nice! That was a great journey, I started Nomyx 2-3 years ago as a personal project and learned Haskell on the way. I went through many refactorings as my comprehension of Haskell and Nomic progressed. Out of the top of my head, the points that gave me some headaches were: - how to split the program into modules properly without dependency cycles - Happstack big type signatures - having the right structures to pass data in a StateT - using existential types and type families for variables and events - ACID state, this is really not practical during development Cheers, Corentin On Wed, Feb 27, 2013 at 2:17 AM, Alexander Solla alex.so...@gmail.comwrote: On Tue, Feb 26, 2013 at 3:28 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. That's very nice. I've been following your progress on the list. Congratulations! Did you learn as much about Haskell as you hoped? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
Hi Chris, Thanks! That's true for the user number. What should I do? Encrypt it? On Wed, Feb 27, 2013 at 5:02 AM, Chris Wong chrisyco+haskell-c...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. I just gave it a go -- it looks fun :) However, I've spotted a security hole. The current user number is stored in the URL -- if I change that number, I can masquerade as someone else! Is this behavior intended? This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum As this is the first beta release of the game, I'm looking for beta testers :) Although I tested it quite a lot, I'm sure a lot of bugs remains, especially in multiplayer. So if you are interested in testing Nomyx, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?p=5 Comments/contributions are very highly welcome! There is still a lot to do. As for now, the game is not completely securised. It is easy to break it by submitting rules containing malicious code. I'm working on it. If you'd like to do security testing, please do it locally on your own machine and send me a bug report :). Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.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] ANN: Nomyx 0.1 beta, the game where you can change the rules
Yes, having a cookie to keep track of the session if something I plan to do. On Wed, Feb 27, 2013 at 3:16 PM, Mats Rauhala mats.rauh...@gmail.comwrote: The user id is not necessarily the problem, but rather that you can impose as another user. For this, one solution is to keep track of a unique (changing) user token in the cookies and use that for verifying the user. -- Mats Rauhala MasseR -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAlEuFVQACgkQHRg/fChhmVMu3ACeLLjbluDQRYekIA2XY37Xbrql tH0An1eQHrLLxCjHHBQcZKmy1iYxCxTt =tf0d -END PGP SIGNATURE- ___ 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: Nomyx 0.1 beta, the game where you can change the rules
So I need to encrypt the user ID in some way? What I need is to associate the user ID to a random number and store the association is a table? On Wed, Feb 27, 2013 at 3:52 PM, Erik Hesselink hessel...@gmail.com wrote: Note that cookies are not the solution here. Cookies are just as user controlled as the url, just less visible. What you need is a session id: a mapping from a non-consecutive, non-guessable, secret token to the user id (which is sequential and thus guessable, and often exposed in urls etc.). It doesn't matter if you then store it in the url or a cookie. Cookies are just more convenient. Erik On Wed, Feb 27, 2013 at 3:30 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes, having a cookie to keep track of the session if something I plan to do. On Wed, Feb 27, 2013 at 3:16 PM, Mats Rauhala mats.rauh...@gmail.com wrote: The user id is not necessarily the problem, but rather that you can impose as another user. For this, one solution is to keep track of a unique (changing) user token in the cookies and use that for verifying the user. -- Mats Rauhala MasseR -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAlEuFVQACgkQHRg/fChhmVMu3ACeLLjbluDQRYekIA2XY37Xbrql tH0An1eQHrLLxCjHHBQcZKmy1iYxCxTt =tf0d -END PGP SIGNATURE- ___ 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] ANN: Nomyx 0.1 beta, the game where you can change the rules
hash is reversible or not? On Wed, Feb 27, 2013 at 8:18 PM, Clark Gaebel cgae...@uwaterloo.ca wrote: You could just hash it. - Clark On Wed, Feb 27, 2013 at 2:08 PM, Corentin Dupont corentin.dup...@gmail.com wrote: So I need to encrypt the user ID in some way? What I need is to associate the user ID to a random number and store the association is a table? On Wed, Feb 27, 2013 at 3:52 PM, Erik Hesselink hessel...@gmail.comwrote: Note that cookies are not the solution here. Cookies are just as user controlled as the url, just less visible. What you need is a session id: a mapping from a non-consecutive, non-guessable, secret token to the user id (which is sequential and thus guessable, and often exposed in urls etc.). It doesn't matter if you then store it in the url or a cookie. Cookies are just more convenient. Erik On Wed, Feb 27, 2013 at 3:30 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes, having a cookie to keep track of the session if something I plan to do. On Wed, Feb 27, 2013 at 3:16 PM, Mats Rauhala mats.rauh...@gmail.com wrote: The user id is not necessarily the problem, but rather that you can impose as another user. For this, one solution is to keep track of a unique (changing) user token in the cookies and use that for verifying the user. -- Mats Rauhala MasseR -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAlEuFVQACgkQHRg/fChhmVMu3ACeLLjbluDQRYekIA2XY37Xbrql tH0An1eQHrLLxCjHHBQcZKmy1iYxCxTt =tf0d -END PGP SIGNATURE- ___ 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] ANN: Nomyx 0.1 beta, the game where you can change the rules
Hi all, there is quite a lot of players! Fantastic! I proposed a rule to lower the vote quorum from unanimity to a quorum of only 4, for the experimentation. But still, to have this rule accepted, everybody needs to vote! Could you please cast your vote? If you don't plan on playing, it's better to unsubscribe. The players which have submitted their email should have received a notification for this rule. To experiment with the rules, it's better to install Nomyx on your machine (cabal install Nomyx) and play alone, since the voting process can be long in multiplayer (I expect 1 or 2 days to reach the quorum for a rule). I saw people having problem writing the rules (in the log), I'll post some comments on the game's forum: http://www.nomyx.net/forum/viewtopic.php?p=5 not to flood this mailing list ;) Just note that all proposed rules should have type RuleFunc. If you'd like to use GHCI to compose your rule, here's how: $ wget http://hackage.haskell.org/packages/archive/Nomyx-Rules/0.1.0/Nomyx-Rules-0.1.0.tar.gz $ tar -xzvf Nomyx-Rules-0.1.0.tar.gz $ ghci Nomyx-Rules-0.1.0/src/Language/Nomyx/Examples.hs Cheers! Corentin On Wed, Feb 27, 2013 at 12:28 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum As this is the first beta release of the game, I'm looking for beta testers :) Although I tested it quite a lot, I'm sure a lot of bugs remains, especially in multiplayer. So if you are interested in testing Nomyx, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?p=5 Comments/contributions are very highly welcome! There is still a lot to do. As for now, the game is not completely securised. It is easy to break it by submitting rules containing malicious code. I'm working on it. If you'd like to do security testing, please do it locally on your own machine and send me a bug report :). Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
NB: being unsubscribed, you can still watch the game. It's just that you are not anymore considered as a citizen of that game, thus not counted in the votes. On Wed, Feb 27, 2013 at 10:12 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi all, there is quite a lot of players! Fantastic! I proposed a rule to lower the vote quorum from unanimity to a quorum of only 4, for the experimentation. But still, to have this rule accepted, everybody needs to vote! Could you please cast your vote? If you don't plan on playing, it's better to unsubscribe. The players which have submitted their email should have received a notification for this rule. To experiment with the rules, it's better to install Nomyx on your machine (cabal install Nomyx) and play alone, since the voting process can be long in multiplayer (I expect 1 or 2 days to reach the quorum for a rule). I saw people having problem writing the rules (in the log), I'll post some comments on the game's forum: http://www.nomyx.net/forum/viewtopic.php?p=5 not to flood this mailing list ;) Just note that all proposed rules should have type RuleFunc. If you'd like to use GHCI to compose your rule, here's how: $ wget http://hackage.haskell.org/packages/archive/Nomyx-Rules/0.1.0/Nomyx-Rules-0.1.0.tar.gz $ tar -xzvf Nomyx-Rules-0.1.0.tar.gz $ ghci Nomyx-Rules-0.1.0/src/Language/Nomyx/Examples.hs Cheers! Corentin On Wed, Feb 27, 2013 at 12:28 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum As this is the first beta release of the game, I'm looking for beta testers :) Although I tested it quite a lot, I'm sure a lot of bugs remains, especially in multiplayer. So if you are interested in testing Nomyx, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?p=5 Comments/contributions are very highly welcome! There is still a lot to do. As for now, the game is not completely securised. It is easy to break it by submitting rules containing malicious code. I'm working on it. If you'd like to do security testing, please do it locally on your own machine and send me a bug report :). Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
Thanks Ozgun, but I'm using Happstack: this will be compatible? On Wed, Feb 27, 2013 at 10:30 PM, Ozgun Ataman ozata...@gmail.com wrote: I would encourage you to take a look at the snap (the web framework) package, where this concern is handled for you as part of the session snaplet. The Snap.Snaplet.Sessionhttp://hackage.haskell.org/packages/archive/snap/0.11.2/doc/html/Snap-Snaplet-Session.html module and the Snap.Snaplet.Session.Backends.CookieSessionhttp://hackage.haskell.org/packages/archive/snap/0.11.2/doc/html/Snap-Snaplet-Session-Backends-CookieSession.html ensure that contents of the cookie-persistent sessions are encrypted and so you can place anything from user ids to other secret information there, although I would certainly keep it to a minimum for size concerns. Here it is: http://hackage.haskell.org/package/snap Hope this helps, Oz On Wed, Feb 27, 2013 at 2:08 PM, Corentin Dupont corentin.dup...@gmail.com wrote: So I need to encrypt the user ID in some way? What I need is to associate the user ID to a random number and store the association is a table? On Wed, Feb 27, 2013 at 3:52 PM, Erik Hesselink hessel...@gmail.comwrote: Note that cookies are not the solution here. Cookies are just as user controlled as the url, just less visible. What you need is a session id: a mapping from a non-consecutive, non-guessable, secret token to the user id (which is sequential and thus guessable, and often exposed in urls etc.). It doesn't matter if you then store it in the url or a cookie. Cookies are just more convenient. Erik On Wed, Feb 27, 2013 at 3:30 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes, having a cookie to keep track of the session if something I plan to do. On Wed, Feb 27, 2013 at 3:16 PM, Mats Rauhala mats.rauh...@gmail.com wrote: The user id is not necessarily the problem, but rather that you can impose as another user. For this, one solution is to keep track of a unique (changing) user token in the cookies and use that for verifying the user. -- Mats Rauhala MasseR -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAlEuFVQACgkQHRg/fChhmVMu3ACeLLjbluDQRYekIA2XY37Xbrql tH0An1eQHrLLxCjHHBQcZKmy1iYxCxTt =tf0d -END PGP SIGNATURE- ___ 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
[Haskell-cafe] ANN: Nomyx 0.1 beta, the game where you can change the rules
Hello everybody! I am very happy to announce the beta release [1] of Nomyx, the only game where You can change the rules. This is an implementation of a Nomic [2] game in Haskell (I believe the first complete implementation). In a Nomyx game you can change the rules of the game itself while playing it. The players can submit new rules or modify existing ones, thus completely changing the behaviour of the game through time. The rules are managed and interpreted by the computer. They must be written in the Nomyx language, which is a subset of Haskell. At the beginning, the initial rules are describing: - how to add new rules and change existing ones. For example a unanimity vote is necessary to have a new rule accepted. - how to win the game. For example you win the game if you have 5 rules accepted. But of course even that can be changed! Here is a video introduction and first tutorial of the game: http://vimeo.com/58265498 The game is running here: www.nomyx.net:8000/Nomyx I have set up a forum where players can learn about Nomyx and discuss the rules they intend to propose: www.nomyx.net/forum As this is the first beta release of the game, I'm looking for beta testers :) Although I tested it quite a lot, I'm sure a lot of bugs remains, especially in multiplayer. So if you are interested in testing Nomyx, please go to this forum thread and we'll set up a small team to start a match! http://www.nomyx.net/forum/viewtopic.php?p=5 Comments/contributions are very highly welcome! There is still a lot to do. As for now, the game is not completely securised. It is easy to break it by submitting rules containing malicious code. I'm working on it. If you'd like to do security testing, please do it locally on your own machine and send me a bug report :). Cheers, Corentin [1] http://hackage.haskell.org/package/Nomyx [2] www.nomic.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checking the content of a string
Up on that, anybody already tried to load an haskell interpreter in a QuasiQuoter? On Sat, Feb 23, 2013 at 12:03 AM, Corentin Dupont corentin.dup...@gmail.com wrote: I'm trying to load my interpreter in the Q monad: cr :: QuasiQuoter cr = QuasiQuoter { quoteExp = quoteRuleFunc} quoteRuleFunc :: String - Q TH.Exp quoteRuleFunc s = do res - runIO $ runInterpreter $ do setImports [Prelude, Language.Nomyx.Rule, Language.Nomyx.Expression, Language.Nomyx.Test, Language.Nomyx.Examples, GHC.Base, Data.Maybe] interpret s (as :: RuleFunc) case res of Right _ - [| s |] Left e - fail $ show e However, I always obtain an error durring compilation: ... Loading package XXX ... linking ... done. GHCi runtime linker: fatal error: I found a duplicate definition for symbol __stginit_ghczm7zi4zi1_DsMeta whilst processing object file /usr/lib/ghc/ghc-7.4.1/libHSghc-7.4.1.a This could be caused by: * Loading two different object files which export the same symbol * Specifying the same object file twice on the GHCi command line * An incorrect `package.conf' entry, causing some object to be loaded twice. GHCi cannot safely continue in this situation. Exiting now. Sorry. I vaguely understand that the interpreted modules are conflicting with the compiled ones... On Fri, Feb 22, 2013 at 11:51 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Great! That seems very powerful. So you can do what you want during compilation, readin files, send data over the network? Other question, in my example how can I halt the compilation if a test program is wrong? On Fri, Feb 22, 2013 at 8:30 PM, Francesco Mazzoli f...@mazzo.li wrote: At Fri, 22 Feb 2013 19:43:51 +0100, Corentin Dupont wrote: Hi Adam, that looks interresting. I'm totally new to TH and QuasiQuotes, though. Can I run IO in a QuasiQuoter? I can run my own interpreter. Yes, you can: http://hackage.haskell.org/packages/archive/template-haskell/2.8.0.0/doc/html/Language-Haskell-TH.html#v:runIO . Francesco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checking the content of a string
Finally, I solved the problem using typeOf instead of interpret: cr :: QuasiQuoter cr = QuasiQuoter { quoteExp = quoteRuleFunc} quoteRuleFunc :: String - Q TH.Exp quoteRuleFunc s = do res - runIO $ runInterpreter $ do setImports [Prelude, Language.Nomyx.Expression] typeOf s case res of Right RuleFunc - [| s |] Right _ - fail $ Rule doesn't typecheck Left e - fail $ show e I don't know really why, but now it's working very well! On Sat, Feb 23, 2013 at 7:56 PM, Daniel Gorín jcpetru...@gmail.com wrote: Hi Corentin, I've never used TH, but from what I understand, trying to combine hint and TH would be redundant (even if it worked): whatever String you can evaluate using hint, you can evaluate it directly in TH. Is this not the case? Cheers, Daniel On Feb 23, 2013, at 6:53 PM, Corentin Dupont wrote: Hi Daniel, Did you already tried to use Hint in a QuasiQuote? This would come handy to check at compile time the validity of some strings... However I have the error hereunder. The duplicate symbol found in the object file is in fact the first symbol in this file. So I guess GHCi tries to load it twice... Best, Corentin On Sat, Feb 23, 2013 at 12:03 AM, Corentin Dupont corentin.dup...@gmail.com wrote: I'm trying to load my interpreter in the Q monad: cr :: QuasiQuoter cr = QuasiQuoter { quoteExp = quoteRuleFunc} quoteRuleFunc :: String - Q TH.Exp quoteRuleFunc s = do res - runIO $ runInterpreter $ do setImports [Prelude, Language.Nomyx.Rule, Language.Nomyx.Expression, Language.Nomyx.Test, Language.Nomyx.Examples, GHC.Base, Data.Maybe] interpret s (as :: RuleFunc) case res of Right _ - [| s |] Left e - fail $ show e However, I always obtain an error during compilation: ... Loading package XXX ... linking ... done. GHCi runtime linker: fatal error: I found a duplicate definition for symbol __stginit_ghczm7zi4zi1_DsMeta whilst processing object file /usr/lib/ghc/ghc-7.4.1/libHSghc-7.4.1.a This could be caused by: * Loading two different object files which export the same symbol * Specifying the same object file twice on the GHCi command line * An incorrect `package.conf' entry, causing some object to be loaded twice. GHCi cannot safely continue in this situation. Exiting now. Sorry. I vaguely understand that the interpreted modules are conflicting with the compiled ones... On Fri, Feb 22, 2013 at 11:51 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Great! That seems very powerful. So you can do what you want during compilation, readin files, send data over the network? Other question, in my example how can I halt the compilation if a test program is wrong? On Fri, Feb 22, 2013 at 8:30 PM, Francesco Mazzoli f...@mazzo.li wrote: At Fri, 22 Feb 2013 19:43:51 +0100, Corentin Dupont wrote: Hi Adam, that looks interresting. I'm totally new to TH and QuasiQuotes, though. Can I run IO in a QuasiQuoter? I can run my own interpreter. Yes, you can: http://hackage.haskell.org/packages/archive/template-haskell/2.8.0.0/doc/html/Language-Haskell-TH.html#v:runIO . Francesco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type checking the content of a string
Hi all, I have a program able to read another program as a string, and interpret it (using Hint). I'd like to make unit tests, so I have a file Test.hs containing a serie of test programs as strings. However, how could I be sure that these test program are syntactically valid, at compile time? Those programs should have the type RuleFunc. I tried some TH: printProg :: Q Exp - String printProg p = unsafePerformIO $ do expr - runQ p return $ pprint expr myTest = printProg [| my test program :: RuleFunc |] But it's not very satisfatory yet. When pretty printing TH changes the program quite a bit and my interpreter cannot compile it due to scoping problems. I'd like to have my test program copied back as is. Is it possible? Any other solutions? Thanks a lot! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checking the content of a string
Hi Adam, that looks interresting. I'm totally new to TH and QuasiQuotes, though. Can I run IO in a QuasiQuoter? I can run my own interpreter. On Fri, Feb 22, 2013 at 7:12 PM, adam vogt vogt.a...@gmail.com wrote: On Fri, Feb 22, 2013 at 12:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi all, I have a program able to read another program as a string, and interpret it (using Hint). I'd like to make unit tests, so I have a file Test.hs containing a serie of test programs as strings. However, how could I be sure that these test program are syntactically valid, at compile time? Hi Corentin, You could write the test programs like: test1 :: String test1 = [qq| x+1 == 3 |] Where qq is a QuasiQuoter you have to define. It could try to parse the string with http://hackage.haskell.org/package/haskell-src-exts, and if that succeeds, returns the original string. -- Adam ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checking the content of a string
Great! That seems very powerful. So you can do what you want during compilation, readin files, send data over the network? Other question, in my example how can I halt the compilation if a test program is wrong? On Fri, Feb 22, 2013 at 8:30 PM, Francesco Mazzoli f...@mazzo.li wrote: At Fri, 22 Feb 2013 19:43:51 +0100, Corentin Dupont wrote: Hi Adam, that looks interresting. I'm totally new to TH and QuasiQuotes, though. Can I run IO in a QuasiQuoter? I can run my own interpreter. Yes, you can: http://hackage.haskell.org/packages/archive/template-haskell/2.8.0.0/doc/html/Language-Haskell-TH.html#v:runIO . Francesco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type checking the content of a string
I'm trying to load my interpreter in the Q monad: cr :: QuasiQuoter cr = QuasiQuoter { quoteExp = quoteRuleFunc} quoteRuleFunc :: String - Q TH.Exp quoteRuleFunc s = do res - runIO $ runInterpreter $ do setImports [Prelude, Language.Nomyx.Rule, Language.Nomyx.Expression, Language.Nomyx.Test, Language.Nomyx.Examples, GHC.Base, Data.Maybe] interpret s (as :: RuleFunc) case res of Right _ - [| s |] Left e - fail $ show e However, I always obtain an error durring compilation: ... Loading package XXX ... linking ... done. GHCi runtime linker: fatal error: I found a duplicate definition for symbol __stginit_ghczm7zi4zi1_DsMeta whilst processing object file /usr/lib/ghc/ghc-7.4.1/libHSghc-7.4.1.a This could be caused by: * Loading two different object files which export the same symbol * Specifying the same object file twice on the GHCi command line * An incorrect `package.conf' entry, causing some object to be loaded twice. GHCi cannot safely continue in this situation. Exiting now. Sorry. I vaguely understand that the interpreted modules are conflicting with the compiled ones... On Fri, Feb 22, 2013 at 11:51 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Great! That seems very powerful. So you can do what you want during compilation, readin files, send data over the network? Other question, in my example how can I halt the compilation if a test program is wrong? On Fri, Feb 22, 2013 at 8:30 PM, Francesco Mazzoli f...@mazzo.li wrote: At Fri, 22 Feb 2013 19:43:51 +0100, Corentin Dupont wrote: Hi Adam, that looks interresting. I'm totally new to TH and QuasiQuotes, though. Can I run IO in a QuasiQuoter? I can run my own interpreter. Yes, you can: http://hackage.haskell.org/packages/archive/template-haskell/2.8.0.0/doc/html/Language-Haskell-TH.html#v:runIO . Francesco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Error: junk while building GHC
Hi all, I'm trying to build GHC HEAD snapshot 7.7.20130210, I have the following error: inplace/bin/ghc-stage1 -optc-Ilibraries/ghc-prim/. -optc-I'/home/cdupont/Haskell/ghc-7.7.20130210/rts/dist/build' -optc-I'/home/cdupont/Haskell/ghc-7.7.20130210/includes' -optc-I'/home/cdupont/Haskell/ghc-7.7.20130210/includes/dist-derivedconstants/header' -fPIC -dynamic -H32m -O-package-name ghc-prim-0.3.1.0 -hide-all-packages -i -ilibraries/ghc-prim/. -ilibraries/ghc-prim/dist-install/build -ilibraries/ghc-prim/dist-install/build/autogen -Ilibraries/ghc-prim/dist-install/build -Ilibraries/ghc-prim/dist-install/build/autogen -Ilibraries/ghc-prim/. -optP-include -optPlibraries/ghc-prim/dist-install/build/autogen/cabal_macros.h -package rts-1.0 -package-name ghc-prim -XHaskell98 -XCPP -XMagicHash -XForeignFunctionInterface -XUnliftedFFITypes -XUnboxedTuples -XEmptyDataDecls -XNoImplicitPrelude -O2 -no-user-package-db -rtsopts -c libraries/ghc-prim/cbits/debug.c -o libraries/ghc-prim/dist-install/build/cbits/debug.dyn_o debug.c: Assembler messages: debug.c:12:0: Error: junk `.get_pc_thunk.bx' after expression debug.c:41:0: Error: junk `.get_pc_thunk.bx' after expression debug.c:63:0: Error: junk at end of line, first unrecognized character is `1' debug.c:64:0: Error: junk at end of line, first unrecognized character is `1' debug.c:65:0: Error: Missing symbol name in directive debug.c:65:0: Error: junk at end of line, first unrecognized character is `1' debug.c:66:0: Error: Missing symbol name in directive debug.c:66:0: Error: junk at end of line, first unrecognized character is `.' debug.c:67:0: Error: junk at end of line, first unrecognized character is `1' The file debug.c is not even 12 lines long (and it looks correct)... Any ideas? Thanks, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] multi-thread and lazy evaluation
Hi Brandon, indeed in my example if you add: *b - evaluate a* after the definition of a it works. However, in my original program it doesn't work, I suppose because I interpret the user submitted code (here *let (a::String) = a * for the example) via Hint and Hint-server, and the interpretation must be done in another thread... Best, Corentin On Mon, Dec 24, 2012 at 3:46 PM, Brandon Allbery allber...@gmail.comwrote: On Mon, Dec 24, 2012 at 8:45 AM, Corentin Dupont corentin.dup...@gmail.com wrote: *execBlocking :: MVar (Maybe MyData) - IO () execBlocking mv = do let (a::String) = a --If you uncomment the next line, it will work --putStrLn $ show a putMVar mv (Just $ MyData a toto)* It's laziness, yes; you need to do something along the lines of let a = length a `seq` a or possibly Control.Exception.evaluate needs to be involved somewhere. -- brandon s allbery kf8nh sine nomine associates allber...@gmail.com ballb...@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] multi-thread and lazy evaluation
Great, with me compiled with ghc -threaded the bug shows up. However, runnning main in ghci doesn't show the bug (it finishes correctly). I have GHC 7.4.1. Corentin On Tue, Dec 25, 2012 at 3:34 PM, timothyho...@seznam.cz wrote: This seems like a bug in GHC. But it has nothing to do with MVars. I've narrowed this down and filed a bug report here: http://hackage.haskell.org/trac/ghc/ticket/7528 Timothy -- Původní zpráva -- Od: Yuras Shumovich shumovi...@gmail.com Datum: 24. 12. 2012 Předmět: Re: [Haskell-cafe] multi-thread and lazy evaluation On Mon, 2012-12-24 at 16:16 +0100, timothyho...@seznam.cz wrote: The real question is, does this mean that GHC is stopping the world every time it puts an MVar? No, GHC rts only locks the MVar itself. See here: http://hackage.haskell.org/trac/ghc/browser/rts/PrimOps.cmm#L1358 Yuras ___ 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] multi-thread and lazy evaluation
Hi all, I have a program where the user can submit his own little programs, which are interpreted using Hint. The user-submitted programs are used to modify a state held in a TVar. As of course those user-submitted programs can't be trusted, I'm trying to protect them, like in Mueval. I installed a watchdog to monitor and kill the user's thread if it doesn't finish. However it doesn't work properly, due to lazy evaluation I believe. I made a little exemple to illustrate the problem. - The following program doesn't terminate, but if you uncomment the putStrLn at the end, it will. Could someone explain me this and how to do it properly?? Merry Christmas to all Corentin * {-# LANGUAGE ScopedTypeVariables #-} import Control.Concurrent.STM.TVar import Control.Concurrent.MVar import Control.Concurrent import Control.Monad.STM data MyData = MyData { a :: String, b :: String } deriving (Show) main = do tv - atomically $ newTVar $ MyData a b protectedExecCommand tv myNewData - atomically $ readTVar tv putStrLn $ show myNewData protectedExecCommand :: (TVar MyData) - IO () protectedExecCommand tv = do mv - newEmptyMVar before - atomically $ readTVar tv id - forkIO $ execBlocking mv forkIO $ watchDog' 5 id mv res - takeMVar mv case res of Nothing - (atomically $ writeTVar tv before) Just after - (atomically $ writeTVar tv after) watchDog' :: Int - ThreadId - MVar (Maybe x) - IO () watchDog' t tid mv = do threadDelay $ t * 100 killThread tid putStrLn $ process timeout tryPutMVar mv Nothing return () execBlocking :: MVar (Maybe MyData) - IO () execBlocking mv = do let (a::String) = a --If you uncomment the next line, it will work --putStrLn $ show a putMVar mv (Just $ MyData a toto)* ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] multi-thread and lazy evaluation
Sorry, I'm thinking my example program wasn't maybe too explicit. In it, the line *let (a::String) = a* represents the program submitted by the user, that is faulty. The objective is to stop it after some time, and set the (TVar MyData) to its previous value. As you can see, it works only if I put a putStrLn in the same thread to force the evaluation *{-# LANGUAGE ScopedTypeVariables #-} import Control.Concurrent.STM.TVar import Control.Concurrent.MVar import Control.Concurrent import Control.Monad.STM data MyData = MyData { a :: String, b :: String } deriving (Show) main = do tv - atomically $ newTVar $ MyData a b protectedExecCommand tv myNewData - atomically $ readTVar tv putStrLn $ show myNewData protectedExecCommand :: (TVar MyData) - IO () protectedExecCommand tv = do mv - newEmptyMVar before - atomically $ readTVar tv id - forkIO $ execBlocking mv forkIO $ watchDog' 5 id mv res - takeMVar mv case res of Nothing - (atomically $ writeTVar tv before) Just after - (atomically $ writeTVar tv after) watchDog' :: Int - ThreadId - MVar (Maybe x) - IO () watchDog' t tid mv = do threadDelay $ t * 100 killThread tid putStrLn $ process timeout tryPutMVar mv Nothing return () execBlocking :: MVar (Maybe MyData) - IO () execBlocking mv = do let (a::String) = a --If you uncomment the next line, it will work --putStrLn $ show a putMVar mv (Just $ MyData a toto)* On Mon, Dec 24, 2012 at 1:17 PM, Corentin Dupont corentin.dup...@gmail.comwrote: Hi all, I have a program where the user can submit his own little programs, which are interpreted using Hint. The user-submitted programs are used to modify a state held in a TVar. As of course those user-submitted programs can't be trusted, I'm trying to protect them, like in Mueval. I installed a watchdog to monitor and kill the user's thread if it doesn't finish. However it doesn't work properly, due to lazy evaluation I believe. I made a little exemple to illustrate the problem. - The following program doesn't terminate, but if you uncomment the putStrLn at the end, it will. Could someone explain me this and how to do it properly?? Merry Christmas to all Corentin * {-# LANGUAGE ScopedTypeVariables #-} import Control.Concurrent.STM.TVar import Control.Concurrent.MVar import Control.Concurrent import Control.Monad.STM data MyData = MyData { a :: String, b :: String } deriving (Show) main = do tv - atomically $ newTVar $ MyData a b protectedExecCommand tv myNewData - atomically $ readTVar tv putStrLn $ show myNewData protectedExecCommand :: (TVar MyData) - IO () protectedExecCommand tv = do mv - newEmptyMVar before - atomically $ readTVar tv id - forkIO $ execBlocking mv forkIO $ watchDog' 5 id mv res - takeMVar mv case res of Nothing - (atomically $ writeTVar tv before) Just after - (atomically $ writeTVar tv after) watchDog' :: Int - ThreadId - MVar (Maybe x) - IO () watchDog' t tid mv = do threadDelay $ t * 100 killThread tid putStrLn $ process timeout tryPutMVar mv Nothing return () execBlocking :: MVar (Maybe MyData) - IO () execBlocking mv = do let (a::String) = a --If you uncomment the next line, it will work --putStrLn $ show a putMVar mv (Just $ MyData a toto)* ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] schedule function
Hi all, I have a simple question: is there in the libraries a function that can schedule a variable list of events for me? For example of the type: type Schedule = [UTCTime, IO()] startSchedule :: TVar Schedule - IO ThreadId The function startSchedule will have to execute my actions at the given times. Of course the TVar can be changed by another thread, so the schedule will have to be recomputed. Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] serialize an unknown type
Hi, I designed my event engine like this: -- | events types data Player = Arrive | Leave deriving (Typeable, Show, Eq) data RuleEvent = Proposed | Activated | Rejected | Added | Modified | Deleted deriving (Typeable, Show, Eq) data Time deriving Typeable data InputChoice c deriving Typeable (...) -- | events names data Event a where Player :: Player - Event Player RuleEv :: RuleEvent - Event RuleEvent Time:: UTCTime -Event Time InputChoice :: (Eq c, Show c) = PlayerNumber - String - [c] - c - Event (InputChoice c) (...) -- | data associated with each events data EventData a where PlayerData :: {playerData :: PlayerInfo}- EventData Player RuleData:: {ruleData :: Rule}- EventData RuleEvent TimeData:: {timeData :: UTCTime} - EventData Time InputChoiceData :: (Show c, Read c, Typeable c) = {inputChoiceData :: c}- EventData (InputChoice c) (...) -- associate an event with an handler data EventHandler where EH :: (Typeable e, Show e, Eq e) = {eventNumber :: EventNumber, event :: Event e, handler :: (EventNumber, EventData e) - Exp ()} - EventHandler --execute all the handlers of the specified event with the given data triggerEvent :: (Typeable a, Show a, Eq a) = Event a - EventData a - [EventHandler] - State Game () I use a type parameter e on Event and EventData to be sure that the right data is shuffled to the right event handler. It worked well until now. But now I'm hitting a wall with the GUI, because the data sent back for InputChoice can only be a String. So, I need to call triggerEvent with: Event(InputChoice String) and EventData (InputChoice String)... Which doesn't work obviously because the types are not the same than initially (for example, the event was built with Event(InputChoice Bool)). Cheers, C On Wed, Oct 24, 2012 at 7:25 PM, Stephen Tetley stephen.tet...@gmail.comwrote: Hi Corentin It looks like you are writing the event handler on the server side. If so, the range of events you can handle is fixed to just those you implement handlers for - having an openly extensible event type is useless if this is the case. Ignoring client/server for a moment, a function (State - State) would be the most extensible API you could allow for clients. You don't need to worry about an open set of Event types, a client knows the state exactly and doesn't need extensibility. Client/Server operation won't allow a state transformer API as Haskell can't readily serialize functions. But you can implement a command language enumerating state changing operations. The second Quickcheck paper gives a very good example of how to implement such a command language. Testing Monadic Code with QuickCheck (2002) Koen Claessen , John Hughes www.cse.chalmers.se/~rjmh/Papers/QuickCheckST.ps Or Citeseer if you need a PDF: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.9275 ___ 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] serialize an unknown type
I'm trying to get around my problem (still stuck...). I have really to call a function like this: triggerEvent :: (Typeable e, Show e, Eq e) = Event e - EventData e - State Game () This function simply execute an event given the corresponding data and change the state of the game. Now as explained my web framework won't accept random types (like e) to be passed around. So I said to myself OK, so let's store the events in a list and ask the gui to just give me the number of the event. So I have an heterogeneous list of events [EventWrap]: data EventWrap where EW :: (Typeable e, Show e, Eq e) = {eventNumber :: Int, event :: Event e} - EventWrap Do you think this solution can lead me somewhere?? I have actually doubts I can find back my Event e from the list because of the implicit forall in the GADT. Thanks, Corentin On Wed, Oct 24, 2012 at 3:37 PM, Chris Smith cdsm...@gmail.com wrote: Corentin Dupont corentin.dup...@gmail.com wrote: I could ask my user to make his new type an instance of a class as suggested by Alberto... If you are working with unknown types, then your options are: (a) constrain to some type class, or (b) have your clients pass in functions to operate on the type alongside the values. Actually the first is just a special case of the second with syntactic sugar... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] serialize an unknown type
Nobody on this one? Here is a simplified version: data Event a where InputChoice :: a - Event a How to serialize/deserialize this? Cheers, Corentin On Sat, Oct 20, 2012 at 10:49 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi the list! I have a simple question, how can I serialize/deserialize a structure like this: data InputChoice c deriving Typeable data Event a where InputChoice :: (Eq c, Show c) = [c] - c - Event (InputChoice c) (...) I'd like that the values of type c get serialized to a String... That's the easy part, but for deserializing, oops! Cheers, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] serialize an unknown type
Hi, Sorry if it was not enough explicit. I want to write functions like this: serialize :: (Show a) = Event a - IO () deserialize :: (Read a) = IO () - Event a The functions would write and read the data in a file, storing/retrieving also the type a I suppose... BR, C On Sun, Oct 21, 2012 at 7:03 PM, MigMit miguelim...@yandex.ru wrote: Seems like nobody really understands what is it that you want to accomplish or what your problem is. Отправлено с iPhone 21.10.2012, в 20:39, Corentin Dupont corentin.dup...@gmail.com написал(а): Nobody on this one? Here is a simplified version: data Event a where InputChoice :: a - Event a How to serialize/deserialize this? Cheers, Corentin On Sat, Oct 20, 2012 at 10:49 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi the list! I have a simple question, how can I serialize/deserialize a structure like this: data InputChoice c deriving Typeable data Event a where InputChoice :: (Eq c, Show c) = [c] - c - Event (InputChoice c) (...) I'd like that the values of type c get serialized to a String... That's the easy part, but for deserializing, oops! Cheers, Corentin ___ 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] serialize an unknown type
Hi Iustin, yes I want to deserialize an unknown type based on the content of the file (in this example). Let's say I can reduce the spectum of types to: Strings, all the types in Enum, Ints. Is it possible? My real problem is that on my web interface I want to use web routes to allow a user to pass an Event back to the engine. The problem is that it seems that web-routes only accepts Strings (or some known types) to be passed on the web route, whereas I need to pass random types. On Sun, Oct 21, 2012 at 8:00 PM, Iustin Pop iu...@k1024.org wrote: On Sun, Oct 21, 2012 at 07:20:10PM +0200, Corentin Dupont wrote: Hi, Sorry if it was not enough explicit. I want to write functions like this: serialize :: (Show a) = Event a - IO () deserialize :: (Read a) = IO () - Event a The functions would write and read the data in a file, storing/retrieving also the type a I suppose... Can't you simply, when defining the type event, add a deriving (Show, Read)? Then the standard (but slow) read/show serialisation would work for you. If you're asking to de-serialise an unknown type (i.e. you don't know what type it should restore a-priori, but you want to do that based on the contents of the file), things become a little more complex. Unless you can further restrict the type 'a', really complex. Maybe stating your actual problem, rather than the implementation question, would be better? regards, iustin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] serialize an unknown type
On Sun, Oct 21, 2012 at 8:42 PM, MigMit miguelim...@yandex.ru wrote: Oh, now I've got it. First of all, functions of type IO () - Event a are impossible (unless you resort to tricks with unsafePerformIO, which is not what you want to deal with right now). You've probably meant something like IO (Event a) (at least, that is the type of function which would read Event a from file or input stream or something else external). Yes, sorry, that's what I meant. Secondly, functions (and values) with parametric types, like IO (Event a) require you to provide the type a in your code. They won't take it from somewhere magically. You can take a look at the read function in Prelude for example. If you really want to store the type information and read it back, you should do it yourself, inventing some representation for your type, writing it to disk, reading back and parsing it. And you can't do that for all types in existence, so you'll need to do that for some specific types (and no, instances of Typeable aren't what you want). And you'll have to deal with type system, which won't allow you to just say hey, let that be whatever type it happens to be, I don't care; you'd have to wrap this into one existentially quantified type (or GADT). Keep in mind that this is not very Haskell-y. First of all, try to analyse, what this a in Event a could be. What are the limits here? And don't say there aren't any, because if you don't know anything about the type, you can't do anything with it. So, maybe you would end up with a finite set of types -- this would simplify matters a lot. Or maybe you'd find out that there are inifinitely many types of events -- but they can be somehow generated with a finite number of constructors -- that would be quite simple as well. So, what is the bigger picture here? In my application, the user can define the a. That's what makes it difficult. For example, the user can define a new enumerate and submit it to the program (it will be interpreted by hint): data Choice = You | Me | Them | Everybody deriving (Enum, Typeable, Show, Eq, Bounded) So, the list of types is not known in advance. I could ask my user to make his new type an instance of a class as suggested by Alberto... On Oct 21, 2012, at 9:20 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi, Sorry if it was not enough explicit. I want to write functions like this: serialize :: (Show a) = Event a - IO () deserialize :: (Read a) = IO () - Event a The functions would write and read the data in a file, storing/retrieving also the type a I suppose... BR, C On Sun, Oct 21, 2012 at 7:03 PM, MigMit miguelim...@yandex.ru wrote: Seems like nobody really understands what is it that you want to accomplish or what your problem is. Отправлено с iPhone 21.10.2012, в 20:39, Corentin Dupont corentin.dup...@gmail.com написал(а): Nobody on this one? Here is a simplified version: data Event a where InputChoice :: a - Event a How to serialize/deserialize this? Cheers, Corentin On Sat, Oct 20, 2012 at 10:49 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi the list! I have a simple question, how can I serialize/deserialize a structure like this: data InputChoice c deriving Typeable data Event a where InputChoice :: (Eq c, Show c) = [c] - c - Event (InputChoice c) (...) I'd like that the values of type c get serialized to a String... That's the easy part, but for deserializing, oops! Cheers, Corentin ___ 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] serialize an unknown type
Hi the list! I have a simple question, how can I serialize/deserialize a structure like this: data InputChoice c deriving Typeable data Event a where InputChoice :: (Eq c, Show c) = [c] - c - Event (InputChoice c) (...) I'd like that the values of type c get serialized to a String... That's the easy part, but for deserializing, oops! Cheers, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Tutorial: Haskell for the Evil Genius
Well, to make it short, I liked it! As suggestions, little things like first class functions and partial application can be easily introduced. For example the line: map (+1) [1..10] contains these concepts and it very short and expressive. On the story side, why not introducing a character? This would help personalize the story. It would be nice if a real story is told also, beside the Haskell story, like a character building something or making a (evil) journey learning Haskell. Cheers, Corentin On Fri, Sep 14, 2012 at 11:18 PM, Andrew Pennebaker andrew.penneba...@gmail.com wrote: A summary of the changes I've included so far: Under Declarative, you aren't creating a named expression, 2 + 2, really. You are redefining (+). Noted and reflected in the new version. Under Lazy, your example of binding fib 30 is not a good example of memoization. With memoization you typically call the underlying computation the first time, and memoize it for repeated retrieval later, not hardwire in values at compile time. Here you never ever call the real fib at all. On top of everything else, it'd be too easy to introduce a typo into one of your hardwired constant values. Noted and reflected in the new version. After several comments to this effect, I do not want to misrepresent memoization in the tutorial. Sometimes it is useful to be slightly inaccurate in a tutorial in order to help bridge the gap between someone with no experience in a something vs the wealth of knowledge and complexity in the thing itself. This is not one of those times, and fortunately, fixing the misrepresentation in my tutorial is as easy as removing the hardcoded call. One thing I want to double check is that Haskell does, in fact, automatically memoize all pure function calls. Is this true? I would still like to provide a performance comparison of the Fibonacci code with and without memoization, for readers who enjoy numerical evidence, using the Unix time command, but I don't know how to turn memoization off. I guess I would have to reimplement the algorithm in a way that can't make use of memoization. Any suggestions? Under Infinite, you should use sieve (n:ns) pattern matching instead of calling head. Thank you! I try to make use of Haskell pattern matching wherever I can. Since I needed to refer to the whole list, as well as the head and tail, I originally used head instead of pattern matching. Noted and reflected in the new version. Under Type-Safe Subtle distinction, but returning () is not the same as returning nothing at all. True. Noted and reflected in the new version. What's the Haskell name for () again? I fear explaining the exact type information of IO () may be too much for a brief introduction to Haskell to cover. s/ommitted/omitted/ Noted and reflected in the new version. You've got an unusual indentation scheme. Consider adopting a more standard one for your tutorial. I'm in the camp of hard tabs rather than soft tabs, and that preference is probably responsible for much of the difference in indentation scheme. Unfortunately, HTML is terrible at representing hard tabs in PRE code with a custom width preference; they all come out looking like some idiot pressed space bar eight times. I could use JavaScript to remedy this, but for now, I like to directly copy and paste my working code from .HS files into PRE tags just in case. If tabs are *not* the issue, then maybe I'm not indenting far enough to the right for some tastes? Or maybe it's my tendency to put where on its own line, something a Perl obfuscater would detest. I dunno. If someone would suggest a more idiomatic indentation scheme for my code so that I know exactly what is different, I can take a look. In general, monotonically decreasing is not sufficient to prove you will hit a base case. For example, decreasing by 5 would still be monotonically decreasing, and could jump right over your base cases. (Not arguing that the code is incorrect, but rather than your explanation is a little misleading/incomplete.) Understood. Noted and reflected in the new version. Incidentally, when will Nat be available in Haskell? The Fibonacci algorithm is designed to work only over natural numbers, and the best way to express this in the type system is with Nat. But this type doesn't seem available out-of-the-box for Haskell users. Unless I'm using my Haskell Platform (GHC 7.0.3) is slightly outdated. Eh? Again, further confusion about what memoization really is. Under Records Functions are already defined by their data structures; they are already semantically bundled... doesn't seem to make sense. Noted and reflected... I'm trying to convey to an audience largely composed of Java and C++ fanatics how Haskell records are much better than OOP, how GADTs are more intuitive, robust, ... OOP doesn't even compare! That's what I'm trying to get across in that bit. And it's
Re: [Haskell-cafe] type variable in class instance
If I understand, the SomeEvent event acts as a proxy to hide the diversity of the events? That's interesting. This way I don't have to use an heterogeneous list and a lot of casting... On Wed, Sep 12, 2012 at 7:44 AM, o...@okmij.org wrote: Let me see if I understand. You have events of different sorts: events about players, events about timeouts, events about various messages. Associated with each sort of event is a (potentially open) set of data types: messages can carry payload of various types. A handler specifies behavior of a system upon the reception of an event. A game entity (player, monster, etc) is a collection of behaviors. The typing problem is building the heterogeneous collection of behaviors and routing an event to the appropriate handler. Is this right? There seem to be two main implementations, with explicit types and latent (dynamic) types. The explicit-type representation is essentially HList (a Type-indexed Record, TIR, to be precise). Let's start with the latent-type representation. Now I understand your problem better, I think your original approach was the right one. GADT was a distraction, sorry. Hopefully you find the code below better reflects your intentions. {-# LANGUAGE ExistentialQuantification, DeriveDataTypeable #-} {-# LANGUAGE StandaloneDeriving #-} import Data.Typeable -- Events sorts data Player = Player PlayerN PlayerStatus deriving (Eq, Show, Typeable) type PlayerN = Int data PlayerStatus = Enetering | Leaving deriving (Eq, Show) newtype Message m = Message m deriving (Eq, Show) deriving instance Typeable1 Message newtype Time = Time Int deriving (Eq, Show, Typeable) data SomeEvent = forall e. Typeable e = SomeEvent e deriving (Typeable) -- They are all events class Typeable e = Event e where -- the Event predicate what_event :: SomeEvent - Maybe e what_event (SomeEvent e) = cast e instance Event Player instance Event Time instance Typeable m = Event (Message m) instance Event SomeEvent where what_event = Just -- A handler is a reaction on an event -- Given an event, a handler may decline to handle it type Handler e = e - Maybe (IO ()) inj_handler :: Event e = Handler e - Handler SomeEvent inj_handler h se | Just e - what_event se = h e inj_handler _ _ = Nothing type Handlers = [Handler SomeEvent] trigger :: Event e = e - Handlers - IO () trigger e [] = fail Not handled trigger e (h:rest) | Just rh - h (SomeEvent e) = rh | otherwise = trigger e rest -- Sample behaviors -- viewing behavior (although viewing is better with Show since all -- particular events implement it anyway) view_player :: Handler Player view_player (Player x s) = Just . putStrLn . unwords $ [Player, show x, show s] -- View a particular message view_msg_str :: Handler (Message String) view_msg_str (Message s) = Just . putStrLn . unwords $ [Message, s] -- View any message view_msg_any :: Handler SomeEvent view_msg_any (SomeEvent e) | (tc1,[tr]) - splitTyConApp (typeOf e), (tc2,_)- splitTyConApp (typeOf (undefined::Message ())), tc1 == tc2 = Just . putStrLn . unwords $ [Some message of the type, show tr] view_msg_any _ = Nothing viewers = [inj_handler view_player, inj_handler view_msg_str, view_msg_any] test1 = trigger (Player 1 Leaving) viewers -- Player 1 Leaving test2 = trigger (Message str1) viewers -- Message str1 test3 = trigger (Message (2::Int)) viewers -- Some message of the type Int ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type variable in class instance
Thanks Martijn, Oleg and Ryan for your kind replies! @Ryan and Martijn: I considered putting the viewEvent in the typeclass, but I figured out that would break the separation of concerns. Indeed this typeclass Event belongs to the inner engine, while the display is done in another component (not even the same library) using a specific technology (for instance HTML). So it doesn't feel right to mix the logic of the event engine with the display... @Oleg: Yes the set of events is closed and I would be much happier with a GADT! But no matter how hard I tried I couldn't manage. Here is the full problem: *{-# LANGUAGE ExistentialQuantification, TypeFamilies, DeriveDataTypeable #-} import Data.Typeable -- | Define the events and their related data class (Eq e, Typeable e, Show e) = Event e where data EventData e -- | Groups of events data PlayerEvent = Arrive | Leave deriving (Typeable, Show, Eq) -- | events types data Player = Player PlayerEvent deriving (Typeable, Show, Eq) data Message m = Message String deriving (Typeable, Show, Eq) -- | event instances instance Event Player where data EventData Player = PlayerData {playerData :: Int} instance (Typeable m) = Event (Message m) where data EventData (Message m) = MessageData {messageData :: m} -- | structure to store an event data EventHandler = forall e . (Event e) = EH {eventNumber :: Int, event :: e, handler :: (EventData e) - IO ()} deriving Typeable -- store a new event with its handler in the list addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent event handler ehs = undefined -- trigger all the corresponding events in the list, passing the **data to the handlers triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent event edata ehs = undefined --Examples: msg :: Message Int msg = Message give me a number myList = addEvent msg (\(MessageData n) - putStrLn $ Your number is: ++ show n) [] trigger = triggerEvent msg (MessageData 1) **myList --Yelds Your number is: 1* Has you can see this allows me to associate an arbitrary data type to each event with the type family EventData. Furthermore some events like Message let the user choose the data type using the type parameter. This way I have nice signatures for the functions addEvent and triggerEvent. The right types for the handlers and the data passed is enforced at compilation time. But I couldn't find any way to convert this into a GATD and get rid of the Event class.. Thanks, Corentin On Tue, Sep 11, 2012 at 1:51 PM, Martijn Schrage mart...@oblomov.comwrote: On 11-09-12 08:53, o...@okmij.org wrote: Corentin Dupon wrote about essentially the read-show problem: class (Typeable e) = Event e data Player = Player Int deriving (Typeable) data Message m = Message String deriving (Typeable) instance Event Player instance (Typeable m) = Event (Message m) viewEvent :: (Event e) = e - IO () viewEvent event = do case cast event of Just (Player a) - putStrLn $ show a Nothing - return () case cast event of Just (Message s) - putStrLn $ show s Nothing - return () Indeed the overloaded function cast needs to know the target type -- the type to cast to. In case of Player, the pattern (Player a) uniquely determines the type of the desired value: Player. This is not so for Message: the pattern (Message s) may correspond to the type Message (), Message Int, etc. To avoid the problem, just specify the desired type explicitly I had the same idea, but it doesn't work. Fixing m to () causes the cast to fail for any other type, so viewEvent (Message yes :: Message ())will work, but viewEvent (Message no :: Message Char) won't. Putting viewEvent in the Event class though, like Ryan suggested, seems to be an elegant solution that stays close to the original source. Cheers, Martijn case cast event of Just (Message s::Message ()) - putStrLn $ show s Nothing - return () (ScopedTypeVariables extension is needed). The exact type of the message doesn't matter, so I chose Message (). BTW, if the set of events is closed, GADTs seem a better fit data Player data Message s data Event e where Player :: Int- Event Player Message :: String - Event (Message s) viewEvent :: Event e - IO () viewEvent (Player a) = putStrLn $ show a viewEvent (Message s) = putStrLn $ show s ___ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://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
Re: [Haskell-cafe] type variable in class instance
Yes. That's fantastic! This GADT is the missing piece of my puzzle. I transformed a bit your solution, polluting it with some classes instances and fleshing the functions: *data Player = Arrive | Leave deriving (Show, Typeable, Eq) data Message m = Message String deriving (Show, Typeable, Eq) data Data a where PlayerData :: Int - Data Player MessageData :: m - Data (Message m) data Handler where Handler :: (Typeable e) = e - (Data e - IO ()) - Handler instance forall e. (Typeable e) = Typeable (Data e) where typeOf _ = mkTyConApp (mkTyCon( (Expression.EventData ( ++ (show $ typeOf (undefined::e))) ++ ) )) [] addEvent :: (Typeable e) = e - (Data e - IO ()) - [Handler] - [Handler] addEvent e h hs = (Handler e h) : hs triggerEvent :: (Eq e, Typeable e) = e - Data e - [Handler] - IO () triggerEvent e d hs = do let filtered = filter (\(Handler e1 _) - e1 === e) hs mapM_ f filtered where f (Handler _ h) = case cast h of Just castedH - do castedH d Nothing - return () viewEvent :: (Typeable e) = e - IO() viewEvent event = do case cast event of Just (a :: Player) - putStrLn $ Player ++ show a Nothing - return () case cast event of (Just (Message s)) - putStrLn $ Player ++ s Nothing - return ()* Unfortunately, I still cannot pattern match on the events to view them (*viewEvent won't compile)*... Best, Corentin On Tue, Sep 11, 2012 at 4:10 PM, Sean Leather leat...@cs.uu.nl wrote: On Tue, Sep 11, 2012 at 3:39 PM, Corentin Dupontwrote: @Oleg: Yes the set of events is closed and I would be much happier with a GADT! But no matter how hard I tried I couldn't manage. Here is the full problem: *{-# LANGUAGE ExistentialQuantification, TypeFamilies, DeriveDataTypeable #-} import Data.Typeable -- | Define the events and their related data class (Eq e, Typeable e, Show e) = Event e where data EventData e -- | Groups of events data PlayerEvent = Arrive | Leave deriving (Typeable, Show, Eq) -- | events types data Player = Player PlayerEvent deriving (Typeable, Show, Eq) data Message m = Message String deriving (Typeable, Show, Eq) -- | event instances instance Event Player where data EventData Player = PlayerData {playerData :: Int} instance (Typeable m) = Event (Message m) where data EventData (Message m) = MessageData {messageData :: m} -- | structure to store an event data EventHandler = forall e . (Event e) = EH {eventNumber :: Int, event :: e, handler :: (EventData e) - IO ()} deriving Typeable -- store a new event with its handler in the list addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent event handler ehs = undefined -- trigger all the corresponding events in the list, passing the **data to the handlers triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent event edata ehs = undefined --Examples: msg :: Message Int msg = Message give me a number myList = addEvent msg (\(MessageData n) - putStrLn $ Your number is: ++ show n) [] trigger = triggerEvent msg (MessageData 1) **myList --Yelds Your number is: 1* Has you can see this allows me to associate an arbitrary data type to each event with the type family EventData. Furthermore some events like Message let the user choose the data type using the type parameter. This way I have nice signatures for the functions addEvent and triggerEvent. The right types for the handlers and the data passed is enforced at compilation time. But I couldn't find any way to convert this into a GATD and get rid of the Event class.. Would this work? data Player = Arrive | Leave data Message m = Message String data Data a where PlayerData :: Int - Data Player MessageData :: m - Data (Message m) data Handler where Handler :: Int - e - (Data e - IO ()) - Handler addEvent :: e - (Data e - IO ()) - [Handler] - [Handler] addEvent = undefined triggerEvent :: e - Data e - [Handler] - IO () triggerEvent = undefined Regards, Sean ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type variable in class instance
I finally come up with this version, which allows to do pattern matching against the events. I'm sure it could be cleaned a bit, but it think the idea is there. I would like to thank again everybody on this list, that's very friendly and helpful! Corentin *{-# LANGUAGE ExistentialQuantification, TypeFamilies, DeriveDataTypeable, GADTs, ScopedTypeVariables, StandaloneDeriving #-} import Data.Typeable data Player = Arrive | Leave deriving (Show, Typeable, Eq) data Message m = Message String deriving (Show, Typeable, Eq) data Event a where PlayerEvent :: Player - Event Player MessageEvent :: Message m - Event (Message m) data Data a where PlayerData :: Int - Data (Event Player) MessageData :: m - Data (Event (Message m)) data Handler where Handler :: (Typeable e) = Event e - (Data (Event e) - IO ()) - Handler deriving instance Eq (Event a) deriving instance Typeable1 Data deriving instance Typeable1 Event addEvent :: (Typeable e) = Event e - (Data (Event e) - IO ()) - [Handler] - [Handler] addEvent e h hs = (Handler e h) : hs triggerEvent :: (Eq e, Typeable e) = Event e - (Data (Event e)) - [Handler] - IO () triggerEvent e d hs = do let filtered = filter (\(Handler e1 _) - e1 === e) hs mapM_ f filtered where f (Handler _ h) = case cast h of Just castedH - do castedH d Nothing - return () viewEvent :: (Typeable e) = (Event e) - IO() viewEvent (PlayerEvent p) = putStrLn $ Player ++ show p viewEvent m@(MessageEvent s) = putStrLn $ Message ++ show s ++ of type ++ (show $ typeOf m) -- | an equality that tests also the types. (===) :: (Typeable a, Typeable b, Eq b) = a - b - Bool (===) x y = cast x == Just y --TEST testPlayer = addEvent (PlayerEvent Arrive) (\(PlayerData d) - putStrLn $ show d) [] msg :: Message Int msg = Message give me a number myList = addEvent (MessageEvent msg) (\(MessageData n) - putStrLn $ Your number is: ++ show n) [] trigger = triggerEvent (MessageEvent msg) (MessageData 1) myList --Yelds Your number is: 1* On Tue, Sep 11, 2012 at 5:06 PM, Corentin Dupont corentin.dup...@gmail.comwrote: Yes. That's fantastic! This GADT is the missing piece of my puzzle. I transformed a bit your solution, polluting it with some classes instances and fleshing the functions: *data Player = Arrive | Leave deriving (Show, Typeable, Eq) data Message m = Message String deriving (Show, Typeable, Eq) data Data a where PlayerData :: Int - Data Player MessageData :: m - Data (Message m) data Handler where Handler :: (Typeable e) = e - (Data e - IO ()) - Handler instance forall e. (Typeable e) = Typeable (Data e) where typeOf _ = mkTyConApp (mkTyCon( (Expression.EventData ( ++ (show $ typeOf (undefined::e))) ++ ) )) [] addEvent :: (Typeable e) = e - (Data e - IO ()) - [Handler] - [Handler] addEvent e h hs = (Handler e h) : hs triggerEvent :: (Eq e, Typeable e) = e - Data e - [Handler] - IO () triggerEvent e d hs = do let filtered = filter (\(Handler e1 _) - e1 === e) hs mapM_ f filtered where f (Handler _ h) = case cast h of Just castedH - do castedH d Nothing - return () viewEvent :: (Typeable e) = e - IO() viewEvent event = do case cast event of Just (a :: Player) - putStrLn $ Player ++ show a Nothing - return () case cast event of (Just (Message s)) - putStrLn $ Player ++ s Nothing - return ()* Unfortunately, I still cannot pattern match on the events to view them (*viewEvent won't compile)*... Best, Corentin On Tue, Sep 11, 2012 at 4:10 PM, Sean Leather leat...@cs.uu.nl wrote: On Tue, Sep 11, 2012 at 3:39 PM, Corentin Dupontwrote: @Oleg: Yes the set of events is closed and I would be much happier with a GADT! But no matter how hard I tried I couldn't manage. Here is the full problem: *{-# LANGUAGE ExistentialQuantification, TypeFamilies, DeriveDataTypeable #-} import Data.Typeable -- | Define the events and their related data class (Eq e, Typeable e, Show e) = Event e where data EventData e -- | Groups of events data PlayerEvent = Arrive | Leave deriving (Typeable, Show, Eq) -- | events types data Player = Player PlayerEvent deriving (Typeable, Show, Eq) data Message m = Message String deriving (Typeable, Show, Eq) -- | event instances instance Event Player where data EventData Player = PlayerData {playerData :: Int} instance (Typeable m) = Event (Message m) where data EventData (Message m) = MessageData {messageData :: m} -- | structure to store an event data EventHandler = forall e . (Event e) = EH {eventNumber :: Int, event :: e, handler :: (EventData e) - IO ()} deriving Typeable -- store a new event with its handler in the list addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent event
Re: [Haskell-cafe] type variable in class instance
Hi David, that may be also a way to go. I've also looked into this way (view patterns), unfortunately it seems that I will be obliged to maintain 2 parallel structures: for each Event instance, I will have to add a ViewEvent element as well carrying the same information: instance Event Time where eventType = TimeEvent data EventType e where PlayerEvent :: EventType Player MessageEvent :: EventType (Message m) TimeEvent :: EventType Time That's why I like the all-GADT solution... Corentin On Tue, Sep 11, 2012 at 6:46 PM, David Menendez d...@zednenem.com wrote: I'm not sure I understand On Tue, Sep 11, 2012 at 11:06 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes. That's fantastic! This GADT is the missing piece of my puzzle. I transformed a bit your solution, polluting it with some classes instances and fleshing the functions: data Player = Arrive | Leave deriving (Show, Typeable, Eq) data Message m = Message String deriving (Show, Typeable, Eq) data Data a where PlayerData :: Int - Data Player MessageData :: m - Data (Message m) data Handler where Handler :: (Typeable e) = e - (Data e - IO ()) - Handler instance forall e. (Typeable e) = Typeable (Data e) where typeOf _ = mkTyConApp (mkTyCon( (Expression.EventData ( ++ (show $ typeOf (undefined::e))) ++ ) )) [] addEvent :: (Typeable e) = e - (Data e - IO ()) - [Handler] - [Handler] addEvent e h hs = (Handler e h) : hs triggerEvent :: (Eq e, Typeable e) = e - Data e - [Handler] - IO () triggerEvent e d hs = do let filtered = filter (\(Handler e1 _) - e1 === e) hs mapM_ f filtered where f (Handler _ h) = case cast h of Just castedH - do castedH d Nothing - return () viewEvent :: (Typeable e) = e - IO() viewEvent event = do case cast event of Just (a :: Player) - putStrLn $ Player ++ show a Nothing - return () case cast event of (Just (Message s)) - putStrLn $ Player ++ s Nothing - return () Unfortunately, I still cannot pattern match on the events to view them (viewEvent won't compile)... Mixing GADTs and Typeable seems like a bad idea. If you really don't want to put viewEvent in the Event typeclass, but the class of events is closed, you could use a GADT to witness the event type. class Event e where eventType :: EventType e ... data EventType e where PlayerEvent :: EventType Player MessageEvent :: EventType (Message m) viewEvent :: Event e = e - IO () viewEvent = viewEvent' eventType viewEvent' :: EventType e - e - IO () viewEvent' PlayerEvent e = ... viewEvent' MessageEvent (Message s) = ... -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type variable in class instance
That's very interesting. One problem is, if the set of event is closed, the set of possible data types is not (the user can choose any data type for a Message callback for example). I think this can be solved using a class instead of a GADT for Type. One can also use a type witness? On Tue, Sep 11, 2012 at 8:09 PM, Sean Leather leat...@cs.uu.nl wrote: On Tue, Sep 11, 2012 at 6:46 PM, David Menendez wrote: Mixing GADTs and Typeable seems like a bad idea. If you really don't want to put viewEvent in the Event typeclass, but the class of events is closed, you could use a GADT to witness the event type. On Tue, Sep 11, 2012 at 7:03 PM, Corentin Dupont wrote: unfortunately it seems that I will be obliged to maintain 2 parallel structures: for each Event instance, I will have to add a ViewEvent element as well carrying the same information: That's why I like the all-GADT solution... Inspired by David's suggestion, here's another version without Typeable. In Corentin's version, the switching back and forth between explicit and forgetful typing bothered me. This version never forgets types. Also, viewEvent is really an instance of Show, as I would expect. I don't see the extra maintenance burden mentioned by Corentin. {-# LANGUAGE TypeFamilies, GADTs #-} data Player = Arrive | Leave deriving Show newtype Message t = Message String deriving (Eq, Show) data Type :: * - * where Int:: Type (Message Int) String :: Type (Message String) Player :: Type Player data TEq :: * - * - * where Refl :: TEq a a teq :: Type a - Type b - Maybe (TEq a b) teq IntInt= Just Refl teq String String = Just Refl teq Player Player = Just Refl teq _ _ = Nothing type family Data t :: * type instance Data (Message t) = t type instance Data Player = Int data Event t = Event (Type t) t data Handler where Handler :: Event t - (Data t - IO ()) - Handler runHandler :: Eq t = Event t - Data t - Handler - IO () runHandler (Event t e) d (Handler (Event u e') f) = case teq t u of Just Refl | e == e' - f d _ - return () runHandlers :: Eq t = Event t - Data t - [Handler] - IO () runHandlers e d hs = mapM_ (runHandler e d) hs -- Replacement for viewEvent instance Show (Event t) where show (Event ty e) = case ty of Int- show e ++ of type Int String - show e ++ of type String Player - Player ++ show e messageEvent :: Type (Message t) - String - Event (Message t) messageEvent t s = Event t (Message s) playerEvent :: Player - Event Player playerEvent = Event Player -- Tests event1 = messageEvent Int give me a number -- No type signature necessary! handler1 = Handler event1 (\n - putStrLn $ Your number is: ++ show n) test1= runHandlers event1 1 [handler1] -- Yields Your number is: 1 Regards, Sean ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] type variable in class instance
Hello everybody! I'm soliciting once again your help! It's been several days I'm blocked by this problem: *{-# LANGUAGE DeriveDataTypeable #-} import Data.Typeable class (Typeable e) = Event e data Player = Player Intderiving (Typeable) data Message m = Message String deriving (Typeable) instance Event Player instance (Typeable m) = Event (Message m) viewEvent :: (Event e) = e - IO () viewEvent event = do case cast event of Just (Player a) - putStrLn $ show a Nothing - return () case cast event of Just (Message s) - putStrLn $ show s Nothing - return () * gives me a: * Ambiguous type variable `t0' in the constraint: (Typeable t0) arising from a use of `cast' Probable fix: add a type signature that fixes these type variable(s) In the expression: cast event In the expression: case cast event of { Just (Message s) - putStrLn $ show s Nothing - return () }* This is because *Message* has a type variable, while *Player* has not... How to get this to work? I tried everything, existential types, scoped type variables etc. without success... Thanks!! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type variable in class instance
Hi Stephen, I wasn't aware of Data.Dynamic. I tried: *viewEvent :: Dynamic - IO () viewEvent event = do case fromDynamic event of Nothing - return () Just (Message s) - putStrLn $ show s* But still got the same error (Ambiguous type variable `t0' in the constraint: (Typeable t0) arising from a use of `fromDynamic')... Best, Corentin On Mon, Sep 10, 2012 at 11:33 PM, Stephen Tetley stephen.tet...@gmail.comwrote: Whilst dynamic typing isn't idiomatic for Haskell, it seems like you've decided you want it. So why not use Data.Dynamic rather than roll you're own dynamic typing with Typeable? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] happstack simpleHTTP state monad
Hi all, I'm trying to make a web server that manages its own state. The user can issue commands that modifies the state. I did like below but unfortunatly the state is not keep after a command is issued... What is the right way to do it? Is there any example sites with an internal state with happstack? *data Game = (the state of my game) type NomicServer = ServerPartT (StateT Game IO) launchWebServer :: Game - IO () launchWebServer initialState = do putStrLn Starting web server...\nTo connect, drive your browser to \ http://localhost:8000/Login\; d - getDataDir simpleHTTP' unpackStateT nullConf $ server d server :: FilePath - ServerPartT (StateT Game IO) Response server d sh = mconcat [fileServe [] d, do decodeBody (defaultBodyPolicy /tmp/ 4096 4096 4096) html - implSite http://localhost:8000/; nomicSite return $ toResponse html] unpackStateT:: Game - UnWebT (StateT Game IO) Response - UnWebT IO Response unpackStateT g w = evalStateT w g --handler for web routes nomicSite :: Site PlayerCommand (NomicServer Html) nomicSite = setDefault (Noop 0) Site { handleSite = \f url - unRouteT (routedNomicCommands url) f , formatPathSegments = \u - (toPathSegments u, []) , parsePathSegments = parseSegments fromPathSegments }* Thanks a lot, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] happstack simpleHTTP state monad
Hi Erik, yes you're right, I'm experimenting with an IORef now (a TVar would be a better idea). I also tried the idea expressed here, to keep the state: https://groups.google.com/forum/?fromgroups=#!msg/happs/_JSpaJKub0k/oa0K01IBlh0J But without success so far. The server is returning me the state in the Response type but I cannot manage to reinject it for the next call :) Best, Corentin On Thu, Aug 30, 2012 at 9:47 PM, Erik Hesselink hessel...@gmail.com wrote: The way you wrote it, you run the state transformer once for each request. So the state will be available within a single request, but not between requests. If you want to persist state between requests, you can use one the the mutable variables available (TVar or MVar are good choices; IORefs also work, but you have to take care about concurrency, using e.g. atomicModifyIORef). Create them before calling simpleHTTP, then pass them in to use them in your handler. You can put them in a ReaderT to avoid passing them, if you want. Another choice is to use something like a database or the file system for persistent state. Databases usually handle most concurrency problems for you, while file systems don't. Regards, Erik On Thu, Aug 30, 2012 at 7:29 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi all, I'm trying to make a web server that manages its own state. The user can issue commands that modifies the state. I did like below but unfortunatly the state is not keep after a command is issued... What is the right way to do it? Is there any example sites with an internal state with happstack? data Game = (the state of my game) type NomicServer = ServerPartT (StateT Game IO) launchWebServer :: Game - IO () launchWebServer initialState = do putStrLn Starting web server...\nTo connect, drive your browser to \http://localhost:8000/Login\; d - getDataDir simpleHTTP' unpackStateT nullConf $ server d server :: FilePath - ServerPartT (StateT Game IO) Response server d sh = mconcat [fileServe [] d, do decodeBody (defaultBodyPolicy /tmp/ 4096 4096 4096) html - implSite http://localhost:8000/; nomicSite return $ toResponse html] unpackStateT:: Game - UnWebT (StateT Game IO) Response - UnWebT IO Response unpackStateT g w = evalStateT w g --handler for web routes nomicSite :: Site PlayerCommand (NomicServer Html) nomicSite = setDefault (Noop 0) Site { handleSite = \f url - unRouteT (routedNomicCommands url) f , formatPathSegments = \u - (toPathSegments u, []) , parsePathSegments = parseSegments fromPathSegments } Thanks a lot, Corentin ___ 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] every Friday the 13th at midnight...
Hello! I'm looking for a library to be able to express, store and retrieve recurring appointments, like every Monday at midnight. I saw Data.Time.Recurrence, which has a nice language, but how to store the appointments? A command like: *now - getCurrentTime recur daily `begin` now* produces an infinite list of UTCTime. Best, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] every Friday the 13th at midnight...
Yes, this is what I need, but to try to serialize invocations of recur would be equivalent to roll my own implementation of iCalendar (RFC 5545)... Is there an implemention of iCalendar (parser, writer) in Haskell? What I want to do is a sort of scheduler: triggering regular tasks a bit like cron. Is there a high-level scheduler in the libraries? For example I would pass it a list of UTCTimes and it wakes me up for my next appointment :) Best, Corentin On Fri, Jul 27, 2012 at 5:14 PM, Brandon Allbery allber...@gmail.comwrote: On Fri, Jul 27, 2012 at 5:50 AM, Corentin Dupont corentin.dup...@gmail.com wrote: I'm looking for a library to be able to express, store and retrieve recurring appointments, like every Monday at midnight. I saw Data.Time.Recurrence, which has a nice language, but how to store the appointments? A command like: *now - getCurrentTime recur daily `begin` now* produces an infinite list of UTCTime. You need to define your own serialization for its structures. If recur can't be serialized directly, your serialization needs to have a way to represent an invocation of recur instead of trying to store its result. This probably isn't provided because different people/applications have different serialization needs, and it's quite easy to roll the serialization yourself given the library as a starting point. -- brandon s allbery allber...@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] existential types and cast
Hi Paolino, the user can add as many handlers he wants for each event. When a event is triggered along with a data, all handlers associated to that event should be triggered and passed the data. The trick is, there is one type of data associated with each event. That's why I cannot use a Event datatype: how to associate a data type to each event value? This would be some sort of dependant typing if I'm not mistaken. That's why my events exists both on type level and value level: *data NewPlayer = NewPlayer *wich allows me to associate it a type of data with type indexing.*.. * Regards Corentin On Wed, Jul 4, 2012 at 12:58 PM, Paolino paolo.verone...@gmail.com wrote: Hi How many handlers for each type of event in the list of handlers ? If you have only one handler for each type , it should go in the typeclass, and you don't need typeable. If you have more than one maybe you can avoid using type indexing at all, because it doesn't resolve the handler selection issue. By the way , it's not clear to me why you don't have a simple Event datatype describing all the possible events in advance. Regards paolino 2012/7/3 Corentin Dupont corentin.dup...@gmail.com Hi all, I read somewhere (here: http://stackoverflow.com/questions/2300275/how-to-unpack-a-haskell-existential-type) that it's bad to try to unbox an existential type using a cast. OK, but without I really can't figure out how to do what I want: *data NewPlayer = NewPlayer deriving (Typeable, Eq) data NewRule = NewRule deriving (Typeable, Eq) class (Eq e, Typeable e) = Event e where data EventData e instance Event NewPlayer where data EventData NewPlayer = P Int instance Event NewRule where data EventData NewRule = R Int instance Typeable1 EventData where typeOf1 _ = mkTyConApp (mkTyCon EventData) [] data EventHandler = forall e . (Event e) = EH e (EventData e - IO ()) addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return ()* How to remove the casts from triggerEvent? All that I want is to apply the handler found on the data passed in parameter. I tried to add a function apply in the class, without success: *apply :: (EventData e - IO ()) - (EventData e) - IO () apply = ($)* Thanks! Corentin ___ 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] existential types and cast
Thanks Paolino, I will try to see how I can use your implementation! Corentin On Wed, Jul 4, 2012 at 9:24 PM, Paolino paowolo.verone...@gmail.compaolo.verone...@gmail.com wrote: Hi Corentin, This is how I would model your request (without concrete constructors for Player and Rule) I'm sure there are better descriptions also as I'm not an expert. paolino {-# LANGUAGE DataKinds, GADTs, KindSignatures #-} data Player data Rule data Data = Player | Rule data EventKind = Action | Reaction data Event :: EventKind - * where NewPlayer :: Player - Event Action NewRule:: Rule - Event Action NewHandler :: (Event Action - IO ()) - Event Reaction handle :: Event Action - Event Reaction - IO () handle x (NewHandler f) = f x reaction :: Event a - [Event Reaction] - IO [Event Reaction] reaction f@(NewHandler _) es = return $ f:es reaction p@(NewPlayer _) es = mapM_ (handle p) es return es reaction r@(NewRule _) es = mapM_ (handle r) es return es 2012/7/4 Corentin Dupont corentin.dup...@gmail.com Hi, for example, in my game (Nomic) if a new player arrives, I trigger a NewPlayer event. All handlers registered for that event should be triggered, and passed a structure Player containing all the infos of the incoming player. If there is a new rule submitted, that the same: the event NewRule is triggered and the handlers are passed a structure Rule. Thus I want the handlers registered on NewPlayer to have the type Player - xxx, and on NewRule to have the type Rule - xxx. I want to be able to associate an arbitrary data type (here Player and Rule) to an event. The handlers are inherently of different types, but I want to store them in a unique list hence the existential... On Wed, Jul 4, 2012 at 4:33 PM, Paolino paolo.verone...@gmail.comwrote: Hi Corentin, If you could explain *why* there should be a type associated to each event value, it would help, maybe. If it's a design choice , maybe it's wrong design. One reason to use dynamic typing would be to plug in new type of events. But if you already have the events semantics , this is not useful. If the language of events is complex , possibly recursive, you can use GADTs to enforce their validity by construction and you don't need to typefy the event values, but some of their characteristics. Remember type machinery is good to give correctness at the compilation time which Typeable defeats moving checks at runtime. So lifting values to types and eliminating this information with existentials and casting seems wrong. paolino 2012/7/4 Corentin Dupont corentin.dup...@gmail.com Hi Paolino, the user can add as many handlers he wants for each event. When a event is triggered along with a data, all handlers associated to that event should be triggered and passed the data. The trick is, there is one type of data associated with each event. That's why I cannot use a Event datatype: how to associate a data type to each event value? This would be some sort of dependant typing if I'm not mistaken. That's why my events exists both on type level and value level: *data NewPlayer = NewPlayer * wich allows me to associate it a typf data with type indexing.*.. * Regards Corentin On Wed, Jul 4, 2012 at 12:58 PM, Paolino paolo.verone...@gmail.comwrote: Hi How many handlers for each type of event in the list of handlers ? If you have only one handler for each type , it should go in the typeclass, and you don't need typeable. If you have more than one maybe you can avoid using type indexing at all, because it doesn't resolve the handler selection issue. By the way , it's not clear to me why you don't have a simple Event datatype describing all the possible events in advance. Regards paolino 2012/7/3 Corentin Dupont corentin.dup...@gmail.com Hi all, I read somewhere (here: http://stackoverflow.com/questions/2300275/how-to-unpack-a-haskell-existential-type) that it's bad to try to unbox an existential type using a cast. OK, but without I really can't figure out how to do what I want: *data NewPlayer = NewPlayer deriving (Typeable, Eq) data NewRule = NewRule deriving (Typeable, Eq) class (Eq e, Typeable e) = Event e where data EventData e instance Event NewPlayer where data EventData NewPlayer = P Int instance Event NewRule where data EventData NewRule = R Int instance Typeable1 EventData where typeOf1 _ = mkTyConApp (mkTyCon EventData) [] data EventHandler = forall e . (Event e) = EH e (EventData e - IO ()) addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return ()* How
Re: [Haskell-cafe] existential types and cast
Hi, for example, in my game (Nomic) if a new player arrives, I trigger a NewPlayer event. All handlers registered for that event should be triggered, and passed a structure Player containing all the infos of the incoming player. If there is a new rule submitted, that the same: the event NewRule is triggered and the handlers are passed a structure Rule. Thus I want the handlers registered on NewPlayer to have the type Player - xxx, and on NewRule to have the type Rule - xxx. I want to be able to associate an arbitrary data type (here Player and Rule) to an event. The handlers are inherently of different types, but I want to store them in a unique list hence the existential... On Wed, Jul 4, 2012 at 4:33 PM, Paolino paolo.verone...@gmail.com wrote: Hi Corentin, If you could explain *why* there should be a type associated to each event value, it would help, maybe. If it's a design choice , maybe it's wrong design. One reason to use dynamic typing would be to plug in new type of events. But if you already have the events semantics , this is not useful. If the language of events is complex , possibly recursive, you can use GADTs to enforce their validity by construction and you don't need to typefy the event values, but some of their characteristics. Remember type machinery is good to give correctness at the compilation time which Typeable defeats moving checks at runtime. So lifting values to types and eliminating this information with existentials and casting seems wrong. paolino 2012/7/4 Corentin Dupont corentin.dup...@gmail.com Hi Paolino, the user can add as many handlers he wants for each event. When a event is triggered along with a data, all handlers associated to that event should be triggered and passed the data. The trick is, there is one type of data associated with each event. That's why I cannot use a Event datatype: how to associate a data type to each event value? This would be some sort of dependant typing if I'm not mistaken. That's why my events exists both on type level and value level: *data NewPlayer = NewPlayer * wich allows me to associate it a typf data with type indexing.*.. * Regards Corentin On Wed, Jul 4, 2012 at 12:58 PM, Paolino paolo.verone...@gmail.comwrote: Hi How many handlers for each type of event in the list of handlers ? If you have only one handler for each type , it should go in the typeclass, and you don't need typeable. If you have more than one maybe you can avoid using type indexing at all, because it doesn't resolve the handler selection issue. By the way , it's not clear to me why you don't have a simple Event datatype describing all the possible events in advance. Regards paolino 2012/7/3 Corentin Dupont corentin.dup...@gmail.com Hi all, I read somewhere (here: http://stackoverflow.com/questions/2300275/how-to-unpack-a-haskell-existential-type) that it's bad to try to unbox an existential type using a cast. OK, but without I really can't figure out how to do what I want: *data NewPlayer = NewPlayer deriving (Typeable, Eq) data NewRule = NewRule deriving (Typeable, Eq) class (Eq e, Typeable e) = Event e where data EventData e instance Event NewPlayer where data EventData NewPlayer = P Int instance Event NewRule where data EventData NewRule = R Int instance Typeable1 EventData where typeOf1 _ = mkTyConApp (mkTyCon EventData) [] data EventHandler = forall e . (Event e) = EH e (EventData e - IO ()) addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return ()* How to remove the casts from triggerEvent? All that I want is to apply the handler found on the data passed in parameter. I tried to add a function apply in the class, without success: *apply :: (EventData e - IO ()) - (EventData e) - IO () apply = ($)* Thanks! Corentin ___ 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] event handler
OK, so here's my last attempt. What do you think? The Event class is optional (it works without because of EventData is enforcing the use of the right types) however, I find it more clear because it clearly specifies which types are events. * data NewPlayer = NewPlayer deriving (Typeable, Eq) data NewRule = NewRule deriving (Typeable, Eq) class (Eq e, Typeable e) = Event e instance Event NewPlayer instance Event NewRule data family EventData e data instance EventData NewPlayer = P Int data instance EventData NewRule = R Int instance Typeable1 EventData where typeOf1 _ = mkTyConApp (mkTyCon EventData) [] data EventHandler = forall e . (Event e) = EH e (EventData e - IO ()) addEvent :: (Event e) = e - (EventData e - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Event e) = e - (EventData e) - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return () -- TESTS h1 :: EventData NewPlayer - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: EventData NewRule - IO () h2 (R a) = putStrLn $ New Rule ++ (show a) eventList1 = addEvent NewPlayer h1 [] eventList2 = addEvent NewRule h2 eventList1 trigger1 = triggerEvent NewPlayer (P 1) eventList2 --Yelds Welcome Player 1! trigger2 = triggerEvent NewRule (R 2) eventList2 --Yelds New Rule 2 * Thanks again!! Corentin On Sun, Jun 17, 2012 at 12:46 AM, Alexander Solla alex.so...@gmail.comwrote: On Sat, Jun 16, 2012 at 3:31 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi Alexander, sorry my initial example was maybe misleading. What I really what to do is to associate each event with an arbitrary data type. For example, consider the following events: NewPlayer NewRule Message User I want to associate the following data types with each, to pass to there respective handlers: NewPlayer --- Player NewRule --- Rule Message --- String User --- String Message and User have the same data type associated, that's why we can't use this type as a key to index the event... In that case, you definitely want FunctionalDependencies or TypeFamilies, and will probably want to drop the constraint (Handler e d) on Event e (if it doesn't work), and maybe enforce it with explicit exports. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] event handler
Just wondering, could type families be of any help here? I don't know type families, but can it be a mean to regroup together the event types, that are now completely separated : *data NewPlayer deriving Typeable data NewRule deriving Typeable* On Fri, Jun 15, 2012 at 10:59 PM, Corentin Dupont corentin.dup...@gmail.com wrote: I made some modifications based on your suggestions (see below). I made a two parameters class: *class (Typeable e, Typeable d) = Handled e d * Because after all what I want is to associate an event with its type parameters. I don't know why I cannot implement you suggestion to restrict the instances of Event: *data **(Handled e d) = **Event e = Event deriving (Typeable, Eq) *gives me a *Not in scope: type variable `d'* But apart from that it works very well! It's quite a nice interface! Also just to know, is there a way of getting ride of all these Typeable? {-# LANGUAGE ExistentialQuantification, DeriveDataTypeable, MultiParamTypeClasses #-} *module Events (addEvent, newPlayer, newRule) where import Control.Monad import Data.List import Data.Typeable newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event e = Event deriving (Typeable, Eq) data NewPlayer deriving Typeable data NewRule deriving Typeable newPlayer :: Event NewPlayer newPlayer = Event newRule :: Event NewRule newRule = Event class (Typeable e, Typeable d) = Handled e d instance Handled NewPlayer Player instance Handled NewRule Rule data EventHandler = forall e d . (Handled e d) = EH (Event e) (d - IO ()) addEvent :: (Handled e d) = Event e - (d - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled e d) = Event e - d - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return () -- TESTS h1 :: Player - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: Rule - IO () h2 (R a) = putStrLn $ New Rule ++ (show a) eventList1 = addEvent newPlayer h1 [] eventList2 = addEvent newRule h2 eventList1 trigger1 = triggerEvent newPlayer (P 1) eventList2 --Yelds Welcome Player 1! trigger2 = triggerEvent newRule (R 2) eventList2 --Yelds New Rule 2 * On Fri, Jun 15, 2012 at 4:53 PM, Alexander Solla alex.so...@gmail.comwrote: On Fri, Jun 15, 2012 at 6:38 AM, Corentin Dupont corentin.dup...@gmail.com wrote: It just bothers me a little that I'm not able to enumerate the events, and also that the user is able to create events with wrong types (like New :: Event String), even if they won't be able to register them. This can be solved with an explicit export list/smart constructors. newPlayer :: Event Player newRule:: Event Rule (hide the New constructor) In any case, my thinking was that your original data Event = *NewPlayer | NewRule* * * was basically trying to join the semantics of new things with Player and Rule. But the original approach ran into the problem you mention below -- it is difficult to maintain invariants, since the types want to multiply. So formally, I factored: data Event = NewPlayer | NewRule == data Event = New (Player | Rule)== data Event d = New -- (since the original event didn't want a Player or Rule value. It witnessed the type relation) On the other hand, if you want to make sure that a type must be Handled before you can issue an Event, you can do: data (Handled d) = Evend d = New I'm pretty sure the compiler will complain if you try to make a (New :: Event String). I like this idea better than smart constructors for events, if only because you get to use ScopedTypeVariables. I also have several unrelated events that use the same type of data, so this would be a problem. Can you clarify? I mean that I have events like: Message String UserEvent String That have a data of the same type, but they are not related. Adding more events like *data Event d = NewPlayer | NewRule deriving (Typeable, Eq)* is not correct because I can add wrong events like: addEvent (NewPlayer :: Event Rule) (H(undefined::(Rule - IO( [] ** Also one question: I don't understand the where clause in your class. If I remove it, it works the same... Yes, unnecessary where clauses are optional. Here is my code: *newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event d = New deriving (Typeable, Eq) class (Typeable d) = Handled d where data Handler d = H (d - IO ()) data EventHandler = forall d . (Handled d) = EH (Event d) (Handler d) instance Handled Player instance Handled Rule addEvent :: (Handled d) = Event d - Handler d - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled d) = Event d - d - [EventHandler
Re: [Haskell-cafe] event handler
Hi Alexander, sorry my initial example was maybe misleading. What I really what to do is to associate each event with an arbitrary data type. For example, consider the following events: NewPlayer NewRule Message User I want to associate the following data types with each, to pass to there respective handlers: NewPlayer --- Player NewRule --- Rule Message --- String User --- String Message and User have the same data type associated, that's why we can't use this type as a key to index the event... On Sun, Jun 17, 2012 at 12:04 AM, Alexander Solla alex.so...@gmail.comwrote: On Fri, Jun 15, 2012 at 1:59 PM, Corentin Dupont corentin.dup...@gmail.com wrote: I made some modifications based on your suggestions (see below). I made a two parameters class: *class (Typeable e, Typeable d) = Handled e d * Because after all what I want is to associate an event with its type parameters. I think our approaches are diverging. In particular, I don't think you want to use both newPlayer :: Event Player newRule:: Event Rule and also data NewPlayer data NewRule without a very good reason. These are representations of the same relationship (the attachment/joining of New Event semantics to a Player or Rule) at different levels in the abstraction hierarchy. All Handled e d type class is doing is attempting to (1) constrain some types, (2) equate/join NewPlayer and newPlayer (as far as I can see), which would be unnecessary without either NewPlayer or newPlayer. That said, you can definitely have a good reason I'm not aware of. So what is your use case for NewPlayer, for example? I don't know why I cannot implement you suggestion to restrict the instances of Event: *data **(Handled e d) = **Event e = Event deriving (Typeable, Eq) *gives me a *Not in scope: type variable `d'* Yeah, that's undecidable. What would happen if you had instance Handled NewPlayer instance Handled NewRule and you tried to make an (Event Player)? The compiler couldn't decide between the instances. In principle, functional dependencies (or type families, as you mentioned) would make d depend on e uniquely, but I don't think the data declaration is smart enough to figure it out, since it appears to be using scoping rules to deal with the possibility of undecidability. If you want to try, the syntax would be: {-# LANGUAGE FunctionalDependencies #-} class Handled e d | e - d where -- ... Of course, apparently the situation with multiple conflicting instances should never happen if you use NewPlayer and NewRule and so on. But that compiler can't know it unless you tell it somehow. But apart from that it works very well! It's quite a nice interface! Also just to know, is there a way of getting ride of all these Typeable? Yes, but you would just be re-inventing the wheel. I pretty much constantly keep deriving (Data, Eq, Ord, Show, Typeable) in my clipboard. I don't use Typeable (or Data), but useful libraries do. For example, SafeCopy. I mean that I have events like: Message String UserEvent String That have a data of the same type, but they are not related. Using my old version of the code for reference, nothing is stopping you from doing: data Event e = New | Message String | User String {-# LANGUAGE ExistentialQuantification, DeriveDataTypeable, MultiParamTypeClasses #-} *module Events (addEvent, newPlayer, newRule) where import Control.Monad import Data.List import Data.Typeable newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event e = Event deriving (Typeable, Eq) data NewPlayer deriving Typeable data NewRule deriving Typeable newPlayer :: Event NewPlayer newPlayer = Event newRule :: Event NewRule newRule = Event class (Typeable e, Typeable d) = Handled e d instance Handled NewPlayer Player instance Handled NewRule Rule data EventHandler = forall e d . (Handled e d) = EH (Event e) (d - IO ()) addEvent :: (Handled e d) = Event e - (d - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled e d) = Event e - d - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return () -- TESTS h1 :: Player - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: Rule - IO () h2 (R a) = putStrLn $ New Rule ++ (show a) eventList1 = addEvent newPlayer h1 [] eventList2 = addEvent newRule h2 eventList1 trigger1 = triggerEvent newPlayer (P 1) eventList2 --Yelds Welcome Player 1! trigger2 = triggerEvent newRule (R 2) eventList2 --Yelds New Rule 2 * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] event handler
Hi, it works very well! I tried to implement it. Here is my test code. Apparently I need some casts to search the list. The syntax looks good. Only addEvent will be on the interface, so that should be fine. If I understand well, that's this function that enforces the right types to be used. The events are referenced via the type of data they use. It just bothers me a little that I'm not able to enumerate the events, and also that the user is able to create events with wrong types (like New :: Event String), even if they won't be able to register them. I also have several unrelated events that use the same type of data, so this would be a problem. Adding more events like *data Event d = NewPlayer | NewRule deriving (Typeable, Eq)* is not correct because I can add wrong events like: addEvent (NewPlayer :: Event Rule) (H(undefined::(Rule - IO( [] ** Also one question: I don't understand the where clause in your class. If I remove it, it works the same... Here is my code: *newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event d = New deriving (Typeable, Eq) class (Typeable d) = Handled d where data Handler d = H (d - IO ()) data EventHandler = forall d . (Handled d) = EH (Event d) (Handler d) instance Handled Player instance Handled Rule addEvent :: (Handled d) = Event d - Handler d - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled d) = Event d - d - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ (H h)) - case cast h of Just castedH - castedH d Nothing - return () h1 :: Player - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: Rule - IO () h2 (R a) = putStrLn $ New Rule ++ (show a) eventList1 = addEvent (New :: Event Player) (H h1) [] eventList2 = addEvent (New :: Event Rule) (H h2) eventList1 trigger1 = triggerEvent (New :: Event Player) (P 1) eventList2 -- yelds Welcome Player 1! trigger2 = triggerEvent (New :: Event Rule) (R 2) eventList2 --yelds New Rule* 2 Best, Corentin On Fri, Jun 15, 2012 at 12:40 AM, Alexander Solla alex.so...@gmail.comwrote: On Thu, Jun 14, 2012 at 2:04 PM, Corentin Dupont corentin.dup...@gmail.com wrote: That look really nice! Unfortunately I need to have an heterogeneous list of all events with their handlers. With this test code it won't compile: test1 = addEvent (New :: Event Player) (H (undefined::(Player - IO ( [] test2 = addEvent (New :: Event Rule) (H (undefined::(Rule - IO ( test1 Right, okay. Heterogenous lists are tricky, but I think we can get away with using ExistentialQuantification, since you seem to only want to dispatch over the heterogenous types. The assumption I made is a big deal! It means you can't extract the d value. You can only apply properly typed functions (your handlers) on it. * {-# LANGUAGE ExistentialQuantification #-} * * type Player = Int * * type Rule = Int * * data Event d = New d * * * *class Handled data where -- Together with EventHandler, corresponds to your Data type* * * *data EventHandler = forall d . (Handled d) = EH (Event d) (d - IO ()) -- EventHandler takes the place of your (Event d, Handler d) pairs without referring to d.* * * *instance Handled Player* *instance Handled Rule* *addEvent :: (Handled d) = Event d - Handler d - [EventHandler] - [EventHandler] -- Every [EventHandler] made using addEvent will be of correct types (i.e., preserve the typing invariants you want), but YOU must ensure that only [EventHandler]s made in this way are used. This can be done statically with another type and an explicit export list. We can talk about that later, if this works in principle.* *triggerEvent :: (Handled d) = Event d - d - [EventHandler] - IO ()* ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] event handler
I made some modifications based on your suggestions (see below). I made a two parameters class: *class (Typeable e, Typeable d) = Handled e d * Because after all what I want is to associate an event with its type parameters. I don't know why I cannot implement you suggestion to restrict the instances of Event: *data **(Handled e d) = **Event e = Event deriving (Typeable, Eq) *gives me a *Not in scope: type variable `d'* But apart from that it works very well! It's quite a nice interface! Also just to know, is there a way of getting ride of all these Typeable? {-# LANGUAGE ExistentialQuantification, DeriveDataTypeable, MultiParamTypeClasses #-} *module Events (addEvent, newPlayer, newRule) where import Control.Monad import Data.List import Data.Typeable newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event e = Event deriving (Typeable, Eq) data NewPlayer deriving Typeable data NewRule deriving Typeable newPlayer :: Event NewPlayer newPlayer = Event newRule :: Event NewRule newRule = Event class (Typeable e, Typeable d) = Handled e d instance Handled NewPlayer Player instance Handled NewRule Rule data EventHandler = forall e d . (Handled e d) = EH (Event e) (d - IO ()) addEvent :: (Handled e d) = Event e - (d - IO ()) - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled e d) = Event e - d - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ h) - case cast h of Just castedH - castedH d Nothing - return () -- TESTS h1 :: Player - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: Rule - IO () h2 (R a) = putStrLn $ New Rule ++ (show a) eventList1 = addEvent newPlayer h1 [] eventList2 = addEvent newRule h2 eventList1 trigger1 = triggerEvent newPlayer (P 1) eventList2 --Yelds Welcome Player 1! trigger2 = triggerEvent newRule (R 2) eventList2 --Yelds New Rule 2 * On Fri, Jun 15, 2012 at 4:53 PM, Alexander Solla alex.so...@gmail.comwrote: On Fri, Jun 15, 2012 at 6:38 AM, Corentin Dupont corentin.dup...@gmail.com wrote: It just bothers me a little that I'm not able to enumerate the events, and also that the user is able to create events with wrong types (like New :: Event String), even if they won't be able to register them. This can be solved with an explicit export list/smart constructors. newPlayer :: Event Player newRule:: Event Rule (hide the New constructor) In any case, my thinking was that your original data Event = *NewPlayer | NewRule* * * was basically trying to join the semantics of new things with Player and Rule. But the original approach ran into the problem you mention below -- it is difficult to maintain invariants, since the types want to multiply. So formally, I factored: data Event = NewPlayer | NewRule == data Event = New (Player | Rule)== data Event d = New -- (since the original event didn't want a Player or Rule value. It witnessed the type relation) On the other hand, if you want to make sure that a type must be Handled before you can issue an Event, you can do: data (Handled d) = Evend d = New I'm pretty sure the compiler will complain if you try to make a (New :: Event String). I like this idea better than smart constructors for events, if only because you get to use ScopedTypeVariables. I also have several unrelated events that use the same type of data, so this would be a problem. Can you clarify? I mean that I have events like: Message String UserEvent String That have a data of the same type, but they are not related. Adding more events like *data Event d = NewPlayer | NewRule deriving (Typeable, Eq)* is not correct because I can add wrong events like: addEvent (NewPlayer :: Event Rule) (H(undefined::(Rule - IO( [] ** Also one question: I don't understand the where clause in your class. If I remove it, it works the same... Yes, unnecessary where clauses are optional. Here is my code: *newtype Player = P Int deriving Typeable newtype Rule = R Int deriving Typeable data Event d = New deriving (Typeable, Eq) class (Typeable d) = Handled d where data Handler d = H (d - IO ()) data EventHandler = forall d . (Handled d) = EH (Event d) (Handler d) instance Handled Player instance Handled Rule addEvent :: (Handled d) = Event d - Handler d - [EventHandler] - [EventHandler] addEvent e h ehs = (EH e h):ehs triggerEvent :: (Handled d) = Event d - d - [EventHandler] - IO () triggerEvent e d ehs = do let r = find (\(EH myEvent _) - cast e == Just myEvent) ehs case r of Nothing - return () Just (EH _ (H h)) - case cast h of Just castedH - castedH d Nothing - return () h1 :: Player - IO () h1 (P a) = putStrLn $ Welcome Player ++ (show a) ++ ! h2 :: Rule - IO () h2 (R a) = putStrLn $ New Rule ++ (show
[Haskell-cafe] event handler
Hi folks, I'm trying to make a simple event driven engine. It simply consists of two functions: - addEvent, where you pass the event name with a callback, - triggerEvent where you pass the event name with the data. the data shall be passed to the callback of the corresponding event. I have trouble making it correctly typed. Here is my try: * type Player = Int --dummy types for the example type Rule = Int data EventEnum = NewPlayer | NewRule deriving Eq data Data = P Player | R Rule data Handler = H (Data - IO ()) addEvent :: EventEnum - Handler - [(EventEnum, Handler)] - [(EventEnum, Handler)] addEvent e h es = (e,h):es triggerEvent :: EventEnum - Data - [(EventEnum, Handler)] - IO () triggerEvent e d es = do let r = lookup e es case r of Nothing - return () Just (H h) - h d* The trouble is that I want the user to be only able to add an event that is compatible with its handler: For example the event NewPlayer should have a handler of type Player - IO (). The data passed when triggering this event should be only of type Player. How can I do that? It sound like dependant typing... Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] event handler
That look really nice! Unfortunately I need to have an heterogeneous list of all events with their handlers. With this test code it won't compile: test1 = addEvent (New :: Event Player) (H (undefined::(Player - IO ( [] test2 = addEvent (New :: Event Rule) (H (undefined::(Rule - IO ( test1 On Thu, Jun 14, 2012 at 10:05 PM, Alexander Solla alex.so...@gmail.comwrote: On Thu, Jun 14, 2012 at 12:15 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hi folks, I'm trying to make a simple event driven engine. It simply consists of two functions: - addEvent, where you pass the event name with a callback, - triggerEvent where you pass the event name with the data. the data shall be passed to the callback of the corresponding event. I have trouble making it correctly typed. Here is my try: * type Player = Int --dummy types for the example type Rule = Int data EventEnum = NewPlayer | NewRule deriving Eq data Data = P Player | R Rule data Handler = H (Data - IO ()) addEvent :: EventEnum - Handler - [(EventEnum, Handler)] - [(EventEnum, Handler)] addEvent e h es = (e,h):es triggerEvent :: EventEnum - Data - [(EventEnum, Handler)] - IO () triggerEvent e d es = do let r = lookup e es case r of Nothing - return () Just (H h) - h d* The trouble is that I want the user to be only able to add an event that is compatible with its handler: For example the event NewPlayer should have a handler of type Player - IO (). The data passed when triggering this event should be only of type Player. How can I do that? It sound like dependant typing... Haven't tried it, and I don't know if it actually does what you want in the big picture. But you can do dynamic dependent typing with dummy (free) type variables. * type Player = Int --dummy types for the example type Rule = Int data Event d = New deriving Eq -- not necessary for this example, but you might want to enumerate other events. * *class Handled data where -- Corresponds to your Data type * *data Handler d = H (d - IO ())* * * *instance Handled Player* *instance Handled Rule* * * *addEvent :: (Handled d) = Event d - Handler d - [(Event d, Handler d)] - [(Event d, Handler)]* *triggerEvent :: (Handled d) = Event d - d - [(Event d, Handler d)] - IO ()* * * Basically, this means that Events are keyed into separate spaces by the Handled types. (New :: Event Player) has a different type as (New :: Event Rule). You might want to look into ScopedTypeVariables. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] mapping a concept to a type
Hi, I'm still thinking on how I can express neatly two fundamentally aspects of a rule in Nomic. I'm not a lawyer ;) but in my opinion there is two sorts of rules in the legal system of any countries: - The rules that say *what* is legal or illegal. - The rules that say *how* to enforce the first (from what date, by whom, is it retro-active, what is the penalty if you infringe it etc.). These rules can be an application decree, for example. In computing terms, the first rules can be called functional rules whereas the second are procedural rules. Among the functional rules, there are the meta rules as said before, rules that are able to judge the legality of another rule. I'm trying to find an adequate type to embrace all this family. Up to now, I came up with: //functional and procedural rule types newtype FuncRule legalizable = FuncRule {unRule :: legalizable → State Game Bool} type ProcRule = State Game () data RuleFunc2 legalizable = FR (FuncRule legalizable) | PR ProcRule //a meta rule is a functional rule type MetaRule = FuncRule Rule What do you think? I've made a design document of the complete game if you need more context: https://github.com/cdupont/Nomic/blob/master/Nomic/doc/Haskell%20Nomic%20EN.docx At the beginning of the development, the rules where only functional and stateless. That was nice because the engine was able to execute them whenever. Now they are becoming more and more stateful (for example a rule can create a bank account, or be executed on event). This make handling them much more complex!! I'm wondering what middle way I can choose. Corentin On Sat, May 19, 2012 at 1:06 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes I totally agree, they have different kind. A Normal Rule is * whereas a Meta Rule is * - *. But I have no experience with typeclasses. That could be what I'm looking for! What they have in common? Well, Id' say that a rule (whatever sort it is) can: - change the state of the game when executed - hence the State Transformer - perhaps assess the legality of *something* (including the legality of another rule) So this gives: class (Monad r) = (Rule r) where changeState :: StateT Game r () legal :: l - r Bool legal _ = return True Does that sound good? I will continue experiment with it tomorrow. My other comment inline: On Sat, May 19, 2012 at 12:02 AM, Ben Doyle benjamin.peter.do...@gmail.com wrote: I wonder if you want a typeclass here, rather than a type? A Normal Rule is pretty much a State Transformer, while a Meta Rule seems like a higher-order function on Normal Rules[*]. These are different kinds of things --- and I say kind advisedly --- so perhaps better to define the specific commonalities you need than to try to shoehorn them both into one type. [*]: Possibly related question: Can a Meta Rule depend upon an implementation detail of a Normal rule? That's a very good question. I think the answer is yes. In other words, does rule1 g == rule2 g imply myMetaRule rule1 == myMetaRule rule2 ? So this does not hold. Here myMetaRule is analysing the legality of rule1, possibly analysing the code of rule1 (quite simply for now). (To make thinks clear, the type of myMetaRule rule1 is a monadic boolean). Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] mapping a concept to a type
Hi, I'm still thinking on how I can express neatly two fundamentally aspects of a rule in Nomic. I'm not a lawyer but in my opinion there is two sorts of rules in the legal system of any countries: - The rules that say *what* is legal or illegal. - The rules that say *how* to enforce the first (from what date, by whom, is it retro-active, what is the penalty if you infringe it etc.). These rules can be an application decree, for example. In computing terms, the first rules can be called functional rules whereas the second are procedural rules. Among the functional rules, there are the meta rules as said before, rules that are able to judge the legality of another rule. I'm trying to find an adequate type to embrace all this family. Up to now, I came up with: //functional and procedural rule types newtype FuncRule a = FuncRule {unRule :: a → State Game Bool} type ProcRule = State Game () data RuleFunc2 a = FR (FuncRule a) | PR ProcRule //a meta rule is a functional rule type MetaRule = FuncRule Rule What do you think? I've made a design document of the game if you need more context: https://github.com/cdupont/Nomic/blob/master/Nomic/doc/Haskell%20Nomic%20EN.docx At the beginning of the development, the rules where only functional and stateless. That was nice because the engine was able to execute them whenever. Now they are becoming more and more stateful (for example a rule can create a bank account, or create a signal handler for future execution). This make handling them much more complex!! I'm wondering what middle way I can choose. Corentin On Sat, May 19, 2012 at 1:06 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes I totally agree, they have different kind. A Normal Rule is * whereas a Meta Rule is * - *. But I have no experience with typeclasses. That could be what I'm looking for! What they have in common? Well, Id' say that a rule (whatever sort it is) can: - change the state of the game when executed - hence the State Transformer - perhaps assess the legality of *something* (including the legality of another rule) So this gives: class (Monad r) = (Rule r) where changeState :: StateT Game r () legal :: l - r Bool legal _ = return True Does that sound good? I will continue experiment with it tomorrow. My other comment inline: On Sat, May 19, 2012 at 12:02 AM, Ben Doyle benjamin.peter.do...@gmail.com wrote: I wonder if you want a typeclass here, rather than a type? A Normal Rule is pretty much a State Transformer, while a Meta Rule seems like a higher-order function on Normal Rules[*]. These are different kinds of things --- and I say kind advisedly --- so perhaps better to define the specific commonalities you need than to try to shoehorn them both into one type. [*]: Possibly related question: Can a Meta Rule depend upon an implementation detail of a Normal rule? That's a very good question. I think the answer is yes. In other words, does rule1 g == rule2 g imply myMetaRule rule1 == myMetaRule rule2 ? So this does not hold. Here myMetaRule is analysing the legality of rule1, possibly analysing the code of rule1 (quite simply for now). (To make thinks clear, the type of myMetaRule rule1 is a monadic boolean). Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] mapping a concept to a type
Hi everybody, I'm still working on implementing a nomic game in Haskell. Although the game is pretty advanced, I'm still confused by one fundamental question: A nomic game is composed of rules. A Rule is a sort of little program submitted by the player during the game. They come in two fashions: - a Normal rule, when executed, can change the state of the Game. - a Meta rule, when executed on another rule, can assess the legality of that rule and change the state of the Game. In those definitions, the Game can be seen as a data structure containing all the current state of the game. Sorry if it's a bit abstract, but as it's fairly complex, I'd prefer to keep it like this for the moment. Thus, I found that those definitions can be translated to two possible type definitions: type NormalRule = State Game () type MetaRule = Rule - State Game Bool data Rule = MR MetaRule | NR NormalRule *** or *** newtype Rule = Rule {rule :: Maybe Rule - (State Game Bool)} All rules submitted by the user must be of the type Rule. It is thus important that it is very clean. Which type do you prefer? I find both heavy and redundant. The first forces me to specify if I want an argument of not (with the constructors MR and NR), the second forces me to pass the Nothing argument in the case of a Normal rule, and to return a dummy value (for ex. return True). Do you know of a construction/abstraction that allows having or not an argument (a variable number of arguments, here zero or one)? Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] mapping a concept to a type
Yes I totally agree, they have different kind. A Normal Rule is * whereas a Meta Rule is * - *. But I have no experience with typeclasses. That could be what I'm looking for! What they have in common? Well, Id' say that a rule (whatever sort it is) can: - change the state of the game when executed - hence the State Transformer - perhaps assess the legality of *something* (including the legality of another rule) So this gives: class (Monad r) = (Rule r) where changeState :: StateT Game r () legal :: l - r Bool legal _ = return True Does that sound good? I will continue experiment with it tomorrow. My other comment inline: On Sat, May 19, 2012 at 12:02 AM, Ben Doyle benjamin.peter.do...@gmail.com wrote: I wonder if you want a typeclass here, rather than a type? A Normal Rule is pretty much a State Transformer, while a Meta Rule seems like a higher-order function on Normal Rules[*]. These are different kinds of things --- and I say kind advisedly --- so perhaps better to define the specific commonalities you need than to try to shoehorn them both into one type. [*]: Possibly related question: Can a Meta Rule depend upon an implementation detail of a Normal rule? That's a very good question. I think the answer is yes. In other words, does rule1 g == rule2 g imply myMetaRule rule1 == myMetaRule rule2 ? So this does not hold. Here myMetaRule is analysing the legality of rule1, possibly analysing the code of rule1 (quite simply for now). (To make thinks clear, the type of myMetaRule rule1 is a monadic boolean). Thanks! Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: web-routes and forms
Thanks On Sat, Jan 29, 2011 at 11:33 AM, Jasper Van der Jeugt jasper...@gmail.comwrote: Hello, I've backported the `inputHidden` combinator to the 0.0.2 branch, you can find it on hackage as digestive-functors-blaze-0.0.2.2. Hope this helps, Cheers, Jasper On Fri, Jan 28, 2011 at 8:10 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello again, is there a way to had a hidden field in digestive-functor-blaze? I'm using it to transmit some data... Thanks, Corentin On Thu, Jan 27, 2011 at 11:21 AM, Corentin Dupont corentin.dup...@gmail.com wrote: OK thanks, now it's clear! On Thu, Jan 27, 2011 at 11:13 AM, Jasper Van der Jeugt jasper...@gmail.com wrote: Hello, As Jeremy said, the HTML returned by formHtml is meant to be placed inside the a form tag: it does not include a form tag. You should use it like this: H.form ! A.enctype (H.stringValue $ show enctype) ! A.method POST ! A.action / $ do html -- The HTML rendered by formHtml H.input ! A.type_ submit ! A.value Submit (with or without the submit button). Cheers, Jasper On Jan 27, 2011 10:54 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello Jasper, Do you have an idea? Thanks, Corentin -- Forwarded message -- From: Jeremy Shaw jer...@n-heptane.com Date: Thu, Jan 27, 2011 at 2:22 AM Subject: Re: web-routes and forms To: Corentin Dupont corentin.dup...@gmail.com Cc: haskell haskell-cafe@haskell.org On Wed, Jan 26, 2011 at 4:33 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Now turning to digestive functors, I don't see where do goes the A.action actionURL part that was in traditionnal forms? It seems I need it for routing the result of the form. I think you will find formHtml is returning you the stuff that goes inside the form tag, but does not actually include the form tag itself ? I am not sure how to modify the attrs using blaze-html. I think that is a missing feature of the digestive-functors-blaze package. In digestive-functors-hsp there is a function: setAttrs :: (EmbedAsAttr x attr, XMLGenerator x, Monad m, Functor m) = Form m i e [HSX.GenXML x] a - attr - Form m i e [HSX.GenXML x] a setAttrs form attrs = mapView (map (`set` attrs)) form You probably need something similar for blaze. - jeremy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: web-routes and forms
Hello again, is there a way to had a hidden field in digestive-functor-blaze? I'm using it to transmit some data... Thanks, Corentin On Thu, Jan 27, 2011 at 11:21 AM, Corentin Dupont corentin.dup...@gmail.com wrote: OK thanks, now it's clear! On Thu, Jan 27, 2011 at 11:13 AM, Jasper Van der Jeugt jasper...@gmail.com wrote: Hello, As Jeremy said, the HTML returned by formHtml is meant to be placed inside the a form tag: it does not include a form tag. You should use it like this: H.form ! A.enctype (H.stringValue $ show enctype) ! A.method POST ! A.action / $ do html -- The HTML rendered by formHtml H.input ! A.type_ submit ! A.value Submit (with or without the submit button). Cheers, Jasper On Jan 27, 2011 10:54 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello Jasper, Do you have an idea? Thanks, Corentin -- Forwarded message -- From: Jeremy Shaw jer...@n-heptane.com Date: Thu, Jan 27, 2011 at 2:22 AM Subject: Re: web-routes and forms To: Corentin Dupont corentin.dup...@gmail.com Cc: haskell haskell-cafe@haskell.org On Wed, Jan 26, 2011 at 4:33 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Now turning to digestive functors, I don't see where do goes the A.action actionURL part that was in traditionnal forms? It seems I need it for routing the result of the form. I think you will find formHtml is returning you the stuff that goes inside the form tag, but does not actually include the form tag itself ? I am not sure how to modify the attrs using blaze-html. I think that is a missing feature of the digestive-functors-blaze package. In digestive-functors-hsp there is a function: setAttrs :: (EmbedAsAttr x attr, XMLGenerator x, Monad m, Functor m) = Form m i e [HSX.GenXML x] a - attr - Form m i e [HSX.GenXML x] a setAttrs form attrs = mapView (map (`set` attrs)) form You probably need something similar for blaze. - jeremy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] web-routes and forms
Hello Jeremy, Yes it would be fine to use solution 1, but I just don't figured how to mix web routes and forms. My forms are like that: loginForm :: RoutedNomicServer Html loginForm = do ok $ H.form ! A.method POST ! A.action /postLogin ! enctype multipart/form-data;charset=UTF-8 $ do H.label ! for login $ Login input ! type_ text ! name login ! A.id login ! tabindex 1 ! accesskey L H.label ! for password $ Password input ! type_ text ! name password ! A.id password ! tabindex 2 ! accesskey P input ! type_ submit ! tabindex 3 ! accesskey S ! value Enter Nomic! And are decoded using a FromData: instance FromData LoginPass where fromData = do login - look login `mplus` (error need login) password - look password `mplus` (error need password) return $ LoginPass login password How this can go inside web routes? I cannot pass the parameters in the URL (here login and password), can I? Thanks, Corentin On Sat, Jan 22, 2011 at 9:49 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, I believe you problem is because you are trying to use 'dir' inside RouteT after you have already consumed and decode the path info using implSite. There are two solutions here: 1. just use web-routes for all your URLs instead of using a mixture of type-safe routes and 'dir'. 2. put the calls to dir outside the call to implSite. For example, something like, simpleHTTP nullConf $ msum [ dir Login $ loginPage, , dir postLogin $ postLogin , implSite http://localhost:8000/; (nomicSite sh) ] You to do that, you would also need to modified loginPage and postLogin to not be in the RoutedNomicServer monad. Since they do not appear to use the RouteT stuff anyway, that should not be hard ? But, personally, I would just choose option #1. Can you explain why you thought it was better to mix the web-routes stuff with the 'dir' style guards? Maybe there is a short coming in web-routes that needs to be addressed ? - jeremy On Fri, Jan 21, 2011 at 2:33 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello Jeremy, I'm still trying to integrate web routes, but there is one thing I don't understand: how to deal with multiple forms? In my former application, each forms used to redirect to a subdirectory of the web site, and an appropriate handler was waiting there. But now with web routes I don't see how to do that. I've tried to push down the decision over subdirectories (with the guard dir) inside the RouteT monad: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer nomicSite :: ServerHandle - Site PlayerCommand (NomicServer Html) nomicSite sh = setDefault (Noop 0) Site { handleSite = \f url - unRouteT (routedNomicHandle sh url) f , formatPathSegments = \u - (toPathSegments u, []) , parsePathSegments = parseSegments fromPathSegments } routedNomicHandle :: ServerHandle - PlayerCommand - RoutedNomicServer Html routedNomicHandle sh pc = do d - liftRouteT $ liftIO getDataDir msum [dir Login $ loginPage, dir postLogin $ postLogin, --nullDir fileServe [] d, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ routedNomicCommands sh pc] routedNomicCommands :: ServerHandle - PlayerCommand - RoutedNomicServer Html routedNomicCommands sh (Noop pn) = nomicPageComm pn sh (return ()) routedNomicCommands sh (JoinGame pn game) = nomicPageComm pn sh (joinGame game pn) routedNomicCommands sh (LeaveGame pn) = nomicPageComm pn sh (leaveGame pn) routedNomicCommands sh (SubscribeGame pn game) = nomicPageComm pn sh (subscribeGame game pn) routedNomicCommands sh (UnsubscribeGame pn game) = nomicPageComm pn sh (unsubscribeGame game pn) routedNomicCommands sh (Amend pn) = nomicPageComm pn sh (amendConstitution pn) routedNomicCommands sh (DoAction pn an ar) = nomicPageComm pn sh (doAction' an ar pn) routedNomicCommands sh (NewRule pn name text code) = nomicPageComm pn sh (submitRule name text code pn) routedNomicCommands sh (NewGame pn game) = nomicPageComm pn sh (newGame game pn) loginPage :: RoutedNomicServer Html loginPage = do l - loginForm ok $ H.html $ do H.head $ do H.title (H.string Login to Nomic) H.link ! rel stylesheet ! type_ text/css ! href /static/css/nomic.css H.meta ! A.httpEquiv Content-Type ! content text/html;charset=utf-8 H.meta ! A.name keywords ! A.content Nomic, game, rules, Haskell, auto-reference H.body $ do H.div ! A.id container $ do H.div ! A.id header $ Login to Nomic
Re: [Haskell-cafe] web-routes and forms
Hello Jeremy, I'm still trying to integrate web routes, but there is one thing I don't understand: how to deal with multiple forms? In my former application, each forms used to redirect to a subdirectory of the web site, and an appropriate handler was waiting there. But now with web routes I don't see how to do that. I've tried to push down the decision over subdirectories (with the guard dir) inside the RouteT monad: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer nomicSite :: ServerHandle - Site PlayerCommand (NomicServer Html) nomicSite sh = setDefault (Noop 0) Site { handleSite = \f url - unRouteT (routedNomicHandle sh url) f , formatPathSegments = \u - (toPathSegments u, []) , parsePathSegments = parseSegments fromPathSegments } routedNomicHandle :: ServerHandle - PlayerCommand - RoutedNomicServer Html routedNomicHandle sh pc = do d - liftRouteT $ liftIO getDataDir msum [dir Login $ loginPage, dir postLogin $ postLogin, --nullDir fileServe [] d, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ routedNomicCommands sh pc] routedNomicCommands :: ServerHandle - PlayerCommand - RoutedNomicServer Html routedNomicCommands sh (Noop pn) = nomicPageComm pn sh (return ()) routedNomicCommands sh (JoinGame pn game) = nomicPageComm pn sh (joinGame game pn) routedNomicCommands sh (LeaveGame pn) = nomicPageComm pn sh (leaveGame pn) routedNomicCommands sh (SubscribeGame pn game) = nomicPageComm pn sh (subscribeGame game pn) routedNomicCommands sh (UnsubscribeGame pn game) = nomicPageComm pn sh (unsubscribeGame game pn) routedNomicCommands sh (Amend pn) = nomicPageComm pn sh (amendConstitution pn) routedNomicCommands sh (DoAction pn an ar) = nomicPageComm pn sh (doAction' an ar pn) routedNomicCommands sh (NewRule pn name text code) = nomicPageComm pn sh (submitRule name text code pn) routedNomicCommands sh (NewGame pn game) = nomicPageComm pn sh (newGame game pn) loginPage :: RoutedNomicServer Html loginPage = do l - loginForm ok $ H.html $ do H.head $ do H.title (H.string Login to Nomic) H.link ! rel stylesheet ! type_ text/css ! href /static/css/nomic.css H.meta ! A.httpEquiv Content-Type ! content text/html;charset=utf-8 H.meta ! A.name keywords ! A.content Nomic, game, rules, Haskell, auto-reference H.body $ do H.div ! A.id container $ do H.div ! A.id header $ Login to Nomic H.div ! A.id login $ l H.div ! A.id footer $ footer loginForm :: RoutedNomicServer Html loginForm = do ok $ H.form ! A.method POST ! A.action /postLogin ! enctype multipart/form-data;charset=UTF-8 $ do H.label ! for login $ Login input ! type_ text ! name login ! A.id login ! tabindex 1 ! accesskey L H.label ! for password $ Password input ! type_ text ! name password ! A.id password ! tabindex 2 ! accesskey P input ! type_ submit ! tabindex 3 ! accesskey S ! value Enter Nomic! postLogin :: RoutedNomicServer Html postLogin = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: postLogin Just (LoginPass login password) - do mpn - liftRouteT $ liftIO $ newPlayerWeb login password case mpn of Just pn - do link - showURL $ Noop pn seeOther link $ string Redirecting... Nothing - seeOther (/Login?status=fail :: String) $ string Redirecting... launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \ http://localhost:8000/Login\; simpleHTTP nullConf $ implSite http://localhost:8000/; (nomicSite sh) But when I drive my browser to http://localhost:8000/Login/;, happstack tell me there is nothing here. Am I doing it right? If yes, I must have made a mistake. (as you can see I'm still far from putting in disgestive functors ;) If you need, the complete application can be found here (see file Web.hs): https://github.com/cdupont/Nomic Thanks, Corentin On Wed, Jan 19, 2011 at 5:12 PM, Corentin Dupont corentin.dup...@gmail.comwrote: Thanks Jeremy. I had it to work now ;) Corentin On Tue, Jan 18, 2011 at 6:01 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, trhsx will be installed in ~/.cabal/bin, so you will need to add that to your PATH. In order to use the demo code I provided you would need the latest happstack from darcs because it contains a few differences in the API. The code can be made to work with what is on hackage though. The submit issue is actually a bug in digestive-functors-blaze. The return type should be, Form m i e BlazeFormHtml (). jaspervdj is going to patch it and upload a new version. - jeremy On Thu, Jan 13, 2011 at 2:40 PM, Corentin
Re: [Haskell-cafe] Happstack events and web page refreshing
Thanks. There seems to be several technologies to realize this push or polling. Is what you explained feasible on the user's side of happstack-server (I mean, if I can do it myself)? If I take an empty MVar in my ServerPartTs, which are read over client's request, I think that nothing will be sent back to the browser and it will remain blank! Is that to be combined with an HTTP refresh timer on the client side? By sessions, you mean sessions that I create myself for every client connected? Regards, Corentin On Wed, Jan 19, 2011 at 2:21 PM, Bas van Dijk v.dijk@gmail.com wrote: On 17 January 2011 21:50, Jeremy Shaw jer...@n-heptane.com wrote: On Jan 17, 2011, at 2:19 PM, Corentin Dupont wrote: Indeed, I tried with META HTTP-EQUIV=Refresh CONTENT=n ? and it's unusable. It make blink the page, ungrey the stop button for a second and make the fields loose the focus so it's impossible to type in. I'll try with XMLHTTPRequest. Right. Using the jQuery library should make it easier to do ajax requests and modify the DOM on the fly, http://jquery.com/ - jeremy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe A nice variation of polling is long polling: http://en.wikipedia.org/wiki/Push_technology#Long_polling This can easily be accomplished in Haskell by having an MVar per session. Initially an empty MVar is created per new session. When a client makes a request, the server thread that handles the request takes the MVar belonging to the session. This thread will block until the MVar is filled. When the server has an update it will fill all the MVars. This causes all the blocked threads to continue with sending a response to the client notifying it about the update. Like Jeremy said it's a good idea to make these update requests asynchronous. Regards, Bas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] web-routes and forms
Thanks Jeremy. I had it to work now ;) Corentin On Tue, Jan 18, 2011 at 6:01 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, trhsx will be installed in ~/.cabal/bin, so you will need to add that to your PATH. In order to use the demo code I provided you would need the latest happstack from darcs because it contains a few differences in the API. The code can be made to work with what is on hackage though. The submit issue is actually a bug in digestive-functors-blaze. The return type should be, Form m i e BlazeFormHtml (). jaspervdj is going to patch it and upload a new version. - jeremy On Thu, Jan 13, 2011 at 2:40 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello, I'm using the combination happstack + digestive-functors + web-routes + blazeHTML. I'm not finding any examples on the net... I've tried to adapt your example (thanks): type NomicForm a = HappstackForm IO String BlazeFormHtml a demoForm :: NomicForm (Text, Text) demoForm = (,) $ ((TDB.label greeting: ++ inputNonEmpty Nothing) * br) * ((TDB.label noun: ++ inputNonEmpty Nothing) * br) * (submit submit) where br :: NomicForm () br = view H.br -- make sure the fields are not blank, show errors in line if they are inputNonEmpty :: Maybe Text - NomicForm Text inputNonEmpty v = (inputText v `validate` (TD.check You can not leave this field blank. (not . T.null)) ++ errors) But I've got a problem on submit and inputText. I don't see how they are compatible with HappstackForm. NomicForm a reduces to: Form (ServerPartT IO) Input String BlazeFormHtml a whereas the type of submit is: submit :: Monad m = String-- ^ Text on the submit button - Form m String e BlazeFormHtml () -- ^ Submit button Maybe I miss some instance? BTW, I also tried to execute your exemple, but I can't install some packages. cabal install digestive-functors-hsp cabal: Unknown build tool trhsx Whereas trhsx is in my PATH (under linux). You said I need the latest happstack from darcs, why? Cheers, Corentin On Sun, Jan 9, 2011 at 8:36 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, newRule also needs to have the type, RoutedNomicServer. The transformation of RoutedNomicServer into NomicServer is done in the handleSite function. Something like this: nomicSpec :: ServerHandle - Site Route (ServerPartT IO Response) nomicSpec sh = Site { handleSite = \f url - unRouteT (nomicSite sh url) f ... main = do ... simpleHTTP nullConf $ siteImpl (nomicSpec sh) Or something like that -- it's hard to tell exactly what is going on in your app based on the snippets you provided. Also, I highly recommend using digestive functors instead of formlets. It is the successor to formlets. Same core idea, better implementation and actively maintained. I have attached a quick demo of using: happstack+digestive-functors+web-routes+HSP To use it you will need the latest happstack from darcs plus: hsp web-routes web-routes-hsp web-routes-happstack web-routes-mtl digestive-functors digestive-functors-hsp I plan to clean up this example and document it better in the crash course for the upcoming release. Clearly things like the FormInput instance and the formPart function belong a library. let me know if you have more questions. - jeremy On Sat, Jan 8, 2011 at 6:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello, I have difficulties mixing web-routes and forms: I have put routes in all my site, except for forms which remains with the type ServerPartT IO Response. How to make them work together? I have: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer newRule :: ServerHandle - NomicServer Response newRule sh = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: newRule Just (NewRule name text code pn) - do html - nomicPageComm pn sh (submitRule name text code pn)) ok $ toResponse html nomicPageComm :: PlayerNumber - ServerHandle - Comm () - RoutedNomicServer Html nomicPageComm pn sh comm = (..) launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \http://localhost:8000/Login\ http://localhost:8000/Login%5C d - liftIO getDataDir simpleHTTP nullConf $ mconcat [dir postLogin $ postLogin, fileServe [] d, dir Login $ ok $ toResponse $ loginPage, dir NewRule
[Haskell-cafe] Happstack events and web page refreshing
Hello again, I have another question for happstack users/experts: I have a program with happstack-state and a web server with happstack-server. What I'd like is, whenever the MACID state is changed, that the web page is refreshed for every clients connected on the web server. So I think the question is 2 fold: - How to add an event handler on happstack-state for that? - How to ask to the web server to refresh every clients? I did not found infos about that in the API. Thanks a lot, Corentin On Thu, Jan 13, 2011 at 9:40 PM, Corentin Dupont corentin.dup...@gmail.comwrote: Hello, I'm using the combination happstack + digestive-functors + web-routes + blazeHTML. I'm not finding any examples on the net... I've tried to adapt your example (thanks): type NomicForm a = HappstackForm IO String BlazeFormHtml a demoForm :: NomicForm (Text, Text) demoForm = (,) $ ((TDB.label greeting: ++ inputNonEmpty Nothing) * br) * ((TDB.label noun: ++ inputNonEmpty Nothing) * br) * (submit submit) where br :: NomicForm () br = view H.br -- make sure the fields are not blank, show errors in line if they are inputNonEmpty :: Maybe Text - NomicForm Text inputNonEmpty v = (inputText v `validate` (TD.check You can not leave this field blank. (not . T.null)) ++ errors) But I've got a problem on submit and inputText. I don't see how they are compatible with HappstackForm. NomicForm a reduces to: Form (ServerPartT IO) Input String BlazeFormHtml a whereas the type of submit is: submit :: Monad m = String-- ^ Text on the submit button - Form m String e BlazeFormHtml () -- ^ Submit button Maybe I miss some instance? BTW, I also tried to execute your exemple, but I can't install some packages. cabal install digestive-functors-hsp cabal: Unknown build tool trhsx Whereas trhsx is in my PATH (under linux). You said I need the latest happstack from darcs, why? Cheers, Corentin On Sun, Jan 9, 2011 at 8:36 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, newRule also needs to have the type, RoutedNomicServer. The transformation of RoutedNomicServer into NomicServer is done in the handleSite function. Something like this: nomicSpec :: ServerHandle - Site Route (ServerPartT IO Response) nomicSpec sh = Site { handleSite = \f url - unRouteT (nomicSite sh url) f ... main = do ... simpleHTTP nullConf $ siteImpl (nomicSpec sh) Or something like that -- it's hard to tell exactly what is going on in your app based on the snippets you provided. Also, I highly recommend using digestive functors instead of formlets. It is the successor to formlets. Same core idea, better implementation and actively maintained. I have attached a quick demo of using: happstack+digestive-functors+web-routes+HSP To use it you will need the latest happstack from darcs plus: hsp web-routes web-routes-hsp web-routes-happstack web-routes-mtl digestive-functors digestive-functors-hsp I plan to clean up this example and document it better in the crash course for the upcoming release. Clearly things like the FormInput instance and the formPart function belong a library. let me know if you have more questions. - jeremy On Sat, Jan 8, 2011 at 6:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello, I have difficulties mixing web-routes and forms: I have put routes in all my site, except for forms which remains with the type ServerPartT IO Response. How to make them work together? I have: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer newRule :: ServerHandle - NomicServer Response newRule sh = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: newRule Just (NewRule name text code pn) - do html - nomicPageComm pn sh (submitRule name text code pn)) ok $ toResponse html nomicPageComm :: PlayerNumber - ServerHandle - Comm () - RoutedNomicServer Html nomicPageComm pn sh comm = (..) launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \http://localhost:8000/Login\ http://localhost:8000/Login%5C d - liftIO getDataDir simpleHTTP nullConf $ mconcat [dir postLogin $ postLogin, fileServe [] d, dir Login $ ok $ toResponse $ loginPage, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ do html - implSite http://localhost:8000/Nomic/; (nomicSite sh
Re: [Haskell-cafe] Happstack events and web page refreshing
Thanks a lot for your response Jeremy. I can see a lot of site that does update infos without the user to have to click refresh (I think Facebook does?). Do they do polling? I think this approach would be fine for me, my app if not very fast paced. Then I don't need to add a event handler to happstack-state ;) This is done with something like: META HTTP-EQUIV=*Refresh* CONTENT=*n* ? Thanks, Corentin On Mon, Jan 17, 2011 at 5:41 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, The problem is that clients are not 'connected' to the web server. The way it works (more or less) is: 1. client connects to server and sends a Request 2. server sends a Response 3. connection is terminated. So, once the page has been loaded there is no connection between the web-server and the client. Hence there is no way for the server to send anything to the clients. In HTML 5, there is something known as web sockets with does allow you to have a persistent connection to the clients. However, it does not yet have broad browser support. In fact, some browsers have temporarily removed support due to a security flaw in the design specification. There are a variety of hacks collectively known as 'comet' for trying to create a persistent connection on top of the existing HTTP 1.1 standard: http://en.wikipedia.org/wiki/Comet_(programming)http://en.wikipedia.org/wiki/Comet_%28programming%29 That deals with trying to have the server push updates to the client. A different approach is to have the clients pull new data from the server by polling the server for changes every now and then. But that depends on how much latency you can afford for the updates. For example, if updating only once a minute is fine versus must update every second. Once you decide how to get the data to the client, then you can figure out how to track changes to the MACID database. - jeremy On Jan 17, 2011, at 4:58 AM, Corentin Dupont wrote: Hello again, I have another question for happstack users/experts: I have a program with happstack-state and a web server with happstack-server. What I'd like is, whenever the MACID state is changed, that the web page is refreshed for every clients connected on the web server. So I think the question is 2 fold: - How to add an event handler on happstack-state for that? - How to ask to the web server to refresh every clients? I did not found infos about that in the API. Thanks a lot, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Happstack events and web page refreshing
Indeed, I tried with META HTTP-EQUIV=*Refresh* CONTENT=*n* ? and it's unusable. It make blink the page, ungrey the stop button for a second and make the fields loose the focus so it's impossible to type in. I'll try with XMLHTTPRequest. On Mon, Jan 17, 2011 at 6:30 PM, Chris Smith cdsm...@gmail.com wrote: On Mon, 2011-01-17 at 18:25 +0100, Corentin Dupont wrote: Thanks a lot for your response Jeremy. I can see a lot of site that does update infos without the user to have to click refresh (I think Facebook does?). Do they do polling? While I'm not familiar with Facebook, I'd guess that today, most such sites are all doing polling. Especially the high-volume ones, for which leaving a connection open for every current user would be impractical. Polling doesn't have to be done with page refreshes. It can also be done with JavaScript using, e.g., the XMLHTTPRequest object. Then it would be pretty transparent to you. -- Chris ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] web-routes and forms
Hello, I'm using the combination happstack + digestive-functors + web-routes + blazeHTML. I'm not finding any examples on the net... I've tried to adapt your example (thanks): type NomicForm a = HappstackForm IO String BlazeFormHtml a demoForm :: NomicForm (Text, Text) demoForm = (,) $ ((TDB.label greeting: ++ inputNonEmpty Nothing) * br) * ((TDB.label noun: ++ inputNonEmpty Nothing) * br) * (submit submit) where br :: NomicForm () br = view H.br -- make sure the fields are not blank, show errors in line if they are inputNonEmpty :: Maybe Text - NomicForm Text inputNonEmpty v = (inputText v `validate` (TD.check You can not leave this field blank. (not . T.null)) ++ errors) But I've got a problem on submit and inputText. I don't see how they are compatible with HappstackForm. NomicForm a reduces to: Form (ServerPartT IO) Input String BlazeFormHtml a whereas the type of submit is: submit :: Monad m = String-- ^ Text on the submit button - Form m String e BlazeFormHtml () -- ^ Submit button Maybe I miss some instance? BTW, I also tried to execute your exemple, but I can't install some packages. cabal install digestive-functors-hsp cabal: Unknown build tool trhsx Whereas trhsx is in my PATH (under linux). You said I need the latest happstack from darcs, why? Cheers, Corentin On Sun, Jan 9, 2011 at 8:36 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, newRule also needs to have the type, RoutedNomicServer. The transformation of RoutedNomicServer into NomicServer is done in the handleSite function. Something like this: nomicSpec :: ServerHandle - Site Route (ServerPartT IO Response) nomicSpec sh = Site { handleSite = \f url - unRouteT (nomicSite sh url) f ... main = do ... simpleHTTP nullConf $ siteImpl (nomicSpec sh) Or something like that -- it's hard to tell exactly what is going on in your app based on the snippets you provided. Also, I highly recommend using digestive functors instead of formlets. It is the successor to formlets. Same core idea, better implementation and actively maintained. I have attached a quick demo of using: happstack+digestive-functors+web-routes+HSP To use it you will need the latest happstack from darcs plus: hsp web-routes web-routes-hsp web-routes-happstack web-routes-mtl digestive-functors digestive-functors-hsp I plan to clean up this example and document it better in the crash course for the upcoming release. Clearly things like the FormInput instance and the formPart function belong a library. let me know if you have more questions. - jeremy On Sat, Jan 8, 2011 at 6:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello, I have difficulties mixing web-routes and forms: I have put routes in all my site, except for forms which remains with the type ServerPartT IO Response. How to make them work together? I have: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer newRule :: ServerHandle - NomicServer Response newRule sh = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: newRule Just (NewRule name text code pn) - do html - nomicPageComm pn sh (submitRule name text code pn)) ok $ toResponse html nomicPageComm :: PlayerNumber - ServerHandle - Comm () - RoutedNomicServer Html nomicPageComm pn sh comm = (..) launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \http://localhost:8000/Login\ http://localhost:8000/Login%5C d - liftIO getDataDir simpleHTTP nullConf $ mconcat [dir postLogin $ postLogin, fileServe [] d, dir Login $ ok $ toResponse $ loginPage, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ do html - implSite http://localhost:8000/Nomic/; (nomicSite sh) ok $ toResponse html ] The red line doesn't compile. I don't know how to transform a RoutedNomicServer into a NomicServer. For the future I intend to use formlets: is these some examples of programs using happstack + web-routes + formlets? Thanks, Corentin On Fri, Jan 7, 2011 at 5:10 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, The [(String, String)] argument is for adding query parameters. encodePathInfo [foo, bar, baz] [(key,value)] foo/bar/baz?key=value Instead of showURL you would use showURLParams. hope
Re: [Haskell-cafe] web-routes and forms
Hello, after installing digestive-functors-blaze with: cabal install digestive-functors-blaze My prog doesn't compiles anymore: Warning: This package indirectly depends on multiple versions of the same package. This is highly likely to cause a compile failure. Followed by an error on MonadCatchIO. I'm using the following versions: happstack-server-0.5.0.2 mtl-1.1.0.2 blaze-html-0.2.3 web-routes-0.22.0 text-0.7.2.1 But cabal tried to install newer versions for these: mtl-2.0.1.0 blaze-html-0.3.2.1 text-0.11.0.1 I already add this problem in the past, when I tried to update my MTL... With absolutely no success!! I encountered the same sort of problem of multiple versions dependencies. I was unable to solve it. After some research, I followed an advise telling that you should stick with the same version of the libraries during development, so that I did: I went back to the previous versions. Is there a safe way to update some base libraries like MTL and all depending libraries? Would I be able to use digestive-functors with my current set of libraries? Thanks, Corentin On Sun, Jan 9, 2011 at 8:36 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, newRule also needs to have the type, RoutedNomicServer. The transformation of RoutedNomicServer into NomicServer is done in the handleSite function. Something like this: nomicSpec :: ServerHandle - Site Route (ServerPartT IO Response) nomicSpec sh = Site { handleSite = \f url - unRouteT (nomicSite sh url) f ... main = do ... simpleHTTP nullConf $ siteImpl (nomicSpec sh) Or something like that -- it's hard to tell exactly what is going on in your app based on the snippets you provided. Also, I highly recommend using digestive functors instead of formlets. It is the successor to formlets. Same core idea, better implementation and actively maintained. I have attached a quick demo of using: happstack+digestive-functors+web-routes+HSP To use it you will need the latest happstack from darcs plus: hsp web-routes web-routes-hsp web-routes-happstack web-routes-mtl digestive-functors digestive-functors-hsp I plan to clean up this example and document it better in the crash course for the upcoming release. Clearly things like the FormInput instance and the formPart function belong a library. let me know if you have more questions. - jeremy On Sat, Jan 8, 2011 at 6:44 PM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello, I have difficulties mixing web-routes and forms: I have put routes in all my site, except for forms which remains with the type ServerPartT IO Response. How to make them work together? I have: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer newRule :: ServerHandle - NomicServer Response newRule sh = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: newRule Just (NewRule name text code pn) - do html - nomicPageComm pn sh (submitRule name text code pn)) ok $ toResponse html nomicPageComm :: PlayerNumber - ServerHandle - Comm () - RoutedNomicServer Html nomicPageComm pn sh comm = (..) launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \http://localhost:8000/Login\ http://localhost:8000/Login%5C d - liftIO getDataDir simpleHTTP nullConf $ mconcat [dir postLogin $ postLogin, fileServe [] d, dir Login $ ok $ toResponse $ loginPage, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ do html - implSite http://localhost:8000/Nomic/; (nomicSite sh) ok $ toResponse html ] The red line doesn't compile. I don't know how to transform a RoutedNomicServer into a NomicServer. For the future I intend to use formlets: is these some examples of programs using happstack + web-routes + formlets? Thanks, Corentin On Fri, Jan 7, 2011 at 5:10 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, The [(String, String)] argument is for adding query parameters. encodePathInfo [foo, bar, baz] [(key,value)] foo/bar/baz?key=value Instead of showURL you would use showURLParams. hope this helps!d - jeremy On Fri, Jan 7, 2011 at 8:12 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello Jeremy, I'm using Web routes with happstack. I'm following this tutorial: http://tutorialpedia.org/tutorials/Happstack+type+safe+URLs.html But It seems out of synch with the latest version of web-routes
[Haskell-cafe] web-routes and forms
Hello, I have difficulties mixing web-routes and forms: I have put routes in all my site, except for forms which remains with the type ServerPartT IO Response. How to make them work together? I have: type NomicServer = ServerPartT IO type RoutedNomicServer = RouteT PlayerCommand NomicServer newRule :: ServerHandle - NomicServer Response newRule sh = do methodM POST -- only accept a post method mbEntry - getData -- get the data case mbEntry of Nothing - error $ error: newRule Just (NewRule name text code pn) - do *html - nomicPageComm pn sh (submitRule name text code pn))* ok $ toResponse html nomicPageComm :: PlayerNumber - ServerHandle - Comm () - RoutedNomicServer Html nomicPageComm pn sh comm = (..) launchWebServer :: ServerHandle - IO () launchWebServer sh = do putStrLn Starting web server...\nTo connect, drive your browser to \ http://localhost:8000/Login\; d - liftIO getDataDir simpleHTTP nullConf $ mconcat [dir postLogin $ postLogin, fileServe [] d, dir Login $ ok $ toResponse $ loginPage, dir NewRule $ newRule sh, dir NewGame $ newGameWeb sh, dir Nomic $ do html - implSite http://localhost:8000/Nomic/; (nomicSite sh) ok $ toResponse html ] The red line doesn't compile. I don't know how to transform a RoutedNomicServer into a NomicServer. For the future I intend to use formlets: is these some examples of programs using happstack + web-routes + formlets? Thanks, Corentin On Fri, Jan 7, 2011 at 5:10 PM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, The [(String, String)] argument is for adding query parameters. encodePathInfo [foo, bar, baz] [(key,value)] foo/bar/baz?key=value Instead of showURL you would use showURLParams. hope this helps!d - jeremy On Fri, Jan 7, 2011 at 8:12 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Hello Jeremy, I'm using Web routes with happstack. I'm following this tutorial: http://tutorialpedia.org/tutorials/Happstack+type+safe+URLs.html But It seems out of synch with the latest version of web-routes: 0.23.2. The haddock documentation seems out of date also: encodePathInfo :: [String] - [(String, String)] - String For example: encodePathInfo [\foo\, \bar\, \baz\] foo/bar/baz And I can't figure out what this [(String, String)] is for ;) Thanks, Corentin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How can I use MACID in my existing application?
Thanks a lot Jeremy. That was also what I finally understood. I cannot coerce MACID into using my monads. Instead, in each of my methods, I have to extract the update and query parts, put them into different functions, and then register these functions into the MACID system. Well, this is a bit of refactoring ;) Indeed, the game is multithreaded / multiplayer. But only one thread accesses the state of the game (the multiplexing is done before). Perhaps this should be made obvious/enforced by the types. But I'm not yet completely at ease with the STM right now. Perhaps as you suggest this will be a good starting point to first add the checkpoint feature in the soft, then later to migrate it to log every events. Cheers, Corentin On Mon, Nov 8, 2010 at 3:29 AM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, Retrofitting MACID will not be trivial because it makes different assumptions that permeate your code. It sounds like your game is possibly multithreaded / multiplayer. But, the Game is stored the StateT monad. So I assume only one thread updates the GameState ? Is the Game state per-player or is there only one global game state ? In your current app, any code in the GameState monad can update the state at any time, and IO can be freely intermixed. There are no really boundaries separating one state update from another -- it is a continual process with no clear separate events. MACID will be a lot closer to a traditional database where you perform a distinct 'query' operation which updates or reads the state. Each update or query you wanted to perform on the state would become a separate isolated function which gets registered with the transaction system (using mkMethod). You would then perform those transactions using the update and query functions (which run in the IO monad). So you would get rid of the GameState monad, and just have Comm. MACID also deals with the issue of multiple threads trying to update the state -- but that may not be a problem you care about if you only have one thread. One question is, what exactly are you trying to achieve. If you simple want to checkpoint your game state now and then, you could use just happstack-data. It provides versioned binary serialization and migration. That would allow you to save the entire state now and then, and migrate the data when the game state format changed. MACID builds on that to add the ability to log every 'update' event that occurs so that you can replay the events if the server crashes between checkpoints. (It also allows for distributed state across multiple servers). But in order to log an event, the app has to first have things when can be clearly identified as a single 'event'. And you have to be able to replay those events later and arrive at the same final state you did the first time. So, in MACID, your events are *written* in the Update and Query monads. To specific where an 'event' begins and ends, you register some of those functions with MACID using the mkMethods function. The event starts when a registered function is called, and ends when that function returns a value. In order to be sure that the events can be replayed later and arrive at the same result, those events can not perform any IO, because the IO might result in a different answer when replayed. So, to answer your question: You will not directly call functions in the Update monad. And you will not integrated the Update monad into your other monads. Instead you will register the Update and Query functions via mkMethods, and call them in the IO monad via query and update. That is likely to be fairly disruptive to your current design. But it ensures that every event is saved. If you merely want periodic checkpoints, you can use happstack-data and just write the state out periodically. hope this helps! If I have still not answered your question, or you have others, feel free to ask! - jeremy On Nov 7, 2010, at 10:02 AM, Corentin Dupont wrote: Hello Jeremy, thanks for your mail. I am in despair on this problem since days, I would really help your help. I can't figure out how I can add MACID into my program. Here's the problem: I already have monads in my program like that: type Comm = StateT Communication IO type GameState a = StateT Game Comm a Many functions make use of GameState. The only type that need to be serialized is Game. The type Communication contains TChans used for players communication. The IO in Comm is necessary to make some print outs and to use an interpretor when needed (Hint). How can this match with the Update type in Happstack? Thanks a lot for your help. Corentin On Fri, Nov 5, 2010 at 3:50 AM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, I added a brief section to the happstack crash course on using MACID: http://www.happstack.com/docs/crashcourse/HappstackState.html That should hopefully get you started. The example uses
Re: [Haskell-cafe] How can I use MACID in my existing application?
Hello Jeremy, thanks for your mail. I am in despair on this problem since days, I would really help your help. I can't figure out how I can add MACID into my program. Here's the problem: I already have monads in my program like that: type Comm = StateT Communication IO type GameState a = StateT Game Comm a Many functions make use of GameState. The only type that need to be serialized is Game. The type Communication contains TChans used for players communication. The IO in Comm is necessary to make some print outs and to use an interpretor when needed (Hint). How can this match with the Update type in Happstack? Thanks a lot for your help. Corentin On Fri, Nov 5, 2010 at 3:50 AM, Jeremy Shaw jer...@n-heptane.com wrote: Hello, I added a brief section to the happstack crash course on using MACID: http://www.happstack.com/docs/crashcourse/HappstackState.html That should hopefully get you started. The example uses happstack state with happstack server. But there is really no connection between the two. Hope this helps! If you have additional questions, feel free to ask! - j On Thu, Nov 4, 2010 at 12:48 PM, Dupont Corentin corentin.dup...@gmail.com wrote: Hello, I'm wondering how can I use Happstack's MACID in my application without breaking everything. I have a monad like that: type Comm = StateT Communication IO type GameState a = StateT Game Comm a and many functions like: foo :: GameState () foo = do lift $ putComm some message to player's channel modify someAction The state of the game is stored in Game. Comm is used as an abstraction to communicate over several channels with players. Whereas MACID asks to use: type Update state = Ev (StateT state STM) How can I use this without modifying everything?? I understand that MACID must record the someAction from above but the message should not. Thanks for help! Corentin ___ 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] internship opportunities in France
Hello, as well as I know, there is very few, if no, jobs in Haskell in France. They are much more on CAML. Corentin On Sat, Nov 6, 2010 at 9:00 PM, Lorenzo Fundaró lfund...@etu.utc.fr wrote: Hello folks ! I am a Computer Science student looking for an internship of 6 months here in France. Does anybody know of any company working with Haskell ? Thanks in advance :D, Lorenzo Fundaró García ___ 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] circular imports
Hello, I had recently a really hard time splitting up my program into parts! The natural, business-oriented split up drove me into a deadly circular dependency. I tried to solve it with: - .hs-boot: It adds a lot of duplicated code and unecessary files, so I gave up - type variables: that too complifies the code with no obvious reasons Finally, i ended up with putting all my types into a file names Types.hs. It's not very satisfatory, since I like to keep the types next to their related code and functions (like it is in the libraries). But I founded this is the way that adds the less burden to the code. Cheers, Corentin Mathew de Detrich dete...@gmail.c Pour om Ivan Lazar Miljenovic Envoyé par : ivan.miljeno...@gmail.com haskell-cafe-bou cc n...@haskell.org haskell haskell-cafe@haskell.org Objet Re: [Haskell-cafe] circular imports 07/09/2010 06:52 I had the same issue zonks ago, and I resorted to using the hs-boot file method as well (which worked fine) Which I guess brings me to my second point, is this something that GHC should do automatically when it sees circular dependencies? When I asked about it earlier on #haskell, I was told that its better that way because it discourages making bad design through circular dependencies (yet in my case and I assume the other cases as well, not using the hs-boot method would have made the design much worse). Are there any cases in particular where people would be encouraged to make interface design with circular dependencies (and that design be deemed as horrible) as opposed to what seems to be more realistic case where circular dependencies rarely crop up, and when they do they actually make the design better? On Tue, Sep 7, 2010 at 1:48 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: On 7 September 2010 03:44, Edward Z. Yang ezy...@mit.edu wrote: Excerpts from Evan Laforge's message of Mon Sep 06 13:30:43 -0400 2010: I feel like the circular imports problem is worse in haskell than other languages. Maybe because there is a tendency to centralize all state, since you need to define it along with your state monad. But the state monad module must be one of the lower level ones, since all modules that use it must import it. However, the tendency for bits of typed data to migrate into the state means it's easy for it to eventually want to import one of its importers. And the state monad module gets larger and larger (the largest modules in my system are those that define state monads: 1186 lines, 706 lines, 1156 lines---the rest tend to be 100--300 lines). I have used hs-boot files to this effect. I separated data and functionality, and typeclasses, which must be in the same module as data or are considered orphaned, get definitions via a circular import. I'm just getting to the point where I have a similar problem. I was thinking about splitting instances off from the classes (and telling GHC to not worry about orphaned instances for the instance-only modules) but then realised that some instance declarations would be circular as well, so I have to either use hs-boot files, define everything in one big module and then re-export them in ways that make sense or define all instances in one big module (at least for those types which have circular deps among instances) and re-export accordingly. -- 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 mailing list
Réf. : [Haskell-cafe] Re: circular imports
That sort of code (stripped out): In Game.hs: data Game = Game { ... activeRules :: [Rule]} applyTo :: Rule - Game - Game applyTo r gs = ... In Rule.hs: data Rule = Cond (Obs) Rule Rule | many others.. deriving (Read, Show, Eq, Typeable) data NamedRule = NamedRule { ..., rule :: Rule } isRuleLegal :: Rule - NamedRule - Game - Bool isRuleLegal = ... In Obs.hs: data Obs a where ProposedBy :: Obs Int -- The player that proposed the tested rule ... evalObs :: Obs - NamedRule - Game - EvalObsType evalObs = ... Corentin Johannes Waldmann waldm...@imn.ht Pour wk-leipzig.dehaskell-cafe@haskell.org Envoyé par : cc haskell-cafe-bou n...@haskell.orgObjet [Haskell-cafe] Re: circular imports 07/09/2010 14:00 corentin.dupont at ext.mpsa.com writes: I had recently a really hard time splitting up my program into parts! The natural, business-oriented split up drove me into a deadly circular dependency. perhaps you could post your code (enough of it to understand the problem)? J.W. ___ 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