Thank you. I think a record of functions is a nice way.
I would write the implementation of the record in each module. I would have this record to be the outside API to my module, all other functions would be hidden.

But that way I must still have public getEventProvider() function which returns the record, that I call by convention without some compiler enforcement, which doesn't sound right.

I think what I am trying to achieve is a very common problem and I maybe suggested a bit too strongly how I would code it in OO languages, maybe it should be arranged completely differently in idiomatic haskell?

Otherwise which Oleg as you talking about, maybe I would read that original post too.

Thank you!

Emmanuel


On Fri, Feb 8, 2013 at 12:43 PM, Daniel Trstenjak <daniel.trstenjak@gmail.com> wrote:

Hi Emmanuel,

On Fri, Feb 08, 2013 at 10:50:30AM +0100, Emmanuel Touzery wrote:
>  The "obvious" way to do in haskell what I would do in OO would be through
> type classes. However I realize type classes are not quite interfaces. I'm
> wondering what would be the "haskell way" to solve this problem?
>
>  For sure type classes do the job. But is it the idiomatic way of solving
> this problem?

The problem is, that without the use of extensions it's not possible to have something like:

class EventProvider a where
   events :: a -> IO [Event]

instance EventProvider Prov1 where ...
instance EventProvider Prov2 where ...

-- won't compile, because Prov1 and Prov2 have different types
providers :: EventProvider a => [a]
providers = [Prov1, Prov2]


To express something like this you need existential quantification:

{-# LANGUAGE ExistentialQuantification #-}

data AnyProvider = forall a. (EventProvider a) => AnyProvider a

providers :: [AnyProvider]
providers = [AnyProvider Prov1, AnyProvider Prov2]


But after trying ExistentialQuantification I got the impression, that
it just doesn't fit nicely into the language, that you can get quite
fast to a point where your head explodes by looking at the type errors ;).

So, like others already said (thanks Oleg ;), a record of functions can get you quite far.


In your case youd could have something like:

data EventProvider = EventProvider {events = IO [Event]}


mkProv1 prov1 = EventProvider {events = do
   -- read from prov1
   }

mkProv2 prov2 = EventProvider {events = do
   -- read from prov2
   }


Greetings,
Daniel

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners