59 votes

En évitant de polluer l'espace de nom en Haskell

Je suis en utilisant beaucoup de différents enregistrements dans un programme, avec certains d'entre eux en utilisant les mêmes noms de champs, par exemple

data Customer = Customer { ..., foo :: Int, ... }
data Product = Product { ..., foo :: Int, ... }

Maintenant que l'accesseur de la fonction "foo" est défini deux fois, j'ai l' "Plusieurs déclarations d'erreur". Une manière d'éviter cela serait, à l'aide de différents modules qui sont importés pleinement qualifié, ou tout simplement de renommer les champs (que je n'ai pas envie de faire).

Ce qui est officiellement suggéré une manière de traiter cette question avec Haskell?

26voto

Ozgur Points 668

C'est un très poilue problème. Il y a plusieurs propositions pour la fixation du système d'enregistrement. Sur une note connexe, voir TDNR et la discussion à ce sujet sur le café.

À l'aide de la langue disponible fonctionnalités, je pense que la meilleure option est de définir les deux types dans deux modules différents, et de faire un qualifié d'importation. En plus de cela, si vous le souhaitez, vous pouvez mettre en œuvre un certain type de classe de machines.

En Client.hs

module Customer where
data Customer = Customer { ..., foo :: Int, ... }

Dans Le Produit.hs

module Product where
data Product = Product { ..., foo :: Int, ... }

Tout en les utilisant, en Troisième.hs

module Third where

import qualified Customer as C
import qualified Product as P

.. C.foo ..
.. P.foo ..

Pourtant, j'imagine que ce ne sera pas trop tard avant de vous frapper le problème de manière récursive modules dépendants.

13voto

Thomas M. DuBuisson Points 31851

(Pour info, cette question est presque certainement un doublon)

Solutions:

1) Préfixe les champs avec une étiquette indiquant le type (très commun)

data Customer = Customer {..., cFoo :: Int, ...}

2) le type d'Utilisation des classes (moins commun, les gens se plaignent des préfixes comme cFoo sont gênant, mais de toute évidence pas si mauvais qu'ils vont écrire une classe et d'instance ou de l'utilisation de la TH de faire de même).

class getFoo a where
    foo :: a -> Int

instance getFoo Customer where
    foo = cFoo

3) mieux Utiliser les noms de champ Si les champs sont en fait différents (ce qui n'est pas toujours vrai, mon ordinateur a un âge que mon employé), c'est la meilleure solution.

7voto

sclv Points 25335

Voir aussi la Est le package: http://chrisdone.com/posts/2010-11-22-duck-typing-in-haskell.html

Et si vous avez vraiment besoin extensible dossiers maintenant, vous pouvez toujours utiliser HList. Mais je ne recommanderais pas cela jusqu'à ce que vous êtes vraiment à l'aise avec moyen-avancé Haskell, et même alors, j'avais triple vérifier que vous en avez besoin.

Haskelldb a un peu plus léger version: http://hackage.haskell.org/packages/archive/haskelldb/2.1.0/doc/html/Database-HaskellDB-HDBRec.html

Et puis, il y a une autre version de extensible dossiers dans le cadre de la pamplemousse prf bibliothèque: http://hackage.haskell.org/package/grapefruit-records

Encore une fois, pour vos fins, je ferais mordre la balle et il suffit de renommer les champs. Mais ces références sont de montrer que lorsque vous avez vraiment besoin de toute la puissance de extensible dossiers, il y a des façons de le faire, même si aucun n'est aussi agréable et bien conçu extension du langage serait.

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