2010-03-02 20 views
9

Si esto funciona:función Haskell composición pregunta

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

Entonces ¿por qué no lo hace?

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

Precedente del operador. La aplicación de función "se une" muy estrechamente; (.) se une muy débilmente. – jrockway

+0

'(.)' Se une muy estrechamente (precedencia = 9), pero la aplicación de función se vincula aún más (precedencia = 10). Simplemente inserte '$' entre las dos cadenas para solucionarlo. '$' tiene muy baja prioridad, ** 0 **. –

Respuesta

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

se analiza como:

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

Así que, básicamente, que está haciendo

(map toUpper) . "sdfsddfgfdg" 

Esto no funciona debido a que el segundo argumento de . tiene que ser una función, no es una cadena.

Supongo que estaba intentando hacer algo más como (map toUpper . (++)) "sdfsd" "dfgfdg". Esto tampoco funciona porque el tipo de devolución de ++ es [a] -> [a], mientras que el tipo de argumento map toUpper es [a].

La cuestión aquí es que si bien uno podría pensar en ++ como una función que toma dos listas y devuelve una lista, realmente es una función que toma una lista y luego devuelve una función que toma otra lista y devuelve una lista. Para obtener lo que desea, necesitará ++ en una función que toma una tupla de dos listas y devuelve una lista. Eso se llama inquieto. Las siguientes obras:

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

Siguiendo su explicación, '(map toUpper. (++) "sdfsd") "dfgfdg"' debería hacer el trabajo. Y lo hace. Gracias. – artemave

+1

Y el mensaje de error ahora tiene sentido. Gracias de nuevo. – artemave

7

Usted quiere $ en lugar de .: map toUpper $ (++) "sdfsd" "dfg" obras y hace lo que quiere. La razón para esto es que $ es una aplicación de función de muy baja precedencia, por lo que la versión corregida se lee como: "Aplicar la función map toUpper al resultado de (++) "sdfsd" "dfg"".

Cuestiones relacionadas