Je me sens mal à l'aise avec la syntaxe d'enregistrement Haskell

9

La plupart de la syntaxe Haskell a la beauté de la pureté. Mais la syntaxe d'enregistrement semble moche. C'est inconfortable. Il se sent une sorte de mélange avec C. Il nécessite une virgule et des accolades. Haskell a une séparation par tabulation et par ligne. Il semble donc trop verbeux qu'il ne le fallait à l'origine. Pourquoi est-il conçu de cette façon?

Eonil
la source
4
Pour moi, tout Haskell se sent bizarre. Que puis-je faire?
Job
7
Tu n'es pas seul. Beaucoup de gens se plaignent (de l'incarnation actuelle des) enregistrements.
Eonil: Si vous détestez vraiment la syntaxe des enregistrements, vous pouvez la désactiver avec l'extension GHC {- # NoTraditionalRecordSyntax # -}.
Daniel Díaz Carrete

Réponses:

8

Bien que je n'étais pas membre du comité de conception, je pense que la syntaxe d'enregistrement a été conçue pour être cohérente avec la syntaxe de liste. La syntaxe d'exportation de module utilise également des virgules, le seul véritable endroit où la disposition est utilisée est les déclarations de niveau supérieur, les clauses where et la notation do.

En plus de cela, étant donné

data Foo = Foo {bar :: Int, baz :: Int}

l'écriture

fnord x = x { bar = 4 }

sans les accolades serait en conflit avec le reste de la syntaxe, et en utilisant la mise en page, comme

fnord x = x
    bar = 4

rendrait la syntaxe assez fragile. Ajoutez un "où" au mauvais endroit et votre code signifie quelque chose de complètement différent.

Si vous n'êtes pas satisfait de l'état des enregistrements dans Haskell (et que vous ne seriez pas seul avec cela), je vous recommande de jeter un œil aux fclabels ou même d'élaborer des hackeries de typographie comme HList ou pamplemousse-enregistrements (les deux derniers n'étant pas pour les faibles de cœur, mais aussi incroyablement puissants)

fclabels vous permettrait d'écrire (yay pointfree)

fnord = setL bar 4

aussi bien que

getBar = getL bar

en plus de sa véritable raison d'être, qui compose des étiquettes:

 data Person = Person { _place  :: Place, ... }
 data Place = Place { _city :: String, ... }

 moveToAmsterdam :: Person -> Person
 moveToAmsterdam = setL (city . place) "Amsterdam"
savon en barre
la source
Hmm. Cela setLsignifie- t -il mutable ?? Sans IO? C'est difficile à comprendre ...
Eonil
2
Pas du tout, vous allez obtenir une autre copie (de partage) de l'enregistrement avec un seul champ modifié, tout comme avec la syntaxe de l'enregistrement. Aucune mutabilité ou rupture de transparence référentielle n'est impliquée.
barsoap