57 votes

Syntaxe d'enregistrement Haskell

Haskell enregistrement syntaxe est considéré par beaucoup comme une verrue sur une autre élégante de la langue, sur le compte de son affreux de la syntaxe et de l'espace de noms de la pollution. D'autre part, il est souvent plus utile que la position de remplacement.

Au lieu d'une déclaration comme ceci:

data Foo = Foo { 
  fooID :: Int, 
  fooName :: String 
} deriving (Show)

Il me semble que quelque chose le long de ces lignes serait plus attractif:

data Foo = Foo id   :: Int
               name :: String
               deriving (Show)

Je suis sûr qu'il doit y avoir une bonne raison, je suis absent, mais pourquoi la C-comme enregistrer une syntaxe adoptée au cours d'un nettoyeur de mise en page basée sur l'approche?

Deuxièmement, il n'y a rien dans le pipeline pour résoudre le problème de l'espace de noms, nous pouvons donc écrire id foo au lieu de fooID foo dans les futures versions de Haskell? (En dehors de la longwinded classe de type de base de solutions actuellement disponibles.)

54voto

Dan Burton Points 26639

Eh bien, si personne d'autre va essayer, alors je vais prendre un autre (un peu plus soigneusement étudié) coup de couteau à répondre à ces questions.

tl;dr

Question 1: C'est juste la façon dont le résultat des dés. C'était une circonstancielle de choix et c'est resté.

Question 2: Oui (sorta). Plusieurs parties ont certainement été à réfléchir à la question.

Lire la suite pour un très longwinded explication pour chaque réponse, autour de des liens et des citations que j'ai trouvé pour être pertinent et intéressant.

Pourquoi le C-comme enregistrer une syntaxe adoptée au cours d'un nettoyeur de mise en page basée sur l'approche?

Les chercheurs Microsoft a écrit une Histoire de Haskell papier. La Section 5.6 parle de dossiers. Je vais citer le premier petit peu, ce qui est perspicace:

L'une des plus évidentes les omissions sur les premières versions de Haskell a l'absence de registres, offrant des champs nommés. Étant donné que les enregistrements sont extrêmement utiles dans la pratique, pourquoi ont-ils été omis?

Les experts de microsoft répond aux répondre à sa propre question

La raison la plus forte semble avoir été qu'il n'était pas évident "droit" de conception.

Vous pouvez lire le livre vous-même, pour les détails, mais ils disent Haskell finalement adopté enregistrement de la syntaxe en raison de la "pression pour le nom des champs dans la structure des données".

Au moment où le Haskell 1.3 conception était en cours, en 1993, l'utilisateur la pression pour le nom des champs dans la structure des données a été forte, de sorte que le comité a finalement adopté un design minimaliste...

Vous vous demandez pourquoi, c'est pourquoi il est? Eh bien, ce que je comprends, si le début de Haskellers a leur manière, nous pourrions nous n'avons jamais eu d'enregistrement de la syntaxe dans la première place. L'idée était apparemment poussé sur Haskell par des gens qui ont déjà l'habitude du C-comme la syntaxe, et étaient plus intéressés à obtenir de C-comme les choses en Haskell, plutôt que de faire les choses "le Haskell façon". (Oui, je me rends compte c'est une interprétation subjective. J'ai peut être tort, mais en l'absence de meilleures réponses, c'est la meilleure conclusion que je peux en tirer.)

Il n'y a rien dans le pipeline pour résoudre le problème de l'espace de noms?

Tout d'abord, pas tout le monde sent qu'il y a un problème. Il y A quelques semaines, une Raquette de passionné de a expliqué à moi (et d'autres) que le fait d'avoir différentes fonctions avec le même nom était une mauvaise idée, car cela complique l'analyse de la question "quelle est la fonction nommée _ faire?" Il n'est pas, en fait, une fonction, mais plusieurs. L'idée peut être très gênant pour Haskell, car elle complique l'inférence de type.

Sur une légère tangente, les experts de microsoft répond aux ont des choses intéressantes à dire au sujet de Haskell typeclasses:

C'était une heureuse coïncidence du moment que Wadler et Blott qui s'est passé pour produire cette idée clé juste au moment où la langue de conception était encore en pleine évolution.

N'oubliez pas que Haskell a été jeunes une fois. Certaines décisions ont été prises tout simplement parce qu'ils ont été faits.

De toute façon, il existe quelques façons intéressantes que ce "problème" pourrait être traitée:

Type Dirigé la Résolution de Nom, une proposition de modification de Haskell (mentionné dans les commentaires ci-dessus). Viens de lire cette page pour voir ce qu'il touche beaucoup de domaines de la langue. Dans l'ensemble, il n'est pas une mauvaise idée. Beaucoup de réflexion a été mis en elle de sorte qu'il ne sera pas en conflit avec des trucs. Cependant, il faudra encore beaucoup plus d'attention à l'obtenir en le maintenant-(plus-)matures Haskell langue.

Un autre Microsoft papier, OO Haskell, propose une extension du langage Haskell à l'appui "ad hoc surcharge". C'est plutôt compliqué, vous n'aurez qu'à consulter la Section 4 pour vous-même. L'essentiel, c'est-à-automatiquement (?) en déduire "A" types, et d'ajouter une étape supplémentaire à la vérification de type à ce qu'ils appellent "l'amélioration", vaguement décrites dans le sélectif citations qui suivent:

Compte tenu de la contrainte de classe Has_m (Int -> C -> r) il y a un seul exemple pour m qui correspond à cette contrainte...Depuis il y a exactement un choix, nous devons le faire maintenant, et qui à son tour correctifs r être Int. D'où nous obtenons le type attendu pour f: f :: C -> Int -> IO Int...[ce] est tout simplement un choix de conception, et l'autre fondée sur l'idée que la classe Has_m est fermé

Mes excuses pour la incohérente citant; si cela vous aide, à tous, très bien, sinon il suffit d'aller lire le papier. C'est compliqué (mais convaincante) idée.

Chris Fait a utilisé le Modèle de Haskell pour fournir duck-typing en Haskell dans une vague manière similaire à l'OO Haskell papier (à l'aide de "A" types). Quelques session interactive des échantillons à partir de son site:

