web-dev-qa-db-fra.com

Accéder à un élément spécifique dans un tuple

Haskell-newbie reporting in. La question est la suivante: Dans Haskell, nous avons fst et snd qui renvoient les premier et deuxième éléments d'un 2-Tuple. Pourquoi n'avons-nous pas un moyen facile d'accéder au i-ème élément à partir d'un tuple? En ce moment, j'ai un 3-Tuple, je veux lire le 1er élément et la seule façon d'accomplir cette tâche est de faire une supercherie de correspondance de motifs. Pourquoi cela ne peut-il pas être plus facile? Ou peut-être existe-t-il un moyen simple?

34
user500944

Ce qui empêche le langage d'avoir la construction spéciale que vous voulez, c'est sa conception. Les concepteurs n'ont tout simplement pas mis cela, car cela compliquerait la définition du langage, qui est assez minimaliste. fst et snd sont des fonctions de bibliothèque pour le cas commun des paires; vous pouvez définir vous-même tous les autres, ou mieux, définir des types d'enregistrement pour vos données afin que vos membres de données aient des noms appropriés.

(Il se peut que GHC ait une extension pour ce faire, mais je n'en ai pas rencontré; vérifiez les documents ou demandez sur la liste de diffusion pour être sûr.)

29
Fred Foo

Consultez la bibliothèque de tuple sur le piratage. Il a des fonctions surchargées pour diverses opérations sur les tuples (jusqu'à une taille prédéfinie).

21
augustss

[~ # ~] n [~ # ~] - les tuples ne sont pas une structure de données pour l'indexation via une clé Int, à la place, vous devriez regarder une structure de données à biais indexé, comme tableaux ou finger-trees.

Maintenant, on pourrait imaginer écrire ne classe de types pour une famille de types Tuple fournissant une opération index , cependant, nous avons déjà des tableaux pour cela, et il y a beaucoup de passe-partout nécessaires pour faire des tuples de tout type assurent cette opération de manière transparente. Le pouvoir gagné ne vaut pas la peine.

13
Don Stewart

Pourquoi cela ne peut-il pas être plus facile? Ou peut-être existe-t-il un moyen simple?

Il peut être plus facile d'utiliser une alternative récente, le package lens . Le module Tuple a des sélecteurs pour jusqu'à 9 tuples d'élément et il est simple d'en définir plus si nécessaire.

> import Control.Lens
> data A = A deriving (Show)
> (1, '2', "3", A) ^. _1
1
> (1, '2', "3", A) ^. _2
'2'
> (1, '2', "3", A) ^. _3
"3"
> (1, '2', "3", A) ^. _4
A

Vous pouvez également utiliser le package lens pour mettre à jour les éléments de manière polymorphe, changer de type à la mise à jour.

Avec et sans opérateurs d'infixe:

> (1, '2', "3", A) & _1 .~ "wow"
("wow",'2',"3",A)
 > set _1 "wow" (1, '2', "3", A)
("wow",'2',"3",A)

Le github readme est un bon point de départ pour en savoir plus sur la théorie sous-jacente ainsi que de nombreux exemples.


Pas seulement des tuples

Une syntaxe similaire fonctionne pour Traverables et Foldables, donc Trees, Maps, Vectors, etc. Par exemple, si j'avais une liste de tuples, je peux accéder au troisième élément Tuple à l'index 1 en composant le element 1 pour accéder au premier élément d'index avec _3 pour accéder au troisième élément Tuple.

[(1,2,3),(4,5,6),(7,8,9)] ^? element 1 . _3
Just 6
8
Davorak

La question d'une approche pour ce faire en utilisant le modèle haskell était précédemment abordée ici .

Un exemple de son utilisation:

> $ (sel 2 3) ('a', 'b', 'c') 
 'b' 
> $ (sel 3 4) ('a', 'b', 'c', 'd') 
 'c' 

d'ici .

5
monk
cabal update
cabal install Tuple
ghci

λ> import Data.Tuple.Select
λ> sel3 (0, "1", 2) --select the third element
2
UnchartedWorks

La nouvelle bibliothèque "record" de Nikita Volkov a une fonctionnalité qui semble faire ce que vous voulez. Recherchez la rubrique "Les tuples sont aussi des enregistrements!" sur la page liée.

Il semble que la bibliothèque soit encore en cours de développement, donc elle ne sera peut-être pas aussi facile à installer et à utiliser maintenant qu'elle le sera à l'avenir.

1
Vectornaut