2009-04-27 6 views
1

Je dois créer une fonction à laquelle est affectée une clé (String), une valeur (String) et une liste d'associations de clés et de valeurs (comme [(String, String)]). La fonction est destinée à ajouter la paire clé/valeur à la fin de la liste et, si la clé est déjà présente dans la liste avec une valeur associée, supprimer l'ancienne valeur.Haskell: Remplacement d'un élément par une clé donnée dans une liste d'association

J'ai essayé d'utiliser lookup sur la liste de clés et d'association, mais je ne suis pas sûr de ce qu'il faut faire avec la sortie - le type de sortie de la fonction lookup est Maybe String, et je ne peux pas sembler faire les fonctions de liste (comme des éléments qui tombent) sur elle. Est-il possible de parcourir la liste et de supprimer un élément de la liste avec une clé donnée sans connaître la valeur associée?

Répondre

5

Vous devriez probablement écrire une fonction récursive qui prend la nouvelle paire clé/valeur et la liste existante en tant que paramètres, et boucle dans la liste pour générer une nouvelle liste avec la nouvelle valeur insérée. Pour chaque élément de la liste, vous vérifiez si la clé est la même que celle que vous voulez insérer. Si c'est différent, vous gardez cet ancien élément, si c'est le même, vous ajoutez le nouvel élément à la place de l'ancien. Si vous atteignez la fin de la liste sans trouver la clé, insérez simplement le nouvel élément à la fin.

4

Dans Haskell, nous utilisons souvent le type de données Maybe lorsque nous ne savons pas si nous obtiendrons une valeur ou rien du tout en conséquence. C'est équivalent à un type nullable dans un langage plus traditionnel tel que Java.

Maybe est défini comme suit:

data Maybe a = Nothing | Just a 

C'est, la valeur peut être Nothing ou Just a, où a est l'objet que vous recherchez. Par exemple, si vous recherchez la chaîne "foo" en utilisant la fonction lookup, et que vous avez un tuple ("foo", "bar") dans votre liste, vous obtiendrez le résultat Just "bar". Cependant, si vous avez recherché "xyzzy", vous obtiendrez Nothing.

Nous pouvons prendre la valeur Maybe et le transformer en quelque chose de plus utile en utilisant la fonction maybe (noms confus, je sais - la fonction est tout en minuscules). Il est défini comme suit:

maybe default f (Just a) = f a 
maybe default f Nothing = default 

Le premier paramètre est une valeur par défaut. C'est ce que nous obtenons si nous avons Nothing. Sinon, nous obtenons la fonction f appliquée à a, où a est la chose que nous voulons. Si vous voulez juste a retour, vous pouvez passer la fonction id comme f:

maybe default id (Just a) = id a 

Obligeamment, id a = a.

Si vous souhaitez continuer à utiliser votre plan lookup actuel, voici comment vous en tirerez quelque chose d'utile. Personnellement, je préfère la méthode de sth - ce serait plus facile pour le processeur.

2

Voici une fonction simple qui fait ce que vous voulez. Il prend la nouvelle paire de valeur de clé et la place au début de la liste assoc donnée avec cette clé filtrée.

addOrReplace :: Eq k => k -> v -> [(k, v)] -> [(k, v)] 
addOrReplace key value assoc = (key,value):(filter ((key /=).fst) assoc) 

La fonction fst est définie comme:

fst (first,second) = first 

filter prend un prédicat et une liste de recherche, et retourne la liste avec les seuls éléments qui satisfont le prédicat. Edit: divisez la paire de valeurs de clé dans les paramètres de addOrReplace comme suggéré par Tom.

+0

Je préférerais passer la clé et la valeur comme arguments séparés au lieu de les coupler. De cette façon, il est plus facile d'appliquer partiellement la fonction sans avoir à le «curry». –

Questions connexes