
Hello, i wrote two programs in haskell which have the same problem: they define a common datatype (let's say Event for instance), and they have several modules, each one importing a list of Event from a specific data source. So all these modules have a similar api: getEvents :: <params> -> IO [Event] And maybe a couple extra functions, more or less the same for each module. In OO, I would make a base class, like EventProvider, with a couple abstract methods and in the main class of my app, I would have a list of EventProvider and loop over them. That way to add a new EventProvider, I would just add the import and an element in that list. Currently in haskell I duplicate the function calls for each provider. And because there is no interface constraint, each module has a slightly different API. 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? Thank you! Emmanuel

Greetings, I have recently asked for a difference between an interface as we know it from OOP and a type class in Haskell. Although it's not an answer to your question, you might find it useful. You can find the conversation archived on gmane at [1] [1] - http://comments.gmane.org/gmane.comp.lang.haskell.beginners/11341 On 08/02/13 09:50, Emmanuel Touzery wrote:
Hello,
i wrote two programs in haskell which have the same problem: they define a common datatype (let's say Event for instance), and they have several modules, each one importing a list of Event from a specific data source.
So all these modules have a similar api:
getEvents :: <params> -> IO [Event]
And maybe a couple extra functions, more or less the same for each module.
In OO, I would make a base class, like EventProvider, with a couple abstract methods and in the main class of my app, I would have a list of EventProvider and loop over them. That way to add a new EventProvider, I would just add the import and an element in that list.
Currently in haskell I duplicate the function calls for each provider. And because there is no interface constraint, each module has a slightly different API.
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?
Thank you!
Emmanuel
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Thank you; I did read that thread, and it helped me better grasp
typeclasses. However it confused me even more as to which is the most
idiomatic solution in haskell for my problem. This thread is partly the
reason why I asked this time ;-)
On Fri, Feb 8, 2013 at 11:58 AM, Mateusz Kowalczyk
Greetings,
I have recently asked for a difference between an interface as we know it from OOP and a type class in Haskell. Although it's not an answer to your question, you might find it useful. You can find the conversation archived on gmane at [1]
[1] - http://comments.gmane.org/gmane.comp.lang.haskell.beginners/11341
On 08/02/13 09:50, Emmanuel Touzery wrote:
Hello,
i wrote two programs in haskell which have the same problem: they define a common datatype (let's say Event for instance), and they have several modules, each one importing a list of Event from a specific data source.
So all these modules have a similar api:
getEvents :: <params> -> IO [Event]
And maybe a couple extra functions, more or less the same for each module.
In OO, I would make a base class, like EventProvider, with a couple abstract methods and in the main class of my app, I would have a list of EventProvider and loop over them. That way to add a new EventProvider, I would just add the import and an element in that list.
Currently in haskell I duplicate the function calls for each provider. And because there is no interface constraint, each module has a slightly different API.
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?
Thank you!
Emmanuel
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

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

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,
The "obvious" way to do in haskell what I would do in OO would be
On Fri, Feb 08, 2013 at 10:50:30AM +0100, Emmanuel Touzery wrote: 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

Hi Emmanuel, On Fri, Feb 08, 2013 at 01:51:26PM +0100, Emmanuel Touzery wrote:
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.
In some way you have to tell your program the available providers. How should a compiler enforce this?
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?
I think that the 'record of functions' is quite idiomatic Haskell for this use case.
Otherwise which Oleg as you talking about, maybe I would read that original post too.
I had pretty much the same issue and Oleg gave pretty much the same answer. And there's really only one Oleg ;): http://okmij.org/ftp/ There's no way you could miss him hanging around in Haskell land for some time. Greetings, Daniel

On Fri, Feb 08, 2013 at 01:51:26PM +0100, Emmanuel Touzery wrote:
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.
In some way you have to tell your program the available providers. How should a compiler enforce this?
It's already pretty good like that but, in an OO language basically if you write a new such "module" you know you must implement the interface, and that's all you need to know: the type of the interface. Then the compiler enforces all the names of methods and return and parameter types. So all you need to know is the name of the interface. Here there is an "interface", the record of functions. But each module must basically define a function returning that record. Sure, the module must implement that function, the same as you must implement it in OO languages, but each module can also make up its mind for the name of the function. I mean it's basically nitpicking at this point, and it's because I'm used to one way. I'm just used that most of the time haskell is better in (almost) every way to OO languages, here I think it's maybe a bit less good, that's all. Emmanuel

Hi Emmanuel, On Fri, Feb 08, 2013 at 02:31:58PM +0100, Emmanuel Touzery wrote:
It's already pretty good like that but, in an OO language basically if you write a new such "module" you know you must implement the interface, and that's all you need to know: the type of the interface. Then the compiler enforces all the names of methods and return and parameter types. So all you need to know is the name of the interface.
All the type enforcement is still done on the 'EventProvider', all you need to know is the 'EventProvider' data type, so there's not really a difference in this regard.
Here there is an "interface", the record of functions. But each module must basically define a function returning that record. Sure, the module must implement that function, the same as you must implement it in OO languages, but each module can also make up its mind for the name of the function.
You could also name the classes implementing the interface in any way, but will probably choose telling und helpful names. Greetings, Daniel

Here there is an "interface", the record of functions. But each module must basically define a function returning that record. Sure, the module must implement that function, the same as you must implement it in OO languages, but each module can also make up its mind for the name of the function.
You could also name the classes implementing the interface in any way, but will probably choose telling und helpful names.
Right, in an OO language i name the subclass, here the function. I was thinking the way i was because i import those modules qualified so the module name already gives me a description. Thank you! Emmanuel
participants (3)
-
Daniel Trstenjak
-
Emmanuel Touzery
-
Mateusz Kowalczyk