2010-05-13 5 views
1

J'ai un devoir et je suis actuellement pris dans une section de ce que j'essaie de faire. Sans entrer dans détail spécifique est ici la mise en page de base: on me donne un élément de données, f, qui détient quatre différents types à l'intérieur (chacun avec leur propre but):Utilisation d'un élément sur une liste entière dans Haskell

data F = F Float Int, Int 

fonction:

func :: F -> F-> Q 

Qui prend deux éléments de données et (par des calculs simples) renvoie un type qui est maintenant une version mise à jour de l'un des types dans le premier f.

J'ai maintenant une liste complète de ces éléments et j'ai besoin d'exécuter la fonction donnée en utilisant un élément de données et de renvoyer la valeur du type (pas l'élément de données). Ma première analyse a été d'utiliser une fonction foldl:

myfunc :: F -> [F] -> Q 
myfunc y [] = func y y -- func deals with the same data element calls 
myfunc y (x:xs) = foldl func y (x:xs) 

mais je continue à obtenir la même erreur:

"Couldn't match expected type 'F' against inferred type 'Q'. 
In the first argument of 'foldl', namely 'myfunc' 
In the expression: foldl func y (x:xs) 

Je présente mes excuses pour une telle analyse abstraite sur mon problème, mais quelqu'un pourrait-il me donner une idée à ce que je devrais faire? Devrais-je même utiliser une fonction de pli ou y a-t-il une récursivité à laquelle je ne pense pas?

+0

Il semble y avoir quelque chose qui cloche avec votre définition de F. La virgule est-elle juste une faute de frappe ou avez-vous l'intention d'écrire quelque chose de différent? – svenningsson

Répondre

3

Le type de foldl est

foldl :: (a -> b -> a) -> a -> [b] -> a 

mais le type de func est

-- #  a -> b -> a 
func :: F -> F -> Q 

Le type de variable a ne peuvent pas être simultanément F et Q, ainsi l'erreur.


Si le Q peut être converti en provenance et à F, vous pouvez utiliser

myfunc y xs = foldl (func . fromQ) (toQ y) xs 

func . fromQ :: Q -> F -> Q 
     toQ y :: Q 
      xs :: [F] 

si celui-ci répond à toutes les exigences de type, et retournera la finale Q

+0

Merci beaucoup d'avoir éclairci pourquoi pli ne peut pas être utilisé. Fondamentalement, j'ai une liste de Fs qui doivent être mis à jour. Pour ce faire, je dois utiliser la fonction func et parcourir toute la liste et mettre à jour la valeur du F au fur et à mesure qu'il passe dans la liste (puis passer au F suivant). Ma réponse était simplement obtenir chaque donnée F (par un simple appel récursif) puis appelez myfunc avec le F et la liste complète des F et de renvoyer la valeur nécessaire. – Snick

+0

@Snick: mais alors vous aurez une liste de Q, pas seulement un seul Q. – kennytm

+0

Je pensais simplement que foldl exécuterait le F courant contre toute la liste en utilisant func, mettant à jour F au fur et à mesure. Je suppose que je devrais revenir à repenser à un moyen d'appeler récursivement F avec chaque élément de la liste avec le nouveau Q qu'il acquiert au fur et à mesure qu'il avance – Snick

2

Peut-être avez-vous besoin de la carte?

map :: (f -> q) -> [f] -> [q] 

il évalue une fonction sur chaque élément d'une liste et donne une liste des résultats. Je ne sais pas pourquoi votre fonction prend deux Fs, peut-être pour travailler avec foldl?

Questions connexes