8
votes

Relations sur l'égalité dans Scala

Je viens de tomber sur l'un de Tony Morris ' Blog -Posts sur Java et un problème fondamental avec la langue: la définition d'une relation d'égalité sur mesure pour une collection. C'est quelque chose que je pense est un gros problème et se demanda s'il y avait une solution Scala.

Le problème classique se manifeste en pensant, disons, un commerce. Disons que je fais deux métiers de +100 actions Vodafone @ 150p. Les deux métiers sont égaux, oui? Sauf qu'ils ne sont pas le même commerce . Dans le cas d'un système normal du monde réel, avec persistance ou sérialisation, je ne peux pas compter sur identité pour me dire si deux références sont pour le même commerce !

Ce que je veux, c'est de pouvoir créer une collection que je peux transmettre une relation d'égalité à: xxx

Comment puis-je implémenter mon ensemble dans un manière (sauf si le EqualityRelation définit également un mécanisme xxx

afin que les questions sont les suivantes:

  • y a-t-il une bibliothèque qui offre cette capacité?
  • Y a-t-il un moyen de le faire soigneusement dans Scala?

    Il semble qu'avec implicite, ce serait une chose assez facile à ajouter au type SCALA SET existant.


3 commentaires

Il y a égal à Scalaz: GITUB.COM / Scalaz / Scalaz / Blob / Master / Exemple / SRC / Main / Scala / ... . Mais je ne suis pas assez familier pour dire ce qui s'appuie dessus.


Je pense que c'est juste un dysfeafe égal, de sorte que "bonjour" === 2 ne compile pas


Scalaz.equal n'est pas seulement tape de sécurité, c'est aussi flexible. égal [LISTE [FOO]]]] est paramétré par un égal [foo] . Cela va à mi-chemin vers votre objectif. Martin Odersky a refusé d'ajouter hachage [t] à la bibliothèque standard, affirmant que "nous voulons maintenir un hachage universel, c'est trop partie de la culture Java". scala-lang.org/node/4091#Comment-16327


3 Réponses :


6
votes

Ceci peut déjà être atteint avec la mise en oeuvre de Java et un comparateur: xxx pré>

sortie: p> xxx pré>

Ceci a les inconvénients que le Le comparateur à mettre en œuvre est plus puissant que nécessaire et que vous êtes limité aux collections qui soutiennent les comparateurs. Comme indiqué par Oxbow_Lakes, la mise en œuvre du comparateur enfreint le contrat défini (pour ! A.Equals (b) code> il pourrait s'agir de ce nouvel ensemble (); set.add (a) == true && set.add (b) == false code>). p>

Scala prend en charge cela avec une transformation de vue d'A => commandé [A]. P>

scala> new scala.collection.immutable.TreeSet[String]()(x=> x.toLowerCase) + "a"
 + "A"
res0: scala.collection.immutable.TreeSet[String] = Set(A)


6 commentaires

Et vous êtes forcé dans la voie de l'o (log (n)) Heure d'accès d'une arborescence


En outre, à partir de la Javadoc de arbreset : Notez que la commande gérée par un ensemble (un comparateur explicite est fournie) doit être cohérente avec des égaux s'il s'agit d'implémenter correctement l'interface de réglage , il semble donc que cette approche fonctionne, il ne se sent pas bien juste


Ceci est un point valable. Briser le contrat Set est une mauvaise idée. Si vous remettez cet arbre autour, il doit être enveloppé. Le Cleverset que vous avez suggéré la briserait de la même manière. Il ne pouvait que mettre en œuvre uniquement [t] non défini [t].


Seulement parce que définir est défini en termes d'égal. Oh, comment je souhaite que cela ait été défini en termes de relation d'égalité (pluggable))


@OXBOW_LAKES - Si vous descendez cette route (flexibilité), il ne restera que GetClass sur l'interface Java.Lang.Object.


@Thomasjung sonne comme une amélioration;)



2
votes

Vous décrivez le concept de stratégie de hachage. Le Bibliothèque de Trove comprend des ensembles et des cartes pouvant être construits avec des stratégies de hachage.


0 commentaires

3
votes

Je sais que vous posez des questions sur Scala, mais cela vaut la peine de comparer avec ce que propose les collections .NET. En particulier, toutes les collections à base de hash (par exemple, Dictionnaire et hashset ) peuvent prendre une instance de IequalityComparer . Ceci est similaire à Scala's Equiv [t] , mais fournit également un code de hachage personnalisé. Vous pouvez créer un trait similaire par sous-classement Equiv : xxx

pour être entièrement pris en charge, les collections basées sur le hachage devraient ajouter hasHequiv paramètres implicites à leur construction et utilisez le implicitement importé equiv et Hashof à la place des méthodes d'objet d'objet (comme arbreset , etc trait avec le commandé trait, mais en marche arrière). Il faudrait également une conversion implicite de tout sur hasHequiv qui utilise le intrinsèque correspondant et hashcode implémentation.


0 commentaires