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?
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.)
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).
[~ # ~] 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.
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.
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
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 .
cabal update
cabal install Tuple
ghci
λ> import Data.Tuple.Select
λ> sel3 (0, "1", 2) --select the third element
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.