Haskell: buscar el segundo valor de una tupla en una lista basada en el primer valor
Pregunta
Tengo una función aquí que está destinada a examinar una lista de tuplas y encontrar el segundo valor en la tupla tomando el primer valor. Aquí está la función hasta ahora:
lookup :: String -> [(String,String)] -> String
lookup _ _ [] = "Not found"
lookup x y zs = if (notFound x zs)
then "Not found"
else (head [b | (a,b) <- zs, (a==x)])
La función notFound simplemente devuelve un Bool como verdadero si no hay una tupla que contenga la primera cadena dada. El problema es que me sale este error de tipo en Hugs:
ERROR "find.hs" (line 22): Type error in explicitly typed binding
*** Term : lookup
*** Type : String -> [(String,String)] -> [a] -> String
*** Does not match : String -> [(String,String)] -> String
Estoy pensando que es algo que ver con el dummy " No encontrado " valor que tiene un tipo diferente a la cadena de la lista generada, pero no estoy seguro.
Solución
Creo que su declaración de tipo explícita es incorrecta. Tienes:
lookup :: String -> [(String,String)] -> String
pero creo que debería ser
lookup :: String -> String -> [(String,String)] -> String
En realidad, después de echarle otro vistazo, parece que no estás usando el segundo parámetro " y " ;. Así que podrías eliminarlo y el guión bajo como tal
lookup :: String -> [(String,String)] -> String
lookup _ [] = "Not found"
lookup x zs = if (notFound x zs)
then "Not found"
else (head [b | (a,b) <- zs, (a==x)])
Esto te permitirá mantener la declaración de tipo que tienes.
Otros consejos
por cierto, ¿sabías que Haskell Prelude ya tiene una " búsqueda " ¿Función para buscar entradas en una lista de asociaciones? Aquí está la firma de tipo (es más general, aceptando cualquier tipo de clave que instale Eq):
lookup :: (Eq a) => a -> [(a,b)] -> Maybe b
para que su función logre algo como el siguiente
myLookup x zs = Maybe.fromMaybe "Not found" $ lookup x zs
De un vistazo, parece que tal vez el segundo parámetro debería eliminarse (la 'y' y el segundo guión bajo). se declara que la búsqueda toma dos parámetros, no tres.