Re: [Haskell-cafe] ANNOUNCE: set-monad

2012-06-16 Thread Tillmann Rendel

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

2012-06-16 Thread Andres Löh
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

2012-06-16 Thread raichoo
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?

2012-06-16 Thread Anton Kholomiov
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?

2012-06-16 Thread Ertugrul Söylemez
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?

2012-06-16 Thread Roman Cheplyaka
* 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?

2012-06-16 Thread Anton Kholomiov
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

2012-06-16 Thread David Menendez
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

2012-06-16 Thread Chris Dornan
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

2012-06-16 Thread Corentin Dupont
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

2012-06-16 Thread Henk-Jan van Tuyl


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

2012-06-16 Thread Alexander Solla
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

2012-06-16 Thread Corentin Dupont
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

2012-06-16 Thread Alexander Solla
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

2012-06-16 Thread Eden - Functional parallel Programming (Mischa Dieterle)
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