λ> flap ^. donald
*Flap flap flap*
λ> flap ^. chris
I'm flapping my arms! -- ' close quote :P dumb syntax highlighter

fly :: (Has Flap duck) => duck -> IO ()
fly duck = do go; go; go where go = flap ^. duck

λ> fly donald
*Flap flap flap*
*Flap flap flap*
*Flap flap flap*

Cela nécessite un peu passe-partout/insolite syntaxe, et personnellement, je préfèrent s'en tenir à typeclasses. Mais bravo à Chris Fait, librement, à la publication de son terre-à-terre dans la région.

11voto

Eric Points 5855

Je pensais juste que j'ajouterais un lien sur le problème de l'espace de noms. Il semble que les champs d'enregistrement surchargés pour GHC arrivent dans GHC 7.10 (et le sont probablement déjà dans HEAD), en utilisant l' extension OverloadedRecordFields .

Cela permettrait une syntaxe telle que

 data Person = Person { id :: Int, name :: String }
data Company { name :: String, employees :: [Person] }

companyNames :: Company -> [String]
companyNames c = name c : map name (employees c)
 

6voto

Dan Burton Points 26639

[modifier] Cette réponse est juste quelques pensées éparses de la mine sur la question. Je recommande aux autres de répondre sur celui-ci, parce que, pour cette réponse, j'ai pris beaucoup plus de temps à rechercher de référence et le travail d'autres personnes.

Enregistrement de syntaxe

En prenant un peu de poignard dans le noir: votre "mise en page à base de" projet de syntaxe ressemble beaucoup à la non-enregistrement de la syntaxe data des déclarations, ce qui risquerait de causer de la confusion pour l'analyse (?)

--record
data Foo = Foo {i :: Int, s :: String} deriving (Show)
--non-record
data Foo = Foo Int String deriving (Show)
--new-record
data Foo = Foo i :: Int, s :: String deriving (Show)

--record
data LotsaInts = LI {a,b,c,i,j,k :: Int}
--new-record
data LostaInts = LI a,b,c,i,j,k :: Int

Dans ce dernier cas, qu'est-ce exactement est - :: Int appliqué à? L'ensemble des données de déclaration?

Les déclarations à l'enregistrement de la syntaxe (actuellement) sont similaires à la construction et la mise à jour de la syntaxe. Mise en page basée sur la syntaxe de ne pas être plus clair pour ces cas; comment analyser ces extra - = signes?

let f1 = Foo {s = "foo1", i = 1}
let f2 = f1 {s = "foo2"}

let f1 = Foo s = "foo1", i = "foo2"
let f2 = f1 s = "foo2"

Comment savez-vous f1 s est une mise à jour d'enregistrement, par opposition à une application de fonction?

Namespacing

Si vous voulez de se mêler de l'utilisation de votre classe définies id avec le Prélude de l' id? Comment avez-vous préciser celle que vous utilisez? Pouvez-vous penser à une meilleure façon que les importations admissibles et/ou de l' hiding mot-clé?

import Prelude hiding (id)

data Foo = Foo {a,b,c,i,j,k :: Int, s :: String}
               deriving (Show)

id = i

ghci> :l data.hs
ghci> let foo = Foo 1 2 3 4 5 6 "foo"
ghci> id foo
4
ghci> Prelude.id f1
Foo {a = 1, b = 2, c = 3, i = 4, j = 5, k = 6, s = "foo"}

Ce ne sont pas des réponses grands, mais ils sont les meilleurs que j'ai eu. Personnellement, je ne pense pas que l'enregistrement de la syntaxe est que laid. Je ne sens qu'il y a place pour de l'amélioration avec le namespacing/modules de trucs, mais je n'ai aucune idée de comment faire mieux.

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