2010-03-02 3 views
9

Si cela fonctionne:composition fonction Haskell question

Prelude Data.Char> map toUpper ("sdfsd" ++ "dfgfdg") 
"SDFSDDFGFDG" 

Alors pourquoi cela ne fonctionne pas?

Prelude Data.Char> map toUpper . (++) "sdfsd" "dfgfdg" 

<interactive>:1:14: 
    Couldn't match expected type `a -> [Char]' 
      against inferred type `[Char]' 
    In the second argument of `(.)', namely `(++) "sdfsd" "dfgfdg"' 
    In the expression: map toUpper . (++) "sdfsd" "dfgfdg" 
    In the definition of `it': it = map toUpper . (++) "sdfsd" "dfgfdg" 
+1

Priorité d'opérateur. L'application de la fonction "se lie" très étroitement; (.) se lie très faiblement. – jrockway

+0

'(.)' Se lie très étroitement (précédence = 9), mais l'application de la fonction se lie encore plus (priorité = 10). Insérez juste '$' entre les deux chaînes pour le réparer. '$' a une priorité très faible, ** 0 **. –

Répondre

13
map toUpper . (++) "sdfsd" "dfgfdg" 

est analysé comme:

(map toUpper) . ((++) "sdfsd" "dfgfdg") 

Donc, fondamentalement, vous faites

(map toUpper) . "sdfsddfgfdg" 

Cela ne fonctionne pas parce que le second argument . doit être une fonction, pas une chaîne.

Je suppose que vous essayiez de faire quelque chose de plus comme (map toUpper . (++)) "sdfsd" "dfgfdg". Cela ne fonctionne pas non plus car le type de retour de ++ est [a] -> [a] tandis que le type d'argument map toUpper est [a]. Le truc ici est que si on peut penser à ++ comme une fonction qui prend deux listes et retourne une liste, c'est vraiment une fonction qui prend une liste et retourne une fonction qui prend une autre liste et retourne une liste. Pour obtenir ce que vous voulez, vous devez ++ dans une fonction qui prend un tuple de deux listes et retourne une liste. C'est ce qu'on appelle sans changement. Les travaux suivants:

map toUpper . (uncurry (++)) $ ("sdfsd", "dfgfdg") 
+5

Suite à votre explication, '(map toUpper. (++) "sdfsd") "dfgfdg"' devrait faire le travail. Et c'est le cas. Merci. – artemave

+1

Et le message d'erreur a maintenant du sens. Merci encore. – artemave

7

Vous voulez $ au lieu de .: map toUpper $ (++) "sdfsd" "dfg" œuvres et fait ce que vous voulez. La raison en est que $ est une application de fonction de très basse priorité, de sorte que la version corrigée se lit comme suit: "Appliquer la fonction map toUpper au résultat de (++) "sdfsd" "dfg"".