Re: [Haskell-cafe] ANNOUNCE: set-monad
Hi George, George Giorgidze wrote: I would like to announce the first release of the set-monad library. On Hackage: http://hackage.haskell.org/package/set-monad Very cool. Seems to work fine. But I am wondering about the impact of using your package on asymptotic complexity (and thereby, on performance). From your implementation: data Set a where Prim :: (Ord a) = S.Set a - Set a [...] Zero :: Set a Plus :: Set a - Set a - Set a I notice that this part of your datatype looks like a binary tree of sets. Lets see how your run function treats it: run :: (Ord a) = Set a - S.Set a run (Prim s) = s [...] run (Zero)= S.empty run (Plus ma mb) = S.union (run ma) (run mb) As expected, the Prim-Zero-Plus structure is treated as a binary tree of sets, and run collects all the sets together. That is probably fine, because it should have the same complexity as combining these sets in the first place. run (Bind (Prim s) f) = S.foldl' S.union S.empty (S.map (run . f) s) [...] run (Bind Zero _) = S.empty run (Bind (Plus ma mb) f) = run (Plus (Bind ma f) (Bind mb f)) [...] But when I use the binary tree of sets on the left-hand side of a bind, your run function has to naively traverse the whole tree. So if the same elements are included in many sets in the tree of sets, these elements will be processed more than once, so the overall complexity is worse than necessary. Here's a ghci session that seems to confirm my suspicion. I first define a function using set-monad's convenient monad instance for sets: $ :m +Control.Monad Data.Set.Monad $ let s1 `times` s2 = do {e1 - s1; e2 - s2; return (e1, e2)} Now I produce some test data: $ let numbers = fromList [1 .. 1000] $ let unioned = numbers `union` numbers $ let mplused = numbers `mplus` numbers Note that these three sets are all equivalent. $ (numbers == unioned, numbers == mplused, unioned == mplused) (True, True, True) However, they behave differently when passed to the times function above. numbers and unioned are similarly fast: $ :set +s $ size $ numbers `times` numbers 100 (2.56 secs, 1315452984 bytes) $ size $ unioned `times` unioned (2.39 secs, 1314950600 bytes) 100 (Why is unioned faster then numbers? Is union doing some rebalancing? Can I trigger that effect directly?) But mplused is much slower: $ size $ mplused `times` mplused 100 (10.83 secs, 5324731444 bytes) I suspect that I can achieve similar results by using the list monad and converting to a set in the very end. In what situations can I benefit from set-monad? Tillmann ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Haskell] JustHub 'Sherkin' Release
Hi Chris. [Sorry if I'm slow responding, but I'm at a summer school right now and have relatively little time to follow my email.] At issue is whether the JustHub Haskell distribution for Enterprise Linux and the hub hackage for sandboxing development projects and integrating multiple GHC tool chains is redundant because all of the functionality is covered by the Nix Haskell distribution, allowing as they do multiple Nix Haskell releases to be deployed simultaneously.] Let me clarify this in advance: I'm *not* questioning the usefulness of JustHub at all! It's great that you provide it. I was asking whether integrating JustHub *into* Nix and/or NixOS would make sense and would provide any benefit on top of the features already provided by these systems. As I indicated, I'm not yet convinced of that. I asked the question in order to learn more about JustHub. I do completely understand that Nix is not for everyone and that JustHub may have less dependencies that make it a very attractive choice for a wide range of applications. All of the standard Haskell tools inter-operate cleanly and transparently with the sandboxes and operate in the normal way outside of them. I guess this may be the main point. You're saying you can use the standard tools to work with hubs and don't need to do anything special, whereas in Nix(OS) you admittedly only get the full benefit of the system if you're installing packages via Nix rather than via Cabal. As Peter has pointed out, you're usually working in Nix(OS) with several profiles. Each of these profiles can contain an arbitrary set of packages (not limited to Haskell or GHC). It's possible to switch between profiles easily. It's possible to use different profiles for development on different projects. Different profiles can contain different versions of GHC as well as different sets or variants of packages. Sandboxed environments (hubs) can be shared between work trees as well as being (re)named, annotated, replicated, swapped, archived, locked and removed. Proper package deletion with the option of garbage collecting orphaned code and documentation is also supported. I'm not completely sure what each of these mean. Package removal is certainly supported in Nix(OS), but again, admittedly, not via the standard tools. You have to invoke nix-specific commands in order to perform garbage collection. I have loaded GHC-7.4.1 platform and the GHC-7.0.4 into Nix and it installs all of the ghc drivers into a single bin directory in the user's profile. I am guessing that running `ghc` will generally get you the latest compiler you have installed (7.4.1 in my case); specific releases can be invoked with ghc-7.0.4, etc. Installing the latest version into the main user profile is merely the default functionality. There's absolutely no problem selecting older versions or installing into separate profiles. If you look at the files actually installed, you'll find that all files in a profile are just links, and that each Haskell package in fact lives in isolation in its own directory in the Nix store. This hardly covers all of the above functionality! It might not. We're having this discussion in order to find out, I think :) Quite related to this (in my mind anyway) are the user-level facilities for managing the package databases that each work tree uses -- the problems that cabal-dev was created to solve. What I have done is to create a system that manages the environment each source work tree uses. If you are in a 2012.2.0.0-based project work tree then the ghc-driver will detect that and invoke the right tools. The 2012.2 platform uses cabal-instal-0.14 and that is what you will get when you invoke cabal in such a work tree. You still have to say at some initial point what version you want to use, I hope? Otherwise, I can't see how it could be detected. However in work trees based on earlier version of the compiler (e.g., GHC-7.2.2), cabal-install-0.10.2 will be used because cabal-install-0.14.0 doesn't interoperate very well with cabal-0.10 and earlier (see https://github.com/haskell/cabal/issues/932). Also in such a work tree you will get all of the tools that were shipped with the GHC-7.2.2 and all through issuing the usual command 'ghc', 'ghci', 'ghc-pkg', etc). Independent of concrete bugs, who's making these decisions? Can I use cabal-install-0.14.0 on projects working with older platforms if I want to? Without some system to help the user invoke the right tools in the right context, having to invoke each version of the compiler explicitly can get awkward to use quite quickly. This is not required in Nix(OS). You switch the profile and then get the versions you have in your profile. The profile is not tied to working dirs, you have to manually switch. I think both approaches have their disadvantages in practice (i.e., either the user shell or the working dir are
[Haskell-cafe] FunctionalOWL: FP Usergroup in Germany, area Bielefeld
Announcing FunctionalOWL in Bielefeld! Next Wednesday will be the first meetup of the FunctionalOWL at Hackerspace Bielefeld. The meetup is aimed at people who are interested in functional programming. FunctionalOWL wants to provide a wide range of interesting topics and opportunities to share and acquire knowledge. Become a part of it. When: Wed 20 June @ 19:00 Where: Sudbrackstraße 42, Bielefeld Followup meetups are planned to happen every 3rd Wednesday at the same location. We have various beamers and whiteboards. Internet and caffeinated lemonade are also available. For more information and contact, check out our website. Feel free to drop a message on our pubML or in our Chatroom. www.hackerspace-bielefeld.de Kind regards, raichoo, Hackerspace Bielefeld ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] lightweight alternative to mtl?
What are you using instead of mtl? I need simple type for State. The more classy it gets the harder error messages are to understand. I've installed new package. Silently it installed new mtl. And here I'm staring into three lines of code for half an hour trying to understand where I misused the types. Compiler tells me long story about functional dependencies. After downgrade it takes me a second to find the mistake. Ohh type mismatch, forgot to pass an argument. It's class for strict and lazy states. Maybe it's better to take approach of containers (the same interface and different modules)? Anton ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] lightweight alternative to mtl?
Anton Kholomiov anton.kholom...@gmail.com wrote: What are you using instead of mtl? I need simple type for State. The more classy it gets the harder error messages are to understand. I've installed new package. Silently it installed new mtl. And here I'm staring into three lines of code for half an hour trying to understand where I misused the types. Compiler tells me long story about functional dependencies. After downgrade it takes me a second to find the mistake. Ohh type mismatch, forgot to pass an argument. It's class for strict and lazy states. Maybe it's better to take approach of containers (the same interface and different modules)? If you are looking for a monomorphic approach you can use the 'transformers' library directly, on which mtl (since version 2) is based. This makes error messages better, but is also less flexible. Also 'transformers' is slightly less convenient to use. For totally different approaches to monad transformer libraries you can also have a look at monadLib and contstuff. However, personally I nowadays recommend mtl over all the three other choices. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife = sex) http://ertes.de/ signature.asc Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] lightweight alternative to mtl?
* Anton Kholomiov anton.kholom...@gmail.com [2012-06-16 17:59:23+0400] It's class for strict and lazy states. Maybe it's better to take approach of containers (the same interface and different modules)? The lazy and strict State monads differ only in their = operator. Since you don't have control over importing the Monad instance, those two have to be different types. The reason why put/get/modify are in a class is to allow them to be used not just with State, but also with any monad stack that has a State inside, like `ReaderT e (State s)`. -- Roman I. Cheplyaka :: http://ro-che.info/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] lightweight alternative to mtl?
I'd rather use 'transformers' then. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: set-monad
On Sat, Jun 16, 2012 at 3:57 AM, Tillmann Rendel ren...@informatik.uni-marburg.de wrote: George Giorgidze wrote: I would like to announce the first release of the set-monad library. On Hackage: http://hackage.haskell.org/package/set-monad Very cool. Seems to work fine. But I am wondering about the impact of using your package on asymptotic complexity (and thereby, on performance). For programs using only the Monad/MonadPlus interface, I would expect it to have the same asymptotic complexity as [] or Cont (S.Set a). As you noticed, you can get somewhat better performance by using the combinators that convert to S.Set internally, because they eliminate redundant computations later on. (Why is unioned faster then numbers? Is union doing some rebalancing? Can I trigger that effect directly?) It's because mplus a b = f turns into mplus (a = f) (b = f), whereas unioned takes the union before calling f. You can force this by defining: simplify :: (Ord a) = Set a - Set a simplify = Prim . run Unfortunately, there doesn't seem to be any equivalent of Prim in the exported interface. I guess doing simplify = union empty would work. -- 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] [Haskell] JustHub 'Sherkin' Release
Hi Andres, Thanks for your detailed reply -- it is much appreciated. Independent of concrete bugs, who's making these decisions? Can I use cabal-install-0.14.0 on projects working with older platforms if I want to? Out of the box you get a set of tools that avoids known problems and complies with the particular platform. It is easy to override this in the configuration file. I expect to add commands to carry out that reconfiguration soon. Not a problem in Nix(OS) either. Indeed, for each compiler version I have standard plain and platform profiles installed on my machine, Excellent! You still have to say at some initial point what version you want to use, I hope? Otherwise, I can't see how it could be detected. Indeed. It can be done statically (by configuring the directory) or dynamically (by setting an environment variable). I think I am getting a feel for how Nix works. As I understand it Nix provides the user with fine control of the combination of packages that can be installed in a profile. A user can maintain many profiles and switch between them. (As I have been saying) I like it. Most of the issues I have been addressing in the hub system are concerned with managing the Haskell user package database. Each project needs to know where to find the tools and where to find the global package database but they are generally static and come pre-packaged in the configuration file. The real action in the Hub system lies in managing the user package database. As I see it the developer's project configuration belongs in the source code repository. Once the developer has checked out the work tree the tools should take care of the rest. (And the tools behave as normal in the absence of such configuration.) Everything I have been trying to do has been geared towards this and helping the developer to manage the development environment. Cheers, Chris ___ 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] -
[Haskell-cafe] Haskell is rapidly approaching the top 20
L.S., From the TIOBE web site[0]: -✂ TIOBE Programming Community Index for June 2012 June Headline: Haskell is rapidly approaching the top 20 Last month we asked ourselves the question what language could become the next big new programming language. We suggested several candidates such as Scala, Erlang and Clojure. Clearly, the new thing was expected to come from the functional programming field. A functional language not explicitly mentioned was Haskell. And this month it was Haskell that jumped from #35 to #25. Looking at the TIOBE trend graph of Haskell (starting in 2003) it shows a constant rise, with peaks in 2006, 2010 and now in 2012. This certainly sounds promising. -✂ Regards, Henk-Jan van Tuyl [0] http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html Haskell programming -- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] event handler
On Fri, Jun 15, 2012 at 1:59 PM, Corentin Dupont corentin.dup...@gmail.comwrote: 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 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
On Sat, Jun 16, 2012 at 3:31 PM, Corentin Dupont corentin.dup...@gmail.comwrote: 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
[Haskell-cafe] ANN: GHC-7.4.2-Eden - Parallel Haskell on multicore and cluster systems
We are happy to announce a new release of Eden, a parallel extension of Haskell. The release comprises: * The GHC-7.4.2-Eden compiler: GHC-7.4.2 extended with the Eden parallel runtime system. * The Eden modules: a library defining the Eden language constructs. * The Eden skeleton library: a comprehensive library with common task and data parallel patterns. * The Eden trace viewer EdenTV: an visualisation and analysis tool for eventlogs of parallel program runs. All resources are available via: http://www.mathematik.uni-marburg.de/~eden Eden extends Haskell with a small set of syntactic constructs for explicit process specification and creation. While providing enough control to implement parallel algorithms efficiently, it frees the programmer from the tedious task of managing low-level details by introducing automatic process handling, synchronisation and communication (via head-strict lazy lists). Eden is tailored for distributed systems but works equally well on multicore architectures. Processes work within disjoint address spaces and do not share any data. This simplifies Eden's implementation as there is no need for global garbage collection. A tutorial is available from http://www.mathematik.uni-marburg.de/~eden/paper/edenCEFP.pdf The compiler release includes binary packages for Linux and Windows, and a source distribution, available from http://www.mathematik.uni-marburg.de/~eden/?content=down_eden_7_4navi=down Other features: - Extensions for GHC's event logging support. - Built-in serialisation of Haskell data structures (orthogonal to evaluation), see Orthogonal Serialisation for Haskell, available from http://www.diku.dk/hjemmesider/ansatte/berthold/jbpubl.html - Optimised local communication. - Stand-alone version for multicore, using middleware MPI or PVM for clusters. Eden libraries and tools are available separately from hackage: - Eden modules: http://hackage.haskell.org/package/edenmodules (already included in the Eden compiler) - Eden skeleton library: http://hackage.haskell.org/package/edenskel - EdenTV: http://hackage.haskell.org/package/edentv (uses gtk2hs and glade) When built using a standard GHC, the packages will produce a threaded simulation of Eden. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe