127 votes

Interface de Java et classe de types de Haskell: différences et similitudes?

Alors que je suis en train d'apprendre Haskell, j'ai remarqué son type de classe, qui est censé être une grande invention qui proviennent de Haskell.

Cependant, dans la page de Wikipedia sur le type de classe:

Le programmeur définit un type de classe en spécifiant un ensemble de fonction ou les noms de constantes, de concert avec leurs types, qui doit exister pour chaque type qui appartient à la classe.

Ce qui semble assez proche de Java de l'Interface de moi (en citant Wikipédia(Interface Java) de la page):

Une interface en langage de programmation Java est un type abstrait qui est utilisé pour indiquer une interface (au sens générique du terme) que les classes doivent implémenter.

Ces deux looks plutôt similaire: type de classe limite d'un type de comportement, alors que l'interface limite de la classe de comportement.

Je me demande quelles sont les différences et les similitudes entre le type de classe en Haskell et de l'interface en Java, ou peut-être qu'ils sont fondamentalement différents?

EDIT: j'ai remarqué que même haskell.org admet qu'ils sont similaires. Si ils sont si semblables (ou sont-ils?), alors pourquoi le type de classe est traitée avec un tel battage médiatique?

PLUS EDIT: Wow, tellement de bonnes réponses! Je crois que je vais laisser la communauté décider qui est le meilleur. Cependant, en lisant les réponses, toutes semblent juste de dire que "il ya beaucoup de choses typeclass peuvent faire si l'interface ne peuvent ou doivent composer avec les médicaments génériques". Je ne peux pas m'empêcher de me demander, est-il rien interfaces peuvent faire tout typeclasses ne le peuvent pas? Aussi, j'ai remarqué que Wikipédia affirme que typeclass a été inventé en 1989 papier *"Comment faire ad-hoc polymorphisme moins ad hoc", tout en Haskell est encore dans son berceau, alors que Java projet a été lancé en 1991 et le premier publié en 1995. Donc peut-être lieu de typeclass étant similaire aux interfaces, c'est l'inverse, c'est-interfaces ont été influencés par typeclass? Existe-il des documents/documents de soutien ou d'infirmer cela? Merci pour toutes ces réponses, elles sont toutes très instructif!

Merci pour toutes les entrées!

53voto

newacct Points 42530

Je dirais qu'une interface est une sorte de classe de type SomeInterface t où toutes les valeurs de type t -> whatever (où whatever ne contient pas d' t). C'est parce que la nature de la relation d'héritage en Java et les langages similaires, la méthode dépend du type de l'objet, ils sont appelés, et rien d'autre.

Cela signifie qu'il est vraiment difficile de faire des choses comme add :: t -> t -> t avec une interface, où il est polymorphe sur plus d'un paramètre, car il n'y a aucun moyen de l'interface pour spécifier que le type d'argument et le type de retour de la méthode est le même type que le type de l'objet sur lequel elle est appelée (c'est à dire le "self" type). Avec les Génériques, il y a un peu de moyens pour faux ce faire, une interface avec le paramètre générique qui devrait être le même type que l'objet lui-même, comme la façon dont Comparable<T> t-il, où vous êtes attendu à utiliser Foo implements Comparable<Foo> , de sorte que l' compareTo(T otherobject) genre de type a t -> t -> Ordering. Mais qui nécessite encore le programmeur de suivre cette règle, et aussi les causes des maux de tête quand des gens veulent faire une fonction qui utilise cette interface, ils ont récursive des paramètres de type générique.

Aussi, vous n'aurez pas des choses comme empty :: t parce que vous n'êtes pas à l'appel d'une fonction ici, donc ce n'est pas une méthode.

49voto

Daniel Pratt Points 8151

Quelles sont les ressemblances entre les interfaces et les classes de type, c'est qu'ils nommer et décrire un ensemble d'opérations liées. Les opérations elles-mêmes sont décrits par leurs noms, les intrants et les extrants. De même, il peut y avoir de nombreuses implémentations de ces opérations qui sera susceptible de varier dans leur mise en œuvre.

Avec cela de la route, voici quelques différences notables:

  • Interfaces méthodes sont toujours associés à une instance d'objet. En d'autres termes, il y a toujours un implicite " ce paramètre qui est l'objet sur lequel la méthode est appelée. Toutes les entrées à un type de fonction de classe sont explicites.
  • Une interface de mise en œuvre doivent être définies dans le cadre de la classe qui implémente l'interface. À l'inverse, une classe de type "instance" peut être défini complètement séparé de son associé type...même dans un autre module.
  • Un type de classe permet de définir une valeur "par défaut" de la mise en œuvre de tout de la définition des opérations. Les Interfaces sont strictement type de spécifications, pas de mise en œuvre.

En général, je pense qu'il est juste de dire que les classes de type sont plus puissant et flexible que les interfaces. Comment pouvez-vous définir une interface pour la conversion d'une chaîne à une valeur ou à une instance de la mise en œuvre de type? Ce n'est certainement pas impossible, mais le résultat ne serait pas intuitif ou élégant. Avez-vous jamais souhaité qu'il a été possible de mettre en place une interface pour un type dans certains compilé bibliothèque? Ce sont à la fois facile à réaliser avec des classes de type.

29voto

C. A. McCann Points 56834

Type de classes ont été créées, comme un moyen structuré express "ad-hoc polymorphisme", qui est essentiellement le terme technique pour les fonctions surchargées. Un type de définition de classe ressemble à quelque chose comme ceci:

class Foobar a where
    foo :: a -> a -> Bool
    bar :: String -> a

Ce que cela signifie, c'est que, lorsque vous appliquez la fonction foo à certains arguments d'un type qui appartiennent à la classe Foobar, il ressemble à une mise en œuvre de l' foo spécifiques à ce type, et l'utilise. Ceci est très similaire à la situation avec la surcharge d'opérateur dans des langages tels que le C, sauf le plus flexible et généralisée.

Les Interfaces de remplir une fonction similaire dans les langages à objets, mais le concept sous-jacent est un peu différent, OO langues viennent avec construit-dans la notion de type de hiérarchies que Haskell n'a simplement pas, ce qui complique les choses, à certains égards, parce que les interfaces peuvent concerner à la fois la surcharge par le sous-typage (c'est à dire, les appels de méthodes sur des cas appropriés, des sous-types de la mise en œuvre de leurs interfaces aux supertypes faire) et par type de plat à base de répartition (depuis deux classes implémentant une interface ne peut pas avoir une commune de la super-classe qui implémente également). Compte tenu de l'énorme complexité supplémentaire introduite par le sous-typage, je suggère qu'il est plus utile de penser à des classes de type comme une version améliorée des fonctions surchargées dans un non-langage OO.

Il faut également noter que les classes de type ont beaucoup plus de moyens souples d'envoi--interfaces ne s'appliquent généralement qu'à la seule classe de la mettre en œuvre, alors que les classes de type sont définis pour un type, qui peuvent apparaître n'importe où dans la signature de la classe de fonctions. L'équivalent de ce dans OO interfaces seraient permettant à l'interface de définir les moyens à passer un objet de cette classe à d'autres classes, de définir les méthodes statiques et les constructeurs qui opteraient pour une mise en œuvre basée sur ce type de retour est exigé dans l'appel de contexte, de définir les méthodes qui prennent des arguments du même type que la classe implémentant l'interface, et diverses autres choses qui ne sont pas vraiment traduire à tous.

En bref: Ils servent à des fins similaires, mais la façon dont ils travaillent est quelque peu différente, et le type de classes sont à la fois nettement plus expressive et, dans certains cas, plus simple à utiliser en raison de travailler sur des types fixes plutôt que des morceaux d'une hiérarchie d'héritage.

11voto

mcandre Points 6965

Regardez les discours de Phillip Wadler sur la foi, l'évolution et les langages de programmation . Wadler a travaillé sur Haskell et a été un contributeur majeur à Java Generics.

8voto

Channing Walton Points 1444

Lisez Extension du logiciel et intégration avec les classes de types, où des exemples sont donnés sur la manière dont les classes de types peuvent résoudre un certain nombre de problèmes que les interfaces ne peuvent pas.

Les exemples cités dans l'article sont les suivants: le problème de l'expression, le problème de l'intégration du cadre, le problème de l'extensibilité indépendante, la tyrannie de la décomposition dominante, la dispersion et l'enchevêtrement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X