Re: [Haskell-cafe] What extension do I need to write type Job = Map k a?
OK. I am totally confused here. Why Couldn't match expected type `Jobs k e a' with actual type `M.Map k0 b0' 9|data JobInfo a e = (Exception e) = 10| JobInfo { jobId :: ThreadId 11| , result :: MVar (Either e a) } 12| 13|type Jobs k e a = (Ord k, Exception e) = 14| M.Map k (JobInfo e a) 15| 16|type JobArgs k a = (Ord k) = 17| M.Map k a 21| 22|start :: (Ord k, Exception e) = JobArgs k a - (a - IO b) - IO (Jobs k e a) 23|start args worker = do 24| arg - newEmptyMVar 25| Map.mapM (\a - do 26| putMVar arg a 27| result - newEmptyMVar 28| tId - forkIO $ do 29| arg_ - takeMVar arg 30| result_ - try $ worker arg_ 31| putMVar result result_ 32| return $ JobInfo tId result 33| ) args On Thu, Jun 14, 2012 at 1:24 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: I think I need to think this through On Thu, Jun 14, 2012 at 12:28 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: On 14 June 2012 14:20, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: OK. I think I understand a little. I use Job here just wants to simplify the code. And since I provide the function as library, I cannot decide what exact type k is. What should I do? Do you know what the type of `a'? If so: type Job k = Map k String Otherwise... do you even need a type alias? On Thu, Jun 14, 2012 at 11:23 AM, Arlen Cuss a...@len.me wrote: (resending to café, turns out I wasn't subbed from this address.) Hi Magicloud, This is correct; because you've hidden the type-variables away by universally quantifying them, there's no more level of specificity you can get back *out* of them than just some kind of Map (Job = M.Map k b, where k ≠ k0, b ≠ b0). If you have a Job type which can store *any* kind of Map (forall k a. Job (Map k a)), then that means you could have a Job with a Map Int Bool, and a Job with a Map String (Float - Float), and they'd both have the same type Job. You can't do anything with the values within, because you're being too permissive about what a Job is. You may want data Job k a = Job (Map k a), *or* if you do actually use one kind of Map only, then why not data Job = Job (Map Int String) (substituting your real types for Int and String). In this case, you could also consider using newtype (newtype Job = Job { getJob :: Map Int String }) to provide the guarantee that you're getting a Job (and not any Map Int String) without performance loss. Let me know if I've been more confusing than helpful; Arlen On Thursday, 14 June 2012 at 1:16 PM, Magicloud Magiclouds wrote: Hi there, Thanks for the reply. To be clear, all I want is to avoid having to type type variables all over the place. What should I do? My original code with RankNTypes and ImpredicativeTypes does not work The type Job = forall k a. M.Map k a works now. But function uses it does not. Compiler complains about Couldn't match expected type `Job' with actual type `M.Map k0 b0'. On Wed, Jun 13, 2012 at 9:15 PM, Daniel Peebles pumpkin...@gmail.com (mailto:pumpkin...@gmail.com) wrote: That doesn't require existential quantification, but it'll need Rank-2 typesif you ever do anything with Job. Unfortunately, a universally quantifiedJob like what you wrote (or what Magicloud seems to want) is only inhabitedby the empty Map. An existentially quantified Job, as you might get with data Job = forall k a. Job (Map k a) does let you wrap up any Map containing anything in it, but unfortunatelythe only thing you can do with that map afterwards is ask for structuralproperties about it, like whether it's empty or how many elements it has init. You could ask to enumerate the elements in it, but you wouldn't be ableto touch any of them because you wouldn't know what their types were. So I'm not really sure how to interpret the question. Was the goal to have aheterogeneous Map, maybe? Or just to avoid having to type type variables allover the place? Both of those are possible but require a bit moresophistication with types. -Dan On Wed, Jun 13, 2012 at 7:32 AM, Ismael Figueroa Paletifiguer...@gmail.com (mailto:ifiguer...@gmail.com) wrote: Do you want to hide the specific types of the job? Presumably to thendefine a type JobList = [Job] ?You can do that with the ExistentialQuantification extension. type Job = forall k a. Map k atype JobList = [Job] ??Note you can't unpack the types k a once you have hidden them. But thetypechecker can use it to ensure some static property.Also you could use unsafeCoerce to do some casts, but *only if you are*sure* that things will go OK*. 2012/6/13 Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) Hi,I've forgotten this.This is OK:type Job k a = Map k
Re: [Haskell-cafe] What extension do I need to write type Job = Map k a?
Sorry, the last 'a' of line 22 is 'b'. On Thu, Jun 14, 2012 at 3:19 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: OK. I am totally confused here. Why Couldn't match expected type `Jobs k e a' with actual type `M.Map k0 b0' 9|data JobInfo a e = (Exception e) = 10| JobInfo { jobId :: ThreadId 11| , result :: MVar (Either e a) } 12| 13|type Jobs k e a = (Ord k, Exception e) = 14| M.Map k (JobInfo e a) 15| 16|type JobArgs k a = (Ord k) = 17| M.Map k a 21| 22|start :: (Ord k, Exception e) = JobArgs k a - (a - IO b) - IO (Jobs k e a) 23|start args worker = do 24| arg - newEmptyMVar 25| Map.mapM (\a - do 26| putMVar arg a 27| result - newEmptyMVar 28| tId - forkIO $ do 29| arg_ - takeMVar arg 30| result_ - try $ worker arg_ 31| putMVar result result_ 32| return $ JobInfo tId result 33| ) args On Thu, Jun 14, 2012 at 1:24 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: I think I need to think this through On Thu, Jun 14, 2012 at 12:28 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: On 14 June 2012 14:20, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: OK. I think I understand a little. I use Job here just wants to simplify the code. And since I provide the function as library, I cannot decide what exact type k is. What should I do? Do you know what the type of `a'? If so: type Job k = Map k String Otherwise... do you even need a type alias? On Thu, Jun 14, 2012 at 11:23 AM, Arlen Cuss a...@len.me wrote: (resending to café, turns out I wasn't subbed from this address.) Hi Magicloud, This is correct; because you've hidden the type-variables away by universally quantifying them, there's no more level of specificity you can get back *out* of them than just some kind of Map (Job = M.Map k b, where k ≠ k0, b ≠ b0). If you have a Job type which can store *any* kind of Map (forall k a. Job (Map k a)), then that means you could have a Job with a Map Int Bool, and a Job with a Map String (Float - Float), and they'd both have the same type Job. You can't do anything with the values within, because you're being too permissive about what a Job is. You may want data Job k a = Job (Map k a), *or* if you do actually use one kind of Map only, then why not data Job = Job (Map Int String) (substituting your real types for Int and String). In this case, you could also consider using newtype (newtype Job = Job { getJob :: Map Int String }) to provide the guarantee that you're getting a Job (and not any Map Int String) without performance loss. Let me know if I've been more confusing than helpful; Arlen On Thursday, 14 June 2012 at 1:16 PM, Magicloud Magiclouds wrote: Hi there, Thanks for the reply. To be clear, all I want is to avoid having to type type variables all over the place. What should I do? My original code with RankNTypes and ImpredicativeTypes does not work The type Job = forall k a. M.Map k a works now. But function uses it does not. Compiler complains about Couldn't match expected type `Job' with actual type `M.Map k0 b0'. On Wed, Jun 13, 2012 at 9:15 PM, Daniel Peebles pumpkin...@gmail.com (mailto:pumpkin...@gmail.com) wrote: That doesn't require existential quantification, but it'll need Rank-2 typesif you ever do anything with Job. Unfortunately, a universally quantifiedJob like what you wrote (or what Magicloud seems to want) is only inhabitedby the empty Map. An existentially quantified Job, as you might get with data Job = forall k a. Job (Map k a) does let you wrap up any Map containing anything in it, but unfortunatelythe only thing you can do with that map afterwards is ask for structuralproperties about it, like whether it's empty or how many elements it has init. You could ask to enumerate the elements in it, but you wouldn't be ableto touch any of them because you wouldn't know what their types were. So I'm not really sure how to interpret the question. Was the goal to have aheterogeneous Map, maybe? Or just to avoid having to type type variables allover the place? Both of those are possible but require a bit moresophistication with types. -Dan On Wed, Jun 13, 2012 at 7:32 AM, Ismael Figueroa Paletifiguer...@gmail.com (mailto:ifiguer...@gmail.com) wrote: Do you want to hide the specific types of the job? Presumably to thendefine a type JobList = [Job] ?You can do that with the ExistentialQuantification extension. type Job = forall k a. Map k atype JobList = [Job] ??Note you can't unpack the types k a once you have hidden them. But thetypechecker can use it to ensure some static property.Also you could use unsafeCoerce to do some casts, but *only if you are*sure* that things will go OK*.
Re: [Haskell-cafe] What extension do I need to write type Job = Map k a?
And line 14, should be JobInfo a e. I must be too sleepy On Thu, Jun 14, 2012 at 3:30 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: Sorry, the last 'a' of line 22 is 'b'. On Thu, Jun 14, 2012 at 3:19 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: OK. I am totally confused here. Why Couldn't match expected type `Jobs k e a' with actual type `M.Map k0 b0' 9|data JobInfo a e = (Exception e) = 10| JobInfo { jobId :: ThreadId 11| , result :: MVar (Either e a) } 12| 13|type Jobs k e a = (Ord k, Exception e) = 14| M.Map k (JobInfo e a) 15| 16|type JobArgs k a = (Ord k) = 17| M.Map k a 21| 22|start :: (Ord k, Exception e) = JobArgs k a - (a - IO b) - IO (Jobs k e a) 23|start args worker = do 24| arg - newEmptyMVar 25| Map.mapM (\a - do 26| putMVar arg a 27| result - newEmptyMVar 28| tId - forkIO $ do 29| arg_ - takeMVar arg 30| result_ - try $ worker arg_ 31| putMVar result result_ 32| return $ JobInfo tId result 33| ) args On Thu, Jun 14, 2012 at 1:24 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: I think I need to think this through On Thu, Jun 14, 2012 at 12:28 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: On 14 June 2012 14:20, Magicloud Magiclouds magicloud.magiclo...@gmail.com wrote: OK. I think I understand a little. I use Job here just wants to simplify the code. And since I provide the function as library, I cannot decide what exact type k is. What should I do? Do you know what the type of `a'? If so: type Job k = Map k String Otherwise... do you even need a type alias? On Thu, Jun 14, 2012 at 11:23 AM, Arlen Cuss a...@len.me wrote: (resending to café, turns out I wasn't subbed from this address.) Hi Magicloud, This is correct; because you've hidden the type-variables away by universally quantifying them, there's no more level of specificity you can get back *out* of them than just some kind of Map (Job = M.Map k b, where k ≠ k0, b ≠ b0). If you have a Job type which can store *any* kind of Map (forall k a. Job (Map k a)), then that means you could have a Job with a Map Int Bool, and a Job with a Map String (Float - Float), and they'd both have the same type Job. You can't do anything with the values within, because you're being too permissive about what a Job is. You may want data Job k a = Job (Map k a), *or* if you do actually use one kind of Map only, then why not data Job = Job (Map Int String) (substituting your real types for Int and String). In this case, you could also consider using newtype (newtype Job = Job { getJob :: Map Int String }) to provide the guarantee that you're getting a Job (and not any Map Int String) without performance loss. Let me know if I've been more confusing than helpful; Arlen On Thursday, 14 June 2012 at 1:16 PM, Magicloud Magiclouds wrote: Hi there, Thanks for the reply. To be clear, all I want is to avoid having to type type variables all over the place. What should I do? My original code with RankNTypes and ImpredicativeTypes does not work The type Job = forall k a. M.Map k a works now. But function uses it does not. Compiler complains about Couldn't match expected type `Job' with actual type `M.Map k0 b0'. On Wed, Jun 13, 2012 at 9:15 PM, Daniel Peebles pumpkin...@gmail.com (mailto:pumpkin...@gmail.com) wrote: That doesn't require existential quantification, but it'll need Rank-2 typesif you ever do anything with Job. Unfortunately, a universally quantifiedJob like what you wrote (or what Magicloud seems to want) is only inhabitedby the empty Map. An existentially quantified Job, as you might get with data Job = forall k a. Job (Map k a) does let you wrap up any Map containing anything in it, but unfortunatelythe only thing you can do with that map afterwards is ask for structuralproperties about it, like whether it's empty or how many elements it has init. You could ask to enumerate the elements in it, but you wouldn't be ableto touch any of them because you wouldn't know what their types were. So I'm not really sure how to interpret the question. Was the goal to have aheterogeneous Map, maybe? Or just to avoid having to type type variables allover the place? Both of those are possible but require a bit moresophistication with types. -Dan On Wed, Jun 13, 2012 at 7:32 AM, Ismael Figueroa Paletifiguer...@gmail.com (mailto:ifiguer...@gmail.com) wrote: Do you want to hide the specific types of the job? Presumably to thendefine a type JobList = [Job] ?You can do that with the ExistentialQuantification extension. type Job = forall k a. Map k atype JobList = [Job] ??Note you can't unpack the types k a once you have hidden them. But thetypechecker can
[Haskell-cafe] [Announce] AusHac 2012 - The Aussie Haskell Hackathon
We know many of you have been holding your breaths for this (hopefully none of you have passed out though!) for quite a while... but we’re pleased to announce that we’re finally getting around to announcing AusHac 2012! This year, we’re moving AusHac to Sydney proper: Atlassian has kindly offered the use of their offices next to Darling Harbour, so there’s more places to stay and eat than in previous years! It’s right across the harbour from Google’s headquarters where FP-Syd is hosted, and we’re starting on the Friday after next month’s FP-Syd. When: Friday 20th - Sunday 22nd of July Where: Atlassian 173/185 Sussex Street Sydney NSW 2000, Australia (02) 9262 1443 Map: http://goo.gl/maps/JoNg If you're looking for places to stay, check out AirBnB (http://www.airbnb.com), the prices are very reasonable (around $100/night within walking distance of Atlassian if you’re lucky). This year we’d like to see a few more talks on interesting things people are working on (Yes, the stuff you are working on IS interesting, and we want to hear about it!). If you’d like to give a talk, please let us know in the sign up sheet. Speaking of which, here it is: http://tinyurl.com/AusHac2012SignUp Please let us know if you’re considering coming along, so we can organise things like adequate power etc. We’d love for you to come along for the whole time or just a few hours, we’re happy for people to drop in when they want, on any day. The more people we have come along, the more awesome it will be. We hope to see you there! Cheers, Alex Mason and Ivan Miljenovic ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Current uses of Haskell in industry?
* Chris Smith cdsm...@gmail.com [2012-06-13 18:00:21-0600] It turns out I'm filling in for a cancelled speaker at a local open source user group, and doing a two-part talk, first on Haskell and then Snap. For the Haskell part, I'd like a list of current places the language is used in industry. I recall a few from Reddit stories and messages here and other sources, but I wonder if anyone is keeping a list. Take a look at the Commercial Users section of the recent HCAR[1]. [1]: http://www.haskell.org/haskellwiki/Haskell_Communities_and_Activities_Report -- Roman I. Cheplyaka :: http://ro-che.info/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[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
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] 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] [Haskell] JustHub 'Sherkin' Release
[This discussion was started on the Haskell mailing list in response to an announcement I made which you can read here http://justhaskell.org/2012/06/13/announce-justhub-sherkin/ 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.] (cd = Chris Dornan, al = Andres Löh) cd: The key feature is the way it integrates the multiple tool chains into cd: a single virtual tool chain with a sandboxing mechanism provided by cd: the hub hackage. cd: I think the Nix distribution might be a natural fit for 'hub' cd: integration -- I would be happy to work with the Nix people on that cd: (though it can't be right now). al: If this adds anything in terms of functionality that Nix doesn't already provide, al: then I would be interested to know. From having a quick look at your al: announcements, it's not quite clear though if it does. Hi Adres, From the original announcement (on the above link): The JustHub distribution is based on the Hub system for sandbox development that allows each work tree to work in its own sandboxed environment with a specific tool chain and a private user-package database. All of the standard Haskell tools inter-operate cleanly and transparently with the sandboxes and operate in the normal way outside of them. 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. Where is this functionality provided by Nix? These are the 'key features' that I emphasized in the clarification. 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. This hardly covers all of the above functionality! I think the Nix distribution is excellent and I strongly agree with its functional philosophy -- which I think is the right way to distribute Haskell. 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. 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). 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. Think about installing a package into a 7.0.4-based work tree where 'ghc' runs version 7.4.1. Cabal will reach for 7.4.1 unless told otherwise. The only practical way to do this is to build a PATH where the right tools get run on the default commands ('ghc', 'ghc-pkg', etc), or equivalently use intelligent drivers that make sure the right tools get invoked (the method JustHub uses). It is also sometimes helpful to be able to start from the minimal collection of packages that you get with compiler (sans platform packages) and build your collection from there. The JustHub system allows you to do this, even on installations that are working double time as Haskell Platform instantiations. Oftentimes less is more in working out the right package combination! Production Haskell development requires this kind of control over the environment, we have all been doing this for years and it isn't technically difficult. But frankly it sure is tedious, especially when you have worked with something better. And it means that everyone has to hand-build their own developments -- that is wasteful. GHC+cabal do provide an awesome build system but the package management mechanisms aren't as easy to use as they could be. There is no proper mechanism for erasing
Re: [Haskell-cafe] ANN: Portackage - a hackage portal
Hi ___, Thank you for your suggestion to provide JSON, which seconds Derek's earlier suggestion. I have anonymised your name since you wrote to me but didn't CC the list. :) As much as I wish the web interface was up to snuff, it is really too slow. While I continue to try to resolve that, there is something like a JSON feed available now. I'm new to these things and may be doing it wrong. Any advice would be appreciated, either in accelerating the web interface or in providing the JSON. I have no idea whether it parses or not. JSON Schema: http://www.fremissant.net/portackage/packages.schema.json.txt Hopefully compressed JSON data: http://www.fremissant.net/portackage/packages.php Raw JSON data in case the compressed doesn't work: http://www.fremissant.net/portackage/packages.json The hackage data updated as of today (June 14). For now this is only the packages which expose modules (i.e. not including binary packages). No particular reason, I just ran out of time this afternoon and thought I'd post what I've got. The fields present in the JSON are those available on the HTML table version. There are several dozen other fields which come up more or less infrequently in the Hackage packages, and they could all be included. The complete list of modules is included (rather than the summary versions used in the HTML table version). A next step would be for the server to incrementally update the JSON data based on the Hackage RSS feed. Kind Regards, Andrew On Wed, Jun 13, 2012 at 7:58 AM, ___ wrote: Hi Andrew Portackage is a great site for browsing packages, but it's really really slow for filtering per column. What about offering an additional non-javascript version of the pages -- searching with plain text in a browser works quite well. On 4/30/12, Andrew Seniuk ras...@gmail.com wrote: Oops, the three links in summary are: module tree: http://fremissant.net/portackage/modules.php library packages: http://fremissant.net/portackage/portackage.php other packages: http://fremissant.net/portackage/binary.php ___ 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
On Thu, Jun 14, 2012 at 2:04 PM, Corentin Dupont corentin.dup...@gmail.comwrote: 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] ANN: Portackage - a hackage portal
I discovered http://jsonlint.com/ and got it to validate. :) On Thu, Jun 14, 2012 at 6:18 PM, Andrew Seniuk ras...@gmail.com wrote: Hi ___, Thank you for your suggestion to provide JSON, which seconds Derek's earlier suggestion. I have anonymised your name since you wrote to me but didn't CC the list. :) As much as I wish the web interface was up to snuff, it is really too slow. While I continue to try to resolve that, there is something like a JSON feed available now. I'm new to these things and may be doing it wrong. Any advice would be appreciated, either in accelerating the web interface or in providing the JSON. I have no idea whether it parses or not. JSON Schema: http://www.fremissant.net/portackage/packages.schema.json.txt Hopefully compressed JSON data: http://www.fremissant.net/portackage/packages.php Raw JSON data in case the compressed doesn't work: http://www.fremissant.net/portackage/packages.json The hackage data updated as of today (June 14). For now this is only the packages which expose modules (i.e. not including binary packages). No particular reason, I just ran out of time this afternoon and thought I'd post what I've got. The fields present in the JSON are those available on the HTML table version. There are several dozen other fields which come up more or less infrequently in the Hackage packages, and they could all be included. The complete list of modules is included (rather than the summary versions used in the HTML table version). A next step would be for the server to incrementally update the JSON data based on the Hackage RSS feed. Kind Regards, Andrew On Wed, Jun 13, 2012 at 7:58 AM, ___ wrote: Hi Andrew Portackage is a great site for browsing packages, but it's really really slow for filtering per column. What about offering an additional non-javascript version of the pages -- searching with plain text in a browser works quite well. On 4/30/12, Andrew Seniuk ras...@gmail.com wrote: Oops, the three links in summary are: module tree: http://fremissant.net/portackage/modules.php library packages: http://fremissant.net/portackage/portackage.php other packages: http://fremissant.net/portackage/binary.php ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- ___ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What extension do I need to write type Job = Map k a?
Hi Magicloud, The indentation has been lost in the mail. Could you post your code (preferably without line numbers) on hpaste.org or similar? —A On Thursday, 14 June 2012 at 5:33 PM, Magicloud Magiclouds wrote: And line 14, should be JobInfo a e. I must be too sleepy On Thu, Jun 14, 2012 at 3:30 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: Sorry, the last 'a' of line 22 is 'b'. On Thu, Jun 14, 2012 at 3:19 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: OK. I am totally confused here. Why Couldn't match expected type `Jobs k e a' with actual type `M.Map k0 b0' 9|data JobInfo a e = (Exception e) = 10| JobInfo { jobId :: ThreadId 11| , result :: MVar (Either e a) } 12| 13|type Jobs k e a = (Ord k, Exception e) = 14| M.Map k (JobInfo e a) 15| 16|type JobArgs k a = (Ord k) = 17| M.Map k a 21| 22|start :: (Ord k, Exception e) = JobArgs k a - (a - IO b) - IO (Jobs k e a) 23|start args worker = do 24| arg - newEmptyMVar 25| Map.mapM (\a - do 26| putMVar arg a 27| result - newEmptyMVar 28| tId - forkIO $ do 29| arg_ - takeMVar arg 30| result_ - try $ worker arg_ 31| putMVar result result_ 32| return $ JobInfo tId result 33| ) args On Thu, Jun 14, 2012 at 1:24 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: I think I need to think this through On Thu, Jun 14, 2012 at 12:28 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com (mailto:ivan.miljeno...@gmail.com) wrote: On 14 June 2012 14:20, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: OK. I think I understand a little. I use Job here just wants to simplify the code. And since I provide the function as library, I cannot decide what exact type k is. What should I do? Do you know what the type of `a'? If so: type Job k = Map k String Otherwise... do you even need a type alias? On Thu, Jun 14, 2012 at 11:23 AM, Arlen Cuss a...@len.me (mailto:a...@len.me) wrote: (resending to café, turns out I wasn't subbed from this address.) Hi Magicloud, This is correct; because you've hidden the type-variables away by universally quantifying them, there's no more level of specificity you can get back *out* of them than just some kind of Map (Job = M.Map k b, where k ≠ k0, b ≠ b0). If you have a Job type which can store *any* kind of Map (forall k a. Job (Map k a)), then that means you could have a Job with a Map Int Bool, and a Job with a Map String (Float - Float), and they'd both have the same type Job. You can't do anything with the values within, because you're being too permissive about what a Job is. You may want data Job k a = Job (Map k a), *or* if you do actually use one kind of Map only, then why not data Job = Job (Map Int String) (substituting your real types for Int and String). In this case, you could also consider using newtype (newtype Job = Job { getJob :: Map Int String }) to provide the guarantee that you're getting a Job (and not any Map Int String) without performance loss. Let me know if I've been more confusing than helpful; Arlen On Thursday, 14 June 2012 at 1:16 PM, Magicloud Magiclouds wrote: Hi there, Thanks for the reply. To be clear, all I want is to avoid having to type type variables all over the place. What should I do? My original code with RankNTypes and ImpredicativeTypes does not work The type Job = forall k a. M.Map k a works now. But function uses it does not. Compiler complains about Couldn't match expected type `Job' with actual type `M.Map k0 b0'. On Wed, Jun 13, 2012 at 9:15 PM, Daniel Peebles pumpkin...@gmail.com (mailto:pumpkin...@gmail.com) wrote: That doesn't require existential quantification, but it'll need Rank-2 typesif you ever do anything with Job. Unfortunately, a universally quantifiedJob like what you wrote (or what Magicloud seems to want) is only inhabitedby the empty Map. An existentially quantified Job, as you might get with data Job = forall k a. Job (Map k a) does let you wrap up any Map containing anything in it, but unfortunatelythe only thing you can do with that map afterwards is ask for structuralproperties about it, like whether it's
Re: [Haskell-cafe] What extension do I need to write type Job = Map k a?
Sorry, the full code is here: http://hpaste.org/69972 On Fri, Jun 15, 2012 at 7:09 AM, Arlen Cuss a...@len.me wrote: Hi Magicloud, The indentation has been lost in the mail. Could you post your code (preferably without line numbers) on hpaste.org or similar? —A On Thursday, 14 June 2012 at 5:33 PM, Magicloud Magiclouds wrote: And line 14, should be JobInfo a e. I must be too sleepy On Thu, Jun 14, 2012 at 3:30 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: Sorry, the last 'a' of line 22 is 'b'. On Thu, Jun 14, 2012 at 3:19 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: OK. I am totally confused here. Why Couldn't match expected type `Jobs k e a' with actual type `M.Map k0 b0' 9|data JobInfo a e = (Exception e) = 10| JobInfo { jobId :: ThreadId 11| , result :: MVar (Either e a) } 12| 13|type Jobs k e a = (Ord k, Exception e) = 14| M.Map k (JobInfo e a) 15| 16|type JobArgs k a = (Ord k) = 17| M.Map k a 21| 22|start :: (Ord k, Exception e) = JobArgs k a - (a - IO b) - IO (Jobs k e a) 23|start args worker = do 24| arg - newEmptyMVar 25| Map.mapM (\a - do 26| putMVar arg a 27| result - newEmptyMVar 28| tId - forkIO $ do 29| arg_ - takeMVar arg 30| result_ - try $ worker arg_ 31| putMVar result result_ 32| return $ JobInfo tId result 33| ) args On Thu, Jun 14, 2012 at 1:24 PM, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: I think I need to think this through On Thu, Jun 14, 2012 at 12:28 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com (mailto:ivan.miljeno...@gmail.com) wrote: On 14 June 2012 14:20, Magicloud Magiclouds magicloud.magiclo...@gmail.com (mailto:magicloud.magiclo...@gmail.com) wrote: OK. I think I understand a little. I use Job here just wants to simplify the code. And since I provide the function as library, I cannot decide what exact type k is. What should I do? Do you know what the type of `a'? If so: type Job k = Map k String Otherwise... do you even need a type alias? On Thu, Jun 14, 2012 at 11:23 AM, Arlen Cuss a...@len.me (mailto:a...@len.me) wrote: (resending to café, turns out I wasn't subbed from this address.) Hi Magicloud, This is correct; because you've hidden the type-variables away by universally quantifying them, there's no more level of specificity you can get back *out* of them than just some kind of Map (Job = M.Map k b, where k ≠ k0, b ≠ b0). If you have a Job type which can store *any* kind of Map (forall k a. Job (Map k a)), then that means you could have a Job with a Map Int Bool, and a Job with a Map String (Float - Float), and they'd both have the same type Job. You can't do anything with the values within, because you're being too permissive about what a Job is. You may want data Job k a = Job (Map k a), *or* if you do actually use one kind of Map only, then why not data Job = Job (Map Int String) (substituting your real types for Int and String). In this case, you could also consider using newtype (newtype Job = Job { getJob :: Map Int String }) to provide the guarantee that you're getting a Job (and not any Map Int String) without performance loss. Let me know if I've been more confusing than helpful; Arlen On Thursday, 14 June 2012 at 1:16 PM, Magicloud Magiclouds wrote: Hi there, Thanks for the reply. To be clear, all I want is to avoid having to type type variables all over the place. What should I do? My original code with RankNTypes and ImpredicativeTypes does not work The type Job = forall k a. M.Map k a works now. But function uses it does not. Compiler complains about Couldn't match expected type `Job' with actual type `M.Map k0 b0'. On Wed, Jun 13, 2012 at 9:15 PM, Daniel Peebles pumpkin...@gmail.com (mailto:pumpkin...@gmail.com) wrote: That doesn't require existential quantification, but it'll need Rank-2 typesif you ever do anything with Job. Unfortunately, a universally quantifiedJob like what you wrote (or what Magicloud seems to want) is only inhabitedby the empty Map. An existentially quantified Job, as you might get with data Job = forall k a. Job (Map k a) does let you wrap up any Map containing anything in it, but unfortunatelythe only thing you can do with that